Skip to content

XACRO arg and condition

arg

Simple xacro file that get argument from outside.
if no argument set it use the default.
Using xacro command to substitute xacro sentence

simple xacro
1
2
3
4
5
6
7
8
9
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="robot_name">
    <xacro:arg name="name" default="default_bot"/>

    <link name="$(arg name)">

    </link>


</robot>
usage
1
2
3
4
5
6
7
8
# use default value
xacro demo.urdf.xacro

# set arg from cli
xacro demo.urdf.xacro name:=turtle

# convert to urdf file
xacro demo.urdf.xacro name:=turtle > demo.urdf

launch file

  • Use python pathlib for path construct
  • Use xacro library
  • Check condition example for command and PathJoinSubstitution
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
import xacro
from pathlib import Path

PKG_DESCRIPTION = "turtlebot_description"
URDF_XACRO_FILE = "demo.urdf.xacro"


def generate_launch_description():
    ld =  LaunchDescription()

    xacro_file = Path(
        get_package_share_directory(PKG_DESCRIPTION)) \
        .joinpath("urdf") \
        .joinpath(URDF_XACRO_FILE) \
        .as_posix()


    urdf = xacro.process_file(xacro_file, mappings={"name":"my_name"}).toxml()
    params = {'robot_description': urdf, 'use_sim_time': True}
    node_robot_state_publisher = Node(
        package='robot_state_publisher',
        executable='robot_state_publisher',
        output='screen',
        parameters=[params]
    )


    ld.add_action(node_robot_state_publisher)
    return ld
usage
#-f outout topic full data
ros2 topic echo /robot_description -f

Condition

simple xacro with condition and argument
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="robot_name">
    <xacro:arg name="use_control" default="false"/>

    <xacro:if value="$(arg use_control)">
        <!-- ros2 control-->
         <link name="ros2_control">

         </link>
    </xacro:if>
    <xacro:unless value="$(arg use_control)">
        <!-- other plugin-->
        <link name="ros2">

        </link>
    </xacro:unless>


</robot>

usage

Launch file with argument to control urdf parse (use ros2_control or not) using substitutions class :

  • LaunchConfiguration
  • Command
  • PathJoinSubstitution
launch file that set xacro argument
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.substitutions import LaunchConfiguration, Command, PathJoinSubstitution
from launch.actions import DeclareLaunchArgument

PKG_DESCRIPTION = "turtlebot_description"
URDF_XACRO_FILE = "demo.urdf.xacro"

ARG_USE_ROS2_CONTROL = "use_ros2_control"

def generate_launch_description():
    ld =  LaunchDescription()

    use_ros2_control = LaunchConfiguration(ARG_USE_ROS2_CONTROL)
    use_ros2_control_arg = DeclareLaunchArgument(
            ARG_USE_ROS2_CONTROL,
            default_value='false',
            description='Use sim time if true')

    xacro_file = PathJoinSubstitution([
        get_package_share_directory(PKG_DESCRIPTION),
        'urdf',
        URDF_XACRO_FILE
    ])


    urdf = Command(['xacro ', xacro_file, " use_control:=", use_ros2_control])


    params = {'robot_description': urdf, 'use_sim_time': True}
    node_robot_state_publisher = Node(
        package='robot_state_publisher',
        executable='robot_state_publisher',
        output='screen',
        parameters=[params]
    )

    ld.add_action(use_ros2_control_arg)
    ld.add_action(node_robot_state_publisher)
    return ld
how to launch
1
2
3
4
# with
ros2 launch turtlebot_bringup demo.launch.py use_ros2_control:=True
# Without
ros2 launch turtlebot_bringup demo.launch.py use_ros2_control:=False
echo topic
# -f: output all topic data
ros2 topic echo /robot_description -f