-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DiscreteFilter block #47
Conversation
c27a8dd
to
57a432d
Compare
If we are going to require the |
toolbox/src/DiscreteFilter.cpp
Outdated
@@ -125,7 +132,10 @@ bool DiscreteFilter::initialize(BlockInformation* blockInfo, wbt::Error* error) | |||
} | |||
return 1; | |||
} | |||
filter = new iCub::ctrl::Filter(*num, *den); | |||
for (unsigned i = 0; i < inputSignalWidth; ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The filter class support vector input/output, why are are you using a different filter for each component of the vector?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the new commit I forced pushed now the block works with vectors and reduces dynamic allocation
toolbox/src/DiscreteFilter.cpp
Outdated
// Get the width of the signals | ||
unsigned inputSignalWidth = blockInfo->getInputPortWidth(INPUT_IDX_SIGNAL); | ||
unsigned outputSignalWidth = blockInfo->getOutputPortWidth(OUTPUT_IDX_SIGNAL); | ||
assert(inputSignalWidth == outputSignalWidth); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not an expert of Simulink, but what happens with this assert if the user connect two signal of different size to the input and output of the block? Simulink crashes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It crashes. In my opinion having asserts is good even in this case. When people work on controllers (downstream) the code should be always be set in release. Debug should be enabled only when developing the block themselves. @francesco-romano
d0cd476
to
d138501
Compare
s.erase(remove_if(s.begin(), s.end(), lambda_remove_chars), s.end()); | ||
|
||
// Convert the cleaned string to a yarp vector of floats | ||
std::istringstream sstrm(s); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This conversion part could be affected by locale-bugs such as robotology/idyntree#288 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in aafaf38
toolbox/src/base/factory.cpp
Outdated
@@ -36,7 +36,10 @@ wbt::Block* wbt::Block::instantiateBlockWithClassName(std::string blockClassName | |||
#ifdef WBT_USES_ICUB | |||
else if (blockClassName == wbt::MinimumJerkTrajectoryGenerator::ClassName) { | |||
block = new wbt::MinimumJerkTrajectoryGenerator(); | |||
} | |||
} | |||
else if (blockClassName == wbt::DiscreteFilter::ClassName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please keep the indentation of the else coherent with the rest of the file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean? It looks already coherent but is morning for me as well :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh sorry, now I see. Inside WBT_USES_ICUB
is coherent, outside no. I fix both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmh consideing that the last part of the file is all with defines, and the indentation has to be changes, imo the current status looks better. Compare:
...
} else if (blockClassName == wbt::GetLimits::ClassName) {
block = new wbt::GetLimits();
} else if (blockClassName == wbt::CentroidalMomentum::ClassName) {
block = new wbt::CentroidalMomentum();
}
#ifdef WBT_USES_ICUB
else if (blockClassName == wbt::MinimumJerkTrajectoryGenerator::ClassName) {
block = new wbt::MinimumJerkTrajectoryGenerator();
}
else if (blockClassName == wbt::DiscreteFilter::ClassName) {
block = new wbt::DiscreteFilter();
}
#endif
#ifdef WBT_USES_IPOPT
else if (blockClassName == wbt::InverseKinematics::ClassName) {
block = new wbt::InverseKinematics();
}
#endif
with
...
} else if (blockClassName == wbt::GetLimits::ClassName) {
block = new wbt::GetLimits();
} else if (blockClassName == wbt::CentroidalMomentum::ClassName) {
block = new wbt::CentroidalMomentum();
}
#ifdef WBT_USES_ICUB
else if (blockClassName == wbt::MinimumJerkTrajectoryGenerator::ClassName) {
block = new wbt::MinimumJerkTrajectoryGenerator();
} else if (blockClassName == wbt::DiscreteFilter::ClassName) {
block = new wbt::DiscreteFilter();
}
#endif
#ifdef WBT_USES_IPOPT
else if (blockClassName == wbt::InverseKinematics::ClassName) {
block = new wbt::InverseKinematics();
}
#endif
But as you prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer the second one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comments are related to the C++ only.
Before merging the matlab part should also be tested
toolbox/include/DiscreteFilter.h
Outdated
private: | ||
bool firstRun; | ||
iCub::ctrl::IFilter* filter; | ||
yarp::sig::Vector* num; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why putting num
and den
in the .h
file? They are only needed in configuration and not in real time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
toolbox/src/DiscreteFilter.cpp
Outdated
|
||
DiscreteFilter::DiscreteFilter() : firstRun(true), filter(nullptr), inputSignalVector(nullptr) | ||
{ | ||
num = new Vector(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see comment in the .h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
toolbox/src/DiscreteFilter.cpp
Outdated
unsigned inputSignalWidth = blockInfo->getInputPortWidth(INPUT_IDX_SIGNAL); | ||
|
||
// Allocate the memory for the input data | ||
if (firstRun) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is also another callback (initializeInitialConditions
) which is called before the first output.
Furthermore, have you tried to ask for the port width in the initialize
method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In initialize()
it returns the correct width. I'll add a private member for that and move the initialization into the initializeInitialConditions
callback that I didn't know existed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if initialize
returns the correct width, I advise to use it instead of initializeInitialConditions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok thanks, should be ok now.
toolbox/src/DiscreteFilter.cpp
Outdated
|
||
void DiscreteFilter::stringToYarpVector(const std::string str, Vector* v) | ||
{ | ||
assert(v != nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the pointer should always be !=
null, I would use a reference, not a pointer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the argument type to Vector&
7e1d745
to
e7f3da7
Compare
@francesco-romano |
toolbox/src/DiscreteFilter.cpp
Outdated
|
||
// If the initial conditions for the output are not set, allocate a properly | ||
// sized vector | ||
if (*y0 == Vector(0)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not asking for the size of the vector and calling a resize on it, instead of allocated twice?
toolbox/src/DiscreteFilter.cpp
Outdated
|
||
DiscreteFilter::DiscreteFilter() : filter(nullptr), inputSignalVector(nullptr) | ||
{ | ||
y0 = new Vector(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the delete are done in the terminate, move the allocation in the corresponding method, and not in the constructor.
Here simply initialise to nullptr
the pointers
toolbox/src/DiscreteFilter.cpp
Outdated
// zero-gain case | ||
Filter* filter_c = dynamic_cast<Filter*>(filter); | ||
if (filter_c != nullptr) { | ||
filter_c->init(*y0, *u0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't remember what init
does, but is it ok to call with an empty vector? (i.e. u0.size() == 0
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With 4a29231 the vectors that hold the optional initial values are null if the parameters are not specified, and allocated to the correct size only when needed. If instead they are specified, their size is checked in the initialize
method.
toolbox/src/DiscreteFilter.cpp
Outdated
y0 = new Vector(inputSignalWidth, 0.0); | ||
if (y0 == nullptr) { | ||
unsigned outputSignalWidth = blockInfo->getInputPortWidth(OUTPUT_IDX_SIGNAL); | ||
y0 = new Vector(outputSignalWidth, 0.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you avoid to align the =
? I don't like this kind of indentation
A part from the inline comment the |
@diegoferigo |
SetReferences subList parameter was erroneously converted to a boolean, while it is actually the index of the selected item in the Simulink mask dropdown. Being the index >=1 the boolean conversion resulted always in a true value. Fix robotology#57
Note: actually the std::cerr are warnings for the user, this is why they are not returned as an error. We have to find a smarter way to return the warning to the user.
This class contains and validates the configuration passed to every wbt::WBBlock object. ValidConfiguration is a Dependent property and it is set to 1 only if the basic checks currently implemented in other properties don't fail. From this state, it is possible to call getSimulinkParameters() in order to obtain the struct which is passed to the S-Functions and then parsed in C++. This class also contains utilities functions for obtainng a simple string representation of 1D vectors and 1D chars, required to serialize the data in the Config Block's mask. The deserialization is performed using eval().
Initial version of the library, which will become independent in the future. MxAnyType handles the C / C++ mxArray pointer that represents any generic data type in Matlab. It wraps most of the C APIs, and it has optional support of strict type checking.
wbt::Log is the new class that provides log support to the WBToolbox. It now supports both Errors and Warnings. For being more flexible, wbt::Log is a singleton. This approach simplifies dramatically the handling of warnings, and can be called from every method without the need of passing it though arguments. Since singletons cannot be deleted, wbt::Log state is reset in the early stage of the processing. [Squash] toolbox.cpp
Its functionality are implemented by the new generic WBBlock, which is a refactored version of WBIBlock that access robot resources in a lazy way. This approach allows avoiding the previous separation between WBIBlock and WBIModelBlock.
2dc2d8e
to
22244c4
Compare
Also renamed Migration.md
WBToolboxLibrary.mdl: R2012A WBToolboxLibrary.slx: R2014B WBToolboxLibrary_repository: R2016B
These messages are displayed in the console from which Matlab was launched
Kept as private variables only what is strictly required
WBToolboxLibrary.mdl: R2012A WBToolboxLibrary.slx: R2014B WBToolboxLibrary_repository.mdl: R2016B
Now it works as expected when the initial state vector is set but is not enabled
22244c4
to
580e430
Compare
For simplifying the test of the WB-Toolbox 3.0, I cherry picked these commits to #56. Closing this PR. |
This block wraps all the filters included in the
iCub::ctrl
namespace (filters.h):iCub::ctrl::Filter
iCub::ctrl::FirstOrderLowPassFilter
iCub::ctrl::MedianFilter
This class already supports multidimensional input signals.
This PR needs the interface that has been discussed in robotology/icub-main#463.
Future TODOs:
This is what is currently missing and it might be included in future PRs if required: