Skip to content

Instantly share code, notes, and snippets.

@clalancette
Created December 5, 2019 18:45
Show Gist options
  • Save clalancette/5d15df1f54a1e01946659dbfa6c46c30 to your computer and use it in GitHub Desktop.
Save clalancette/5d15df1f54a1e01946659dbfa6c46c30 to your computer and use it in GitHub Desktop.
Using xacro with ROS 2 python launch
The goal here is to be able to use the ROS 2 python launch system to generate URDF files from xacro files, utilizing substitution. All of the comments below are an attempt to solve this problem.
# Robot state publisher
In order to make this work, it is easiest to use the refactored robot_state_publisher branch https://github.com/ros/robot_state_publisher/tree/ros2-refactor . The reason for this is that the refactor takes the `robot_description` as a parameter rather than as an argument on the command-line. This branch isn't currently reviewed or released into any ROS 2 distribution, so it needs to be built from source. (I'll note that it is probably *possible* to make all of this work with the version of robot_state_publisher released into Eloquent, but the rest of this comment will assume you are using the ros2-refactor branch).
```
source /opt/ros/eloquent/setup.bash
mkdir -p rsp_ws/src
cd rsp_ws/src
git clone https://github.com/ros/robot_state_publisher -b ros2-refactor
cd ..
colcon build
```
# Xacro file
The rest of the comments will assume the simple xacro file as follows. More complex ones will probably work but have not been tested:
```
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="test">
<xacro:arg name="length" default="0.6"/>
<xacro:property name="length" value="$(arg length)"/>
<xacro:arg name="radius" default="0.2"/>
<xacro:property name="radius" value="$(arg radius)"/>
<link name="base_link">
<visual>
<geometry>
<cylinder length="${length}" radius="${radius}"/>
</geometry>
<material name="blue"/>
</visual>
</link>
</robot>
```
# Launch file
Now we can put the above together and create a launch file that will take the xacro file, create a URDF file from it (incorporating any mappings from the user):
```
import launch
import launch_ros.actions
import xacro
def generate_launch_description():
doc = xacro.process_file('/home/ubuntu/rsp_ws/test-desc.urdf.xacro', mappings={'radius': '0.9'})
robot_desc = doc.toprettyxml(indent=' ')
params = {'robot_description': robot_desc}
rsp = launch_ros.actions.Node(package='robot_state_publisher',
node_executable='robot_state_publisher_node',
output='both',
parameters=[params])
return launch.LaunchDescription([rsp])
```
Note that the mappings parameter is a dictionary of keys to values, so as many mapping as necessary can be substituted in.
# Output
The output will be as follows:
```
<?xml version=\"1.0\" ?>
<!-- =================================================================================== -->
<!-- | This document was autogenerated by xacro from /home/ubuntu/rsp_ws/test-desc.urdf.xacro | -->
<!-- | EDITING THIS FILE BY HAND IS NOT RECOMMENDED | -->
<!-- =================================================================================== -->
<robot name="test">
<link name="base_link">
<visual>
<geometry>
<cylinder length="0.6" radius="0.9"/>
</geometry>
<material name="blue"/>
</visual>
</link>
</robot>
```
@superseppl
Copy link

Thanks for the detailed explanation. One question, how can I pass LaunchArguments to the xacro files?

@MrBlenny
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment