ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

tl;dr: you probably forgot to add a joint between world and your box/cylinder's base_link.


Longer version: a urdf (which is what the .xacro files are turned into before Gazebo or anything else in ROS gets to them) models a scene as a tree. So every link needs to be connected to another. Forests (set of disconnected trees, or islands of links) are not allowed.

In your case, the two calls to xacro:schunk_lwa4d supply that macro with two important arguments:

  1. parent="world"
  2. <origin xyz="0 0 0.026" rpy="0 0 0" />

Argument 1 is used internally in xacro:schunk_lwa4d to setup a fixed joint (or parent-child relation) between a link outside of the schunk_lwa4d macro called world and the root of the LWA 4D (here). One of those two links will be made the root of the LWA 4D model, depending on the has_podest argument.

Argument 2 then defines the relative transform between that world link and the ${name}_podest_link here (in case has_podest=true), or here for ${name}_base_link if you have has_podest=false.

Now the world link can either be predefined by Gazebo, or added by you to your composite xacro (I use the term composite to mean an xacro that does not really define anything new itself, but is a collection of instantiations of other xacro:macros). In all cases you end up with a tree structure, in which world is the root.

Failed to find root link: Two root links found: [base_link] and [world]

This should now be obvious, but in the case where you added the box/cylinder, you seem to not have defined any joint linking the base_link (or its root) of your box to the rest of the scene. That results in two forests (ie: islands) and that is not allowed in urdf (and so Gazebo can't work with it either).

Solution: define a joint (probaby a fixed one) which fixes your box/cylinder in your scene, using origin to define the relative transform between the parent and the base_link of your new addition (or whatever you end up naming the root of your model). See wiki/urdf/Tutorials - Using Xacro to Clean Up a URDF File: Leg macro for an example.


Note also that all links in a urdf must be uniquely named: you cannot have two base_links. This is why most xacros include a prefix or name parameter, which is prefixed to all internally defined links. It essentially namespaces all links, allowing you to instantiate a single xacro macro multiple times, by using different values for the prefix (in your case arm and arm2). You should probably do something similar with your box/cylinder.

tl;dr: you probably forgot to add a joint between world and your box/cylinder's base_link.


Longer version: a urdf (which is what the .xacro files are turned into before Gazebo or anything else in ROS gets to them) models a scene as a tree. So every link needs to be connected to another. Forests (set of disconnected trees, or islands of links) are not allowed.

In your case, the two calls to xacro:schunk_lwa4d supply that macro with two important arguments:

  1. parent="world"
  2. <origin xyz="0 0 0.026" rpy="0 0 0" />

Argument 1 is used internally in xacro:schunk_lwa4d to setup a fixed joint (or parent-child relation) between a link outside of the schunk_lwa4d macro called world and the root of the LWA 4D (here). One of those two links will be made the root of the LWA 4D model, depending on the has_podest argument.

Argument 2 then defines the relative transform between that world link and the ${name}_podest_link here (in case has_podest=true), or here for ${name}_base_link if you have has_podest=false.

Now the world link can either be predefined by Gazebo, or added by you to your composite xacro (I use the term composite to mean an xacro that does not really define anything new itself, but is a collection of instantiations of other xacro:macros). In all cases you end up with a tree structure, in which world is the root.

Failed to find root link: Two root links found: [base_link] and [world]

This should now be obvious, but in the case where you added the box/cylinder, you seem to not have defined any joint linking the base_link (or its root) of your box to the rest of the scene. That results in two forests (ie: islands) and that is not allowed in urdf (and so Gazebo can't work with it either).

Solution: define a joint (probaby a fixed one) which fixes your box/cylinder in your scene, using origin to define the relative transform between the parent and the base_link of your new addition (or whatever you end up naming the root of your model). See wiki/urdf/Tutorials - Using Xacro to Clean Up a URDF File: Leg macro for an example.model).


Note also that all links in a urdf must be uniquely named: you cannot have two base_links. This is why most xacros include a prefix or name parameter, which is prefixed to all internally defined links. It essentially namespaces all links, allowing you to instantiate a single xacro macro multiple times, by using different values for the prefix (in your case arm and arm2). You should probably do something similar with your box/cylinder.

box/cylinder. See wiki/urdf/Tutorials - Using Xacro to Clean Up a URDF File: Leg macro for an example.