# Problem in adding two Schunk arms plus a simple shape (e.g. cylinder) into .urdf.xacro

Dear Friends, First of all, I apologize if my question may look trivial. I am new with ROS. Here is the problem: The aim is to have two Schunk arms mounted on a simple box. We have a robot.urdf.xacro file. This file "includes" the model of the arm:

<xacro:include filename="$(find schunk_description)/urdf/lwa4d/lwa4d.urdf.xacro" />  And uses it twice to have two arms: <!-- arm --> <xacro:schunk_lwa4d name="arm" parent="world" has_podest="true"> <origin xyz="0 0 0.026" rpy="0 0 0" /> </xacro:schunk_lwa4d> <!-- arm2 --> <xacro:schunk_lwa4d name="arm2" parent="world" has_podest="true"> <origin xyz="0.5 0.5 0.526" rpy="0 0 0" /> </xacro:schunk_lwa4d>  And then when I spawn the xacro file in launch file, 2 arms are loaded in Gazebo. Till here seems fine! But adding a simple shape to this set was/is a pain for me. I define a ros package, called myschunk_gazebo. Then I try to include one simple .xacro file including only a box (or cylinder) in myschunk_gazebo/models and I call the file simple_shape.xacro. I know that ROS can locate the package. I check it with rospack: ros@ros:~/Documents/Damon_CPP/ROS_Workspace/devel$ rospack find myschunk_gazebo
/home/ros/Documents/Damon_CPP/ROS_Workspace/src/myschunk_gazebo


But from here the problem starts! Well, as I know, even this simple shape is called a "robot". So I write simple_shape.xacro. like:

<?xml version="1.0"?>
<robot name="myfirst">
<visual>
<geometry>
</geometry>
</visual>
</robot>


When I launch the file, only the empty space is loaded in gazebo. And between many messages, I thought this might be useful to be put in here:

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

I guess I know what is going on. We should have only one <robot>, which I have in my urdf.xacro file that I spawn in my launch file. But what I do when I include simple_shape.xacro is that I have two <robot> s. And hence, two root links.

I remove the lines related to robot and change simple_shape.xacro to:

<?xml version="1.0"?>
<visual>
<geometry>
</geometry>
</visual>


I also include base_link in my robot.urdf.xacro file:

<link name="base_link"/>


And loads only empty space. I don't think the inclusion of the file should be a problem. But I highly doubt if I use the shape in robot.urdf.xacro properly, or my codes for generating the shape are correct.

It would be so nice if a friend can clarify for me what is going on. Thanks. :)

edit retag close merge delete

Sort by » oldest newest most voted

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).

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. See wiki/urdf/Tutorials - Using Xacro to Clean Up a URDF File: Leg macro for an example.

more

Dear gvdhoorn, Thank you so much for your answer. The reason that I am replying late is that I realized I need to learn urdf more deeply. So I started from the beginning and at the end I was able to solve the problem. I will write my experience here in the form of an answer soon. Thanks again. :)

( 2015-07-23 04:11:03 -0600 )edit

( 2015-07-28 04:38:44 -0600 )edit

Ow, Ok. I will do so. Plus, if anybody else is reading this, I should mention again that I will write the problem and the solution more in detail as soon as I have time (right now I have 15 days to my thesis deadline! :( )

( 2015-07-29 00:41:20 -0600 )edit