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

Just thought I'd share a workaround that works in Foxy now, without the need to checkout galactic/rolling versions of packages, using OpaqueFunction and the xacro python library:

#!/usr/bin/env python3

import os

from ament_index_python.packages import get_package_share_directory

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node

# add these imports:
import xacro
from launch.actions import OpaqueFunction


# evaluates LaunchConfigurations in context for use with xacro.process_file(). Returns a list of launch actions to be included in launch description
def evaluate_xacro(context, *args, **kwargs):
    use_sim_time = LaunchConfiguration('use_sim_time').perform(context)
    model_path = LaunchConfiguration('model_path').perform(context)
    xacro_prefix = LaunchConfiguration('xacro_prefix').perform(context)

    robot_state_publisher_node = Node(
      package='robot_state_publisher',
      executable='robot_state_publisher',
      name='robot_state_publisher',
      output='screen',
      parameters=[{
        'use_sim_time': use_sim_time,
        'robot_description': xacro.process_file(model_path, mappings={'prefix': xacro_prefix}).toxml()
      }])

    return [robot_state_publisher_node]

def generate_launch_description():
  return LaunchDescription([

    DeclareLaunchArgument(
      'use_sim_time',
      default_value="false",
      description='Flag to use simulation time'),   

    DeclareLaunchArgument(
      'model_path',
      default_value=os.path.join(get_package_share_directory('my_package'),'urdf','test.urdf'),
      description='path to urdf'),

    DeclareLaunchArgument(
      'xacro_prefix',
      default_value="my_robot_",
      description='prefix argument input to xacro file'),   

    # add OpaqueFunction to evaluate xacro file in context and pass to any nodes that need it
    OpaqueFunction(function=evaluate_xacro)  
  ])

While it is admittedly a bit harder to read than a typical launch file, it checks all the boxes for my use cases; namely it:

  • supports xacro argument inputs when parsing a file
  • supports dynamically set paths using LaunchConfigurations
  • supports URDF containing special characters (though I haven't tested this exhaustively)