Skip to content
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

URDF to SDF conversion ignores links without inertia #199

Closed
osrf-migration opened this issue Sep 5, 2018 · 23 comments
Closed

URDF to SDF conversion ignores links without inertia #199

osrf-migration opened this issue Sep 5, 2018 · 23 comments
Labels
enhancement New feature or request major URDF URDF parsing

Comments

@osrf-migration
Copy link

Original report (archived issue) by Louise Poubel (Bitbucket: chapulina, GitHub: chapulina).


For example, this:

<?xml version="1.0" ?>
<robot name="always_ignored">
  <link name="link">
    <visual>
      <geometry>
        <sphere radius="1.0"/>
      </geometry>
    </visual>
  </link>
</robot>

Results in:

$ gz sdf -p /tmp/urdf_ball.urdf 
<sdf version='1.6'>
  <model name='always_ignored'/>
</sdf>

But when inertia is added, the link is not ignored:

<?xml version="1.0" ?>
<robot name="always_ignored">
  <link name="link">
    <visual>
      <geometry>
        <sphere radius="1.0"/>
      </geometry>
    </visual>
    <inertial>
      <mass value="1"/>
      <inertia ixx="1" ixy="0.0" ixz="0.0" iyy="1" iyz="0.0" izz="1"/>
    </inertial>
  </link>
</robot>
$ gz sdf -p /tmp/urdf_ball.urdf 
<sdf version='1.6'>
  <model name='always_ignored'>
    <link name='link'>
      <pose frame=''>0 0 0 0 -0 0</pose>
      <inertial>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <mass>1</mass>
        <inertia>
          <ixx>1</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>1</iyy>
          <iyz>0</iyz>
          <izz>1</izz>
        </inertia>
      </inertial>
      <visual name='link_visual'>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <sphere>
            <radius>1</radius>
          </sphere>
        </geometry>
      </visual>
    </link>
  </model>
</sdf>

It could be argued that:

  • it is good practice to add inertia for simulation
  • URDF will rarely be used to describe static objects, where inertia is ignored

But I'd expect a URDF link without an inertia element to be converted to an SDF link without an inertia element, which is valid SDF.

This can become very confusing for someone trying to convert URDF files from the beginner tutorials to SDF and getting an empty model - based on a true story.

@osrf-migration
Copy link
Author

Original comment by Louise Poubel (Bitbucket: chapulina, GitHub: chapulina).


  • Edited issue description

@osrf-migration
Copy link
Author

Original comment by Silvio Traversaro (Bitbucket: traversaro).


To be honest, I think the ideal solution to the issue would be if both URDF and SDF could explicitly represent "purely kinematic frames", and in this way a URDF containing a "purely kinematic frame" would be converted to a SDF model containing a "purely kinematic frame". Clearly this is not immediate, as it would also require introducing a URDF tag or similar,or at least a Gazebo-specific extension of the URDF.

@osrf-migration
Copy link
Author

Original comment by Louise Poubel (Bitbucket: chapulina, GitHub: chapulina).


Thanks for all the context, I suspected there was a good reason for the current behaviour.

Agreed that being explicit would be the most elegant solution. On SDF, the tag is probably what would be used.

@osrf-migration
Copy link
Author

Original comment by Silvio Traversaro (Bitbucket: traversaro).


Agreed that being explicit would be the most elegant solution. On SDF, the tag is probably what would be used.

That would be great, and it would make possible to actually replace URDF files with SDF for control/planning applications.

By the way, I thought about it and there is no need to modify the URDF specification at the moment: as soon as SDF supports "pure kinematic frames", it would just be necessary
to transform all the currently removed/lumped/ignored URDF links with corresponding frames in the URDF --> SDF conversion.

However, there are several corner cases: what about an URDF where all the links are inertial-less (similar to the example in this): you cannot model the non-fixed joints in Gazebo/SDF unless they actually connect physical links, how should that be converted? Perhaps the conversion should simply fail, providing a clear error explaining the reason for the failure, but even that would mean breaking backward compatibility.

@osrf-migration
Copy link
Author

Original comment by Louise Poubel (Bitbucket: chapulina, GitHub: chapulina).


there are several corner cases: what about an URDF where all the links are inertial-less (similar to the example in this)

That's a good point. In this specific case, besides being connected by joints, the links also contain visuals, so they're definitely more than just frames.

Perhaps the conversion should simply fail, providing a clear error explaining the reason for the failure

Personally, I lean more towards choosing a well-defined behaviour, documenting it well, and at most printing warnings instead of failing. The idea being that over time, users will start adopting the well-defined convention.

@osrf-migration
Copy link
Author

Original comment by Silvio Traversaro (Bitbucket: traversaro).


For some reason, the first comment to this issue is visible to me only if I am logged in bitbucket.

@osrf-migration
Copy link
Author

Original comment by Silvio Traversaro (Bitbucket: traversaro).


The comment that for some reason is hidden is:


@osrf-migration
Copy link
Author

Original comment by Silvio Traversaro (Bitbucket: traversaro).


Anyhow, now that sdf v1.7 supports frames, I think the best way to deal with this is to make sure that URDF links without inertia are converted to SDF frames.

@osrf-migration
Copy link
Author

Original comment by Silvio Traversaro (Bitbucket: traversaro).


Anyhow, now that sdf v1.7 supports frames, I think the best way to deal with this is to make sure that URDF links without inertia are converted to SDF frames.

As https://osrf-migration.github.io/sdformat-gh-pages/#!/osrf/sdformat/pull-requests/676 is already changing the URDF → SDF converter to emit SDF 1.7 files, this probably would be even more doable.

@osrf-migration
Copy link
Author

Original comment by Kaelin (Bitbucket: Kaelin).


I happen to have run into a variant of this issue today and spent a while debugging it. In addition to the case of having not declared an inertia node in the XML at all, this also occurs if you have a mass value which is too small. A mass value of 0.00001 (1e-5) works fine, but if you decrease it to 0.000001 (1e-6), the link is silently omitted. This is pretty dangerous, since it is easy to gloss over an additional 0 when scanning for issues. I saw that having no mass was disallowed, so my natural inclination was to make it some very small number, and happened to hit too many zeroes.

An error in this case, even if massless links aren’t implemented, would be much appreciated.

@azeey
Copy link
Collaborator

azeey commented Apr 30, 2020

Copying relevant comments from Asana:

@scpeters : links without inertias connected to another link via a fixed joint could clearly be converted to a frame on the parent link, but what if the link without inertia has a collision or visual, or it's connected by a different type of joint?

@EricCousineau-TRI
Sounds like using the welding approach work best, though it does incur the cost of an additional joint.
For visuals / collisions in those links, I guess you could update their //pose/@relative_to, but that sounds a tad hairy.

@azeey
So, currently, by default (you can set a parameter to disable this), the collisions and visuals get lumped into the link that has inertia. We can keep doing that, but in addition, create a frame for the the link without inertia attached to the link with the inertia. This would make it possible for a gazeb-ros plugin to publish static transforms for the link without inertia, which I think is the desired effect.

@traversaro
Copy link
Contributor

Other related issue (it is a sort of "corner case"): #105 .

@azeey
Copy link
Collaborator

azeey commented Apr 30, 2020

Thanks @traversaro for pointing that out.

My previous comment is not entirely correct. It would be true if the massless link is attached to a "massive" link with a fixed joint.

Here's my current understanding:

Current behavior

  • Empty links in URDF are assumed to be massless
  • Non-empty links (containing child elements such as visuals) without inertias are assumed to be massless
  • Links with masses less than or equal to 1e-6 Kg are considered massless
  • All massless links are ignored
  • "Massive" links connected to other links via a fixed joint are merged with the other link
    • Unless either disableFixedJointLumping or preserveFixedJoint is set to true
  • disableFixedJointLumping is a legacy option that, if set to true, replaces the fixed joint with a revolute joint with joint limits set to 0. This prevents the links connected by the joint from getting merged. Since fixed joints are directly supported in libsdformat, a new parameter, "preserveFixedJoint", was created. When this is set to true, the fixed joint in URDF is represented by a fixed joint in SDFormat.

Desired behavior

  • Empty links in URDF are assumed to be massless and get converted into SDFormat frames
  • A Non-empty link (containing child elements such as visuals) without inertia is assumed to be massless.
    • If the link is attached to another link by a fixed joint, its child elements are moved to the other link and a frame is created in place of the link. The child elements' poses will be "relative_to" this new frame.
    • If the link is attached to another link by a non-fixed joint, a warning is displayed. We then have two options:
      • Keep the current behaviour of ignoring such links. (my preference)
      • Add an SDFormat link with default inertial
  • Links with masses less than 1e-6 are considered massless and get converted into SDFormat frames. There is an argument to be made about keeping such links as links in SDFormat, but that could break simulation for files that rely on such links being ignored.
  • If disableFixedJointLumping is enabled, keep current behavior. If any of the links would be ignored because it was massless, replace it with a frame.
  • If preserveFixedJoint is enabled, keep current behavior. If any of the links would be ignored because it was massless, replace it with a frame.

@EricCousineau-TRI
Copy link
Collaborator

For what @traversaro commented on, I've made a Wiki edit:
ros/urdfdom#138 (comment)

If this is a corrected edit, @azeey could you include a link to the spec in your above post?
http://wiki.ros.org/urdf/XML/link#Elements

@toliver
Copy link

toliver commented May 19, 2020

  • If preserveFixedJoint is enabled, keep current behavior. If any of the links would be ignored because it was massless, replace it with a frame.

In case the fixed joint contains a force torque sensor, as described in the last section of this tutorial, I assume the sensor element should be conveniently modified, when replacing the massless link with a frame, so that the sensor is not silently removed, and its measurements are still correct and with respect to the correct frame.

@RicoJia
Copy link

RicoJia commented Oct 15, 2020

Original comment by Kaelin (Bitbucket: Kaelin).

I happen to have run into a variant of this issue today and spent a while debugging it. In addition to the case of having not declared an inertia node in the XML at all, this also occurs if you have a mass value which is too small. A mass value of 0.00001 (1e-5) works fine, but if you decrease it to 0.000001 (1e-6), the link is silently omitted. This is pretty dangerous, since it is easy to gloss over an additional 0 when scanning for issues. I saw that having no mass was disallowed, so my natural inclination was to make it some very small number, and happened to hit too many zeroes.

An error in this case, even if massless links aren’t implemented, would be much appreciated.

SOLVED MY PROBLEM, BIG THANKS!

@scpeters
Copy link
Member

scpeters commented Nov 6, 2020

we should improve the console error message for this: gazebosim/gazebo-classic#2869

@traversaro
Copy link
Contributor

traversaro commented May 2, 2022

Original comment by Kaelin (Bitbucket: Kaelin).

I happen to have run into a variant of this issue today and spent a while debugging it. In addition to the case of having not declared an inertia node in the XML at all, this also occurs if you have a mass value which is too small. A mass value of 0.00001 (1e-5) works fine, but if you decrease it to 0.000001 (1e-6), the link is silently omitted. This is pretty dangerous, since it is easy to gloss over an additional 0 when scanning for issues. I saw that having no mass was disallowed, so my natural inclination was to make it some very small number, and happened to hit too many zeroes.

An error in this case, even if massless links aren’t implemented, would be much appreciated.

I suspect this is what you are experiencing @fabiodinatale. Anyhow, this is quite a different problem from the one described in this issue. In this issue we are discussing that URDF to SDF ignores links without inertia, while the issue is about URDF to SDF ignoring links with really small mass, that is quite a different problem. For this reason, I opened a new issue: #1007 .

@fabiodinatale
Copy link

Thanks @traversaro!

@traversaro
Copy link
Contributor

Probably this will be fixed by #1148 .

@scpeters
Copy link
Member

Probably this will be fixed by #1148 .

maybe in some cases, but #1148 only has an effect for links connected by fixed joints, so the always_ignored example URDF at the top of this issue would not be affected as it only has a single link and no fixed joints.

The challenge is that URDF defaults to zero inertia values if //link/inertial is unset, while SDFormat defaults to nonzero inertial values.

@j-rivero
Copy link
Contributor

we should improve the console error message for this: osrf/gazebo#2869

Let's start improving the user information until a proper fix is made: first step #1171

@aaronchongth
Copy link
Collaborator

This can probably be considered fixed by #1238, in the end links without inertial properties or has a mass of 0, that is not attached rigidly with fixed joints, cannot be considered a correct workflow, the best we can do is to warn users about it in the cases where joint lumping and frames cannot resolve them.

Debug messages promoted to warnings

Before #1238, links and joints that were ignored due to inertial issues, were reported via sdfdbg, which logs to a file. Users would just find that these links and joints were dropped silently. Now, warnings would appear when files are parsed, for when links or joints are dropped.

More specific warnings

Other than the names of massless links, which links or joints were ignored, warnings will also provide suggestions to resolve such issues, in the event that joint lumping can help.

urdf2sdf: link[link3] has no <inertial> block defined.
urdf2sdf: allowing joint lumping by removing the <disableFixedJointLumping> tag or setting it to false
on fixed parent joint[joint1_2] could help resolve this warning.
urdf2sdf: parent joint[joint2_3] ignored
urdf2sdf: link[link3] is not modeled in sdf

Joint lumping

Joint lumping is an existing mechanism to reduce the number of fixed joints in a model, see http://sdformat.org/tutorials?tut=sdformat_urdf_extensions&cat=specification&#fixed-joint-lumping.

When a massless link has a fixed parent joint or child joint, the joint lumping mechanism can conveniently resolve the issue, by lumping inertias into the previously massless link, or convert it into frames. However in the event that joint lumping is turned off manually, the warning would suggest that users allow joint lumping to help resolve this massless link issue. See https://github.com/gazebosim/sdformat/blob/sdf12/test/integration/urdf_to_sdf.cc#L475-L561 for an example.

scpeters added a commit that referenced this issue May 10, 2023
When converting from URDF to SDFormat, some links without
an <inertial> block or a small mass may be dropped with only
debug messages in a log file, which are easily missed.
This makes the following changes:

* When a massless link in the middle of a kinematic chain is
  successfully merged to its parent by fixed joint reduction,
  fix bug that was dropping the massless link's child links and
  joints.
* Print no warnings or debug messages when a massless link
  is successfully merged to a parent by fixed joint reduction.
* Promote debug messages to warnings / errors when links
  are dropped to improve visibility. Improve message clarity
  and suggest fixes to the user.
* Change massless threshold test to `> 0` instead of being
  within a 1e-6 tolerance of 0.
* Add unit and integration tests.

Related to #199 and #1007.

(cherry picked from commit 6ffe669)

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>
Co-authored-by: Steve Peters <scpeters@openrobotics.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request major URDF URDF parsing
Projects
None yet
Development

No branches or pull requests