-
Notifications
You must be signed in to change notification settings - Fork 17
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
WB-Toolbox 3.0 #56
WB-Toolbox 3.0 #56
Conversation
toolbox/include/CentroidalMomentum.h
Outdated
iDynTree::Vector3* m_gravity; | ||
iDynTree::Transform* m_world_T_base; | ||
iDynTree::VectorDynSize* m_jointsVelocity; | ||
iDynTree::VectorDynSize* m_jointsState; |
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 mechanical systems, "state" is tipically used to indicate position and velocity, so I would call this member m_jointsPosition
or something similar.
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 didn't like the previous word configuration and I switched to State. Position is even more clear 👍
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.
Do you think it would make sense to add an explicitly call to setFrameVelocityRepresentation
to make sure that the representation is the intended one?
toolbox/include/DotJNu.h
Outdated
class Twist; | ||
class Transform; | ||
class VectorDynSize; | ||
typedef int FrameIndex; |
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 understand the concern of avoiding too many includes to reduce compilation times, but I think redefining a typedef
like this, as it will create problems if we have change the definition of FrameIndex
.
However, if you prefer it like this no problem for me.
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 tried to keep as much as possible the same behavior as the current state, and I agree with you on these forward declaration. For VectorFixSize
I had to add the header since redefining templates was a bit too much imo, but applying this line to all the typedefs would make sense too
toolbox/src/CentroidalMomentum.cpp
Outdated
m_jointsVelocity = new double[dofs]; | ||
|
||
return m_basePose && m_centroidalMomentum && m_basePoseRaw && m_configuration && m_baseVelocity && m_jointsVelocity; | ||
double m_gravityRaw[3] {0, 0, -9.81}; |
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 know where this is set at the moment, but for different reasons it could make sense to have this configurable at configure time/runtime eventually. A classical example is a fixed base robot mounted on a table, if the gravity acceleration of the table can be set from the outside it is trivial to compensate eventual skewness of the table.
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.
So far the only block with an optional input for gravity is InverseDynamics
. So far I tried to maintain the current functionalities, without the need of editing the Simulink's masks. I'll add this in a future TODO list
toolbox/src/DotJNu.cpp
Outdated
} | ||
|
||
else { | ||
m_frameIndex = COM_LINK_ID; |
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 KinDynComputations class has separate methods to compute the COM position/jacobian/bias term. Passing a m_frameIndex
of -1
(that is equivalent to iDynTree::FRAME_INVALID_INDEX` will result in a runtime error.
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.
@traversaro In the output()
method of all the blocks that use COM_LINK_ID
the correct iDynTree's method for CoM is called. Since all integers <0
are treated as FRAME_INVALID_INDEX
by iDynTree, do you have any suggestion on how to handle this case with a viarable?
I mean, when m_frameIndex = -1
and the frame is com
, an error is thrown. If m_frameIndex = -1
and the frame is not com
, the block goes further to the output()
and the COM_LINK_ID
is used to to select the alternative method for computations on CoM.
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 see, I missed the check on COM_LINK_ID
. Everything should work fine indeed, but personally I would prefer to have a separated boolean variable to save the information "is this block computing COM-related stuff", rather than overloading the meaning of m_frameIndex
. However, this is mostly a personal taste, so feel free to use the pattern that you prefer. The only advice that I would recommend is to define COM_LINK_ID
to any negative number different from -1
, as -1
is exactly the value of iDynTree::FRAME_INVALID_INDEX
.
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 like the boolean variable idea. It is the most safe and clean in the long run
toolbox/src/DotJNu.cpp
Outdated
// OUTPUT | ||
// ====== | ||
|
||
// Compute the dot{J}*dot{q} |
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.
We typically prefer \nu over dot{q} .
toolbox/src/ForwardKinematics.cpp
Outdated
success = success && blockInfo->setInputPortMatrixSize(0, 4, 4); | ||
success = success && blockInfo->setInputPortVectorSize(1, dofs); | ||
success &= blockInfo->setInputPortMatrixSize(INPUT_IDX_BASE_POSE, 4, 4); | ||
success &= blockInfo->setInputPortVectorSize(INPUT_IDX_JOINTCONF, dofs); |
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.
Not a bit fan of the use of bit field operations to represent compactly boolean operations, but I know it works so if for you it is ok it is ok also for me. : )
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 found the previous version redundant, if @francesco-romano has no comments on this I'd like to use the new 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.
honestly I am against the use of &=
toolbox/src/MassMatrix.cpp
Outdated
// ======================= | ||
model->setRobotState(*m_world_T_base, | ||
*m_jointsState, | ||
*m_baseVelocity, |
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.
By default for performance reason iDynTree::VectorFixSize
objects are not initialized to any value, so this call will effectively use not initialized memory. I suggest to explicitly add a call to m_baseVelocity->zero()
in the initialization method to all the vector that you expect to be set to zero.
The VectorDynSize
are indeed zeroed during initialization, but I suggest to add an explicit to zero()
also for them for consistency and protect you from possible future changes in iDynTree .
@traversaro Can you please give me some further detail on this? What representation are we using inside the Toolbox? I'm a bit confused on this. |
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.
@francesco-romano @traversaro |
* @param [out] option implementation-specific block option | ||
* @return true if the option has been converted. False otherwise | ||
* @param [in] key identifier of the block option | ||
* @param [in] option implementation-specific block option |
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.
Is this an in or out parameter?
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.
An out parameter, I don't even remember why I changed this
I think we use Mixed representation, am I right @traversaro ? |
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 discussed F2F I reviewed until 0e99c6f (included)
+WBToolbox/WBToolboxConfig.m
Outdated
|
||
properties | ||
% Robot state | ||
RobotName (1,:) char |
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 capital case letters?
Is this a MATLAB convention?
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.
+WBToolbox/WBToolboxConfig.m
Outdated
% Dependent properties | ||
% -------------------- | ||
|
||
function set.ValidConfiguration(~,~) |
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 do not know anything of MATLAB classes but, isn't possible to have "read only" properties, i.e. only public getter?
This would avoid to declare a fake set 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.
ValidConfiguration
is a Dependent
property, so by default even without this set method an error is generated. Specifying this method gives the possibility to provide a custom error message, and in this case it is used exactly for this reason.
+WBToolbox/WBToolboxConfig.m
Outdated
~isempty(obj.ControlBoardsNames) && ... | ||
~isempty(obj.LocalName) && ... | ||
~isequal(obj.GravityVector,[0, 0, 0]); | ||
% Check if the urdf file has the right extension |
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 sure that the extension is actually needed. I would drop this requirement.
It is then iDynTree that will validate the URDF 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.
Ok, let's be generic then
MxAnyType/CMakeLists.txt
Outdated
set(CMAKE_CXX_STANDARD 11) | ||
set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
include(GNUInstallDirs) | ||
option(BUILD_SHARED_LIBS OFF) |
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 line is not needed.
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.
Removed
MxAnyType/CMakeLists.txt
Outdated
|
||
# Find Eigen | ||
find_package(Eigen3 REQUIRED) | ||
target_include_directories(${VARS_PREFIX} PUBLIC "${EIGEN3_INCLUDE_DIR}") |
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.
actually, if Eigen is used only in cpp, this can have a PRIVATE
include
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.
Ping @traversaro. Has Eigen been fixed on Windows when used in headers? Any comment / alternatives on this?
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 by "been fixed"? And how this is related to PRIVATE/PUBLIC?
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.
@traversaro the actual question is: Eigen members in header files.
I know there were issues with exported symbols in Windows. Furthermore, I do not like them in header files (as they force you to have Eigen)
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.
Replied in #56 (comment) .
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.
Final solution #56 (comment)
toolbox/src/base/Signal.cpp
Outdated
{ | ||
if (isConstPort) return; | ||
unsigned dataSize = sizeof(bool); | ||
const void* address = static_cast<const bool*>(data) + startIndex; | ||
|
||
memcpy(contiguousData, address, dataSize * length); | ||
memcpy(contiguousData, address, dataSize* length); |
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.
same as before
// ======================== | ||
|
||
ToolboxSingleton(); | ||
ToolboxSingleton(const ToolboxSingleton&); |
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 it is a singleton both copy and assignment should be prohibited
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.
Used = delete
* @return A \c shared_ptr to the iDynTree::KinDynComputations of the requested | ||
* configuration | ||
*/ | ||
const std::shared_ptr<iDynTree::KinDynComputations> model(const std::string& confKey); |
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.
To be consistent with the previous two methods I would rename this into getModel
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 was an inheritance of the previous version, changed the name. This method might even be removed, it's never called. Right now the best way to gather the model is asking it directly from the parent WBBlock
using getRobotInterface()->getKinDynComputations()
. This allows the block not to know the existence of the confKey
variable.
* @return Returns \c true if configure is successful, \c false otherwise | ||
* @see ToolboxSingleton::isKeyValid | ||
*/ | ||
bool configure(const std::string& confKey, const Configuration& config); |
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 before, I do not like the name configure
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.
Renamed to storeConfiguration()
// This may cause problems if the config block's mask is changed after the first compilation. | ||
if (m_interfaces.find(confKey) == m_interfaces.end()) { | ||
m_interfaces[confKey] = std::make_shared<RobotInterface>(config); | ||
return m_interfaces[confKey].get(); |
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 comment applies also to other uses of .get()
.
shared_ptr
have an operator bool
. This means that you can directly return return m_interfaces[confKey]
to assess validity of the pointer.
Change this line and the other times you use get()
as a boolean check
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 conversion from shared_ptr to bool is explicit
. An alternative to get()
would be static_cast<bool>
. Using this latter version.
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.
MxAnyType/CMakeLists.txt
Outdated
set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
include(GNUInstallDirs) | ||
option(BUILD_SHARED_LIBS OFF) | ||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) |
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 variable only make sense if you are building shared libraries.
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.
Yes, in the future this will become a shared library. For the time being it is static, but just for convenience.
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.
This class contains the data passed from Simulink. It matches the data structure of Matlab's WBToolboxConfig.getSimulinkParameters() struct.
This class contains all the required data structures to operate on a robot, either through the model or the interfaces to the hardware / gazebo. From the Simulink point of view, there is one instance of RobotInterface for every Configuration block added in the model. In fact, RobotInterface extends by composition the Configuration object. It handles the pointers to its members in a lazy way, initializing on the fly the asked resource.
This is a temporary fix. The cpp file should be generated by its thrift source, which should be found already installed in the system. A new CMake option e.g. USE_GAZEBO should be added.
This commit fixes also some error in computing the address used in memcpy calls
Furthermore: - All methods that read parameters return a bool value - optionFromKey doesn't use anymore wbt::Data - setNumberOfOuputPorts() became setNumberOfOutputPorts()
This new WBBlock implements the same functionalities of the former WBIBlock and WBIModelBlock blocks. Resources are lazy-handled, and it is not anymore necessary having two different setups. Furthermore: - The parameters from Simulink are stored in the ToolboxSingleton in the configureSizeAndPorts() instead of initialize(). This is possible because singletons are not deleted by Simulink between these two steps (Blocks instead are deleted).
- Removed old Error parameter from methods - Small documentation changes - Small style edits
The new ToolboxSingleton class contains in a persistent wat Configuration and RobotInterface objects. Most of the logic previously contained in WBInterface has been moved in these two new classes.
Kept as private variables only what is strictly required
Now it works as expected when the initial state vector is set but is not enabled
It is still not clear what is the Matlab version which introduced this feature. For now I am reverting it, addressing robotology#66.
Refer to #46 and this milestone for the task list.
This PR:
[WIP]
WBTPIDConfig
still misses aget
method returning a struct+WBToolbox
packagestd::vector::assign()
is used on non non-contiguous arrays, double check all blocksrad2deg
is required inSetReferences.cpp
YarpRead.cpp
wbt::
namespace nesting in thecpp
filesREADME.md