# '#pragma once' equivalent for urdf/xacro files

I have multiple urdf files representing different components of a robot. As I don't want to define materials multiple times in different files, I created a file containing those definitions ('materials.urdf.xacro'). The file looks like this:

<?xml version="1.0"?>

<robot>

<material name="Black">
<color rgba="0.0 0.0 0.0 1.0"/>
</material>

<material name="Blue">
<color rgba="0.0 0.0 0.8 1.0"/>
</material>

<material name="Green">
<color rgba="0.0 0.8 0.0 1.0"/>
</material>

<material name="Grey">
<color rgba="0.2 0.2 0.2 1.0"/>
</material>

<material name="DarkGrey">
<color rgba="0.1 0.1 0.1 1.0"/>
</material>

<material name="Orange">
<color rgba="${255/255}${108/255} ${10/255} 1.0"/> </material> <material name="Brown"> <color rgba="${222/255} ${207/255}${195/255} 1.0"/>
</material>

<material name="Red">
<color rgba="0.8 0.0 0.0 1.0"/>
</material>

<material name="White">
<color rgba="1.0 1.0 1.0 1.0"/>
</material>

</robot>


I include them via

<xacro:include filename="$(find package_name)/urdf/materials.urdf.xacro" />  in a component file ('laser.urdf.xacro') and in the robot definition file ('robot.urdf.xacro') with itself includes 'laser.urdf.xacro'). When I try to run the urdf file via rviz, I get an error: material 'Black' is not unique.  I presume it's due to the indirect second include of the 'materials.urdf.xacro' file, just like the problems you would have in C++ without '#pragma once' or the '#ifndef ... => #define ... => #endif' construct. So is there an equivalent to this in urdf/xacro files? • ROS Kinetic • Ubuntu 16.04 edit retag close merge delete ## 2 Answers Sort by » oldest newest most voted I'm not aware of this kind of workaround and it doesn't seem possible. What you can do is instead of having multiple <xacro:include ..../> tags in all of your urdf files is to can create a new file like standalone.urdf.xacro (i usually do my_robot_name_standalone.urdf.xacro) and inside it you only use the <xacro:include../> to add all of your urdf files (which have no includes anymore). With that you ensure to avoid multiple inclusions. Here's an exemple : <?xml version="1.0"?> <robot name="my_robot" xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor" xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller" xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface" xmlns:xacro="http://ros.org/wiki/xacro"> <xacro:include filename="$(find my_robot_description)/urdf/common_properties.urdf.xacro" />
<xacro:include filename="\$(find my_robot_description)/urdf/my_robot.urdf.xacro" />
</robot>

more

FYI: the playerstage stuff is not needed any longer.

( 2018-10-04 01:49:50 -0600 )edit

Okay I didn't know that, thank you.

( 2018-10-04 01:52:03 -0600 )edit

I presume it's due to the indirect second include of the 'materials.urdf.xacro' file, just like the problems you would have in C++ without '#pragma once' or the '#ifndef ... => #define ... => #endif' construct.

So is there an equivalent to this in urdf/xacro files?

Not that I know of.

Personally I work around this by using "anonymous" materials and using a macro to create them. See here for an example.

It's actually an error from the URDF parser, not xacro itself (it doesn't care).

You may also want to look into namespace support in xacro.

Edit: I've never tried it, but perhaps the conditional support in xacro can now prevent pieces of xacro from being evaluated. You could use that to wrap everything in a xacro:if and then set a xacro:property inside the body.

more