-
Notifications
You must be signed in to change notification settings - Fork 70
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
Add support for exporting additional frames in ModelExporter #557
Add support for exporting additional frames in ModelExporter #557
Conversation
2173398
to
726c917
Compare
@prashanthr05 this PR is now ready for review, thanks! |
} | ||
|
||
frameIndices.resize(0); | ||
for (FrameIndex frameIndex=this->getNrOfLinks(); frameIndex < this->getNrOfFrames(); 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.
For quicker understanding and readabilityof code, it would be great to document the relationship between the link serialization and the additional frames serialization, also here.
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 it is documented here,
* The frame indices between 0 and getNrOfLinks()-1 are always assigned to the |
In that case, we can give a pointer to this documentation here.
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 81e7f7a .
* @param[out] frames a vector of FrameIndex of the frame indeces attached to the specified link index, | ||
* @return true if the specified link is a valid link, false otherwise. | ||
*/ | ||
bool getLinkAdditionalFrames(const LinkIndex lnkIndex, std::vector<FrameIndex>& frameIndeces) const; |
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.
Does it also make sense to have an overload with linkName
as input argument?
Not specifically for this scenario. but in general nice-to-have feature in the Model API.
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.
Similar overload for frameNames
as output?
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 could make sense, but I would leave this to a separate PR. Probably we can have a guideline to have for all methods in iDynTree::Model
both the index and the names one, and then have a PR for add names-variant for all methods missing them. Can you open a new issue on this?
@@ -63,11 +63,30 @@ class ModelExporterOptions | |||
* | |||
* Furthermore, currently the model exporter only exports a subset of the features | |||
* supported in iDynTree::Model. In particular, the following features are not exported: | |||
* * Additional frames | |||
* |
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 way how Additional Frames
disappeared ;D
* due to workaround a bug in official %KDL parser used in ROS (see https://github.com/ros/kdl_parser/issues/27 for more info). For this reason, | ||
* if the selected base_link has at least one additional frame, the first additional frame of the base link is added as a **parent** fake URDF link, | ||
* instead as a **child** fake URDF link as done with the rest of %iDynTree's additional frames. If no additional frame is available for the base link, | ||
* the base link of the URDF will have a mass, and will generate a warning then used with the ROS's [`kdl_parser`](https://github.com/ros/kdl_parser) . |
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.
Wow, is this the reason why Travis is failing in this pull request robotology/icub-models-generator#113 related to icub-model-generator
?
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 think so, I think that is an error is always there even if non-failing PRs.
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 I thought was, due to the parent-child direction inverting workaround, the root_tlink-base_link gets inverted parent reference and the base link might have a mass throwing an error?
Because, the segfaults was due to the fact that root_link has a described and the exact words from the failure read...
The root link root_link has an inertia specified in the URDF, but KDL does not support a root link with an inertia. As a workaround, you can add an extra dummy link to your URDF.
No link found with name base_link
Would that be possible?
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.
Because, the segfaults was due to the fact that root_link has a described and the exact words from the failure read...
Are you sure that the same error were not present in the successful builds?
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.
Are you sure that the same error were not present in the successful builds?
Uhmm.. of this, I am not sure.
* <parent_element> | ||
* <link name="<frame_name>"/> | ||
* <joint name="<frame_name>_fixed_joint" type="fixed"> | ||
* <origin xyz="0.1 0.2 0.3" rpy="0 0 3.1416"/> |
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 numbers here are misleading. Can we change them to placeholders?
UPDATE: Ok, given that this is just an example of it might look on the generated URDF, please ignore my comment.
|
||
// Export fake link | ||
xmlNodePtr link_xml = xmlNewChild(parent_element, NULL, BAD_CAST "link", NULL); | ||
xmlNewProp(link_xml, BAD_CAST "name", BAD_CAST frame_name.c_str()); |
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 any future developer asks why there is BAD_CAST
all across the code, we could possibly document this https://stackoverflow.com/questions/45058878/why-libxml2-uses-bad-cast-everywhere-in-a-c-c-code somewhere in the code ?
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 ee923f4 .
// child | ||
xmlNodePtr child_xml = xmlNewChild(joint_xml, NULL, BAD_CAST "child", NULL); | ||
xmlNewProp(child_xml, BAD_CAST "link", BAD_CAST child_of_fake_joint.c_str()); | ||
|
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 a common trend of using the method xmlNewChild
and xmlNewProp
sequentially. Can we not make a function that does the composition of these two steps?
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 this also depends on how many properties we add in sequence. So the complexity of having a single function to handle all properties might be big. But can still be handled by a vector of key-value pairs.
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, this could make sense, but at least initially I preferred to avoid start writing a C++ wrapper on the top of the libxml2 API, without having a clear idea about our need from the libxml2's API. Furthermore, I am a bit afraid that adding a layer between the libxml2's API and the parser could impact readability. However, a C++ wrapper could make sense, but I would prefer to complete the URDF exporter implementation to understand our needs, and eventually do an libxml2 abstraction as a refactoring. What do you think?
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.
Agreed.
I should have addressed all your comments @prashanthr05 . |
|
||
// TODO(traversaro) : uncomment the following line when frames are correctly handled by the exporter | ||
// ASSERT_EQUAL_DOUBLE(model.getNrOfFrames(), modelReloaded.getNrOfLinks()); | ||
|
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.
Thank you for remembering to remove this. Sorry I missed this in the review!
To return all the additional frames connected to a given link.
805d1fe
to
358beda
Compare
Thanks @prashanthr05 ! |
This PR builds on the top of #554, so it will not be ready to be merged until that PR is merged before.Relevant commits:
Model::getLinkAdditionalFrames
methodAll addition come with the respective unit tests and documentation.