Launch Files and Parameters
Overview
In complex robotic systems like humanoid robots, managing multiple nodes and their configurations can become challenging. ROS 2 provides launch files and parameters to simplify the process of starting and configuring multiple nodes simultaneously.
Launch Files
Launch files allow you to start multiple nodes with a single command, configure their parameters, and manage their lifecycle. They can be written in Python, XML, or YAML.
Python Launch Files
Python launch files provide the most flexibility and are the recommended approach for complex systems:
# example_launch.py
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from ament_index_python.packages import get_package_share_directory
def generate_launch_description():
# Declare launch arguments
use_sim_time = LaunchConfiguration('use_sim_time')
return LaunchDescription([
# Declare launch arguments
DeclareLaunchArgument(
'use_sim_time',
default_value='false',
description='Use simulation (Gazebo) clock if true'),
# Launch a node
Node(
package='demo_nodes_cpp',
executable='talker',
name='talker_node',
parameters=[
{'use_sim_time': use_sim_time},
{'frequency': 1.0}
],
remappings=[
('chatter', 'my_chatter')
]
),
# Launch another node
Node(
package='demo_nodes_cpp',
executable='listener',
name='listener_node',
parameters=[
{'use_sim_time': use_sim_time}
]
)
])
Launch File Concepts
Actions
Node: Launch a ROS nodeDeclareLaunchArgument: Define a launch argumentLogInfo: Print a message to the consoleTimerAction: Execute actions after a delayExecuteProcess: Run an external process
Substitutions
LaunchConfiguration: Access launch argument valuesPathJoinSubstitution: Join path componentsTextSubstitution: Literal textPythonExpression: Python expressions
XML Launch Files
XML launch files provide a more declarative approach:
<launch>
<arg name="use_sim_time" default="false"/>
<node pkg="demo_nodes_cpp" exec="talker" name="talker_node">
<param name="use_sim_time" value="$(var use_sim_time)"/>
<param name="frequency" value="1.0"/>
<remap from="chatter" to="my_chatter"/>
</node>
<node pkg="demo_nodes_cpp" exec="listener" name="listener_node">
<param name="use_sim_time" value="$(var use_sim_time)"/>
</node>
</launch>
YAML Launch Files
YAML launch files offer a more readable format:
launch:
- node:
pkg: "demo_nodes_cpp"
exec: "talker"
name: "talker_node"
parameters:
- use_sim_time: $(var use_sim_time)
- frequency: 1.0
remappings:
- ["chatter", "my_chatter"]
Parameters
Parameters in ROS 2 allow you to configure nodes at runtime. They can be declared, set, and changed dynamically.
Parameter Declaration
# Python parameter declaration
class ParameterNode(Node):
def __init__(self):
super().__init__('parameter_node')
# Declare parameters with default values and descriptions
self.declare_parameter('robot_name', 'humanoid_robot')
self.declare_parameter('max_velocity', 1.0)
self.declare_parameter('safety_enabled', True)
# Access parameter values
robot_name = self.get_parameter('robot_name').value
max_velocity = self.get_parameter('max_velocity').value
safety_enabled = self.get_parameter('safety_enabled').value
// C++ parameter declaration
class ParameterNode : public rclcpp::Node
{
public:
ParameterNode() : Node("parameter_node")
{
// Declare parameters
this->declare_parameter("robot_name", "humanoid_robot");
this->declare_parameter("max_velocity", 1.0);
this->declare_parameter("safety_enabled", true);
// Get parameter values
std::string robot_name = this->get_parameter("robot_name").as_string();
double max_velocity = this->get_parameter("max_velocity").as_double();
bool safety_enabled = this->get_parameter("safety_enabled").as_bool();
}
};
Parameter Callbacks
You can react to parameter changes:
from rcl_interfaces.msg import ParameterEvent
def parameter_callback(self, parameter_list):
for param in parameter_list.parameters:
if param.name == 'max_velocity':
new_value = param.value.double_value
self.get_logger().info(f'Max velocity changed to: {new_value}')
# Handle the parameter change
self.update_velocity_limits(new_value)
return SetParametersResult(successful=True)
# Register the callback
self.add_on_set_parameters_callback(self.parameter_callback)
Parameter Files (YAML)
Parameters can be loaded from YAML files:
/**: # Applies to all nodes
ros__parameters:
use_sim_time: false
parameter_node: # Applies to node named 'parameter_node'
ros__parameters:
robot_name: "advanced_humanoid"
max_velocity: 2.0
safety_enabled: true
joint_limits:
left_leg:
min: -1.57
max: 1.57
right_arm:
min: -2.0
max: 2.0
Advanced Launch Features
Conditional Launch
Launch nodes based on conditions:
from launch.conditions import IfCondition, UnlessCondition
from launch.substitutions import LaunchConfiguration
use_gui = LaunchConfiguration('use_gui')
# Launch node only if use_gui is true
Node(
package='rviz2',
executable='rviz2',
condition=IfCondition(use_gui)
),
# Launch node unless use_gui is true
Node(
package='rqt_graph',
executable='rqt_graph',
condition=UnlessCondition(use_gui)
)
Composition
Run multiple nodes in the same process for better performance:
from launch_ros.actions import ComposableNodeContainer
from launch_ros.descriptions import ComposableNode
container = ComposableNodeContainer(
name='image_processing_container',
namespace='',
package='rclcpp_components',
executable='component_container',
composable_node_descriptions=[
ComposableNode(
package='image_proc',
plugin='image_proc::RectifyNode',
name='rectify_node'
),
ComposableNode(
package='image_view',
plugin='image_view::ImageViewNode',
name='image_view_node'
)
]
)
Lifecycle Nodes
Manage node lifecycle explicitly:
from launch_ros.actions import LifecycleNode
LifecycleNode(
package='my_package',
executable='my_lifecycle_node',
name='my_lifecycle_node',
namespace='',
parameters=[...]
)
Practical Applications in Humanoid Robotics
Robot Bringup
A typical humanoid robot launch file might include:
def generate_launch_description():
return LaunchDescription([
# Robot state publisher
Node(
package='robot_state_publisher',
executable='robot_state_publisher',
parameters=[robot_description]
),
# Joint state publisher
Node(
package='joint_state_publisher',
executable='joint_state_publisher',
parameters=[{'use_sim_time': use_sim_time}]
),
# IMU driver
Node(
package='imu_driver',
executable='imu_node',
parameters=[
{'sensor_port': '/dev/ttyUSB0'},
{'baud_rate': 115200}
]
),
# Controller manager
Node(
package='controller_manager',
executable='ros2_control_node',
parameters=[controller_config]
)
])
Simulation vs Real Robot
Different configurations for simulation and real hardware:
# Simulation-specific launch
sim_nodes = [
Node(
package='gazebo_ros',
executable='spawn_entity.py',
arguments=['-topic', 'robot_description', '-entity', 'humanoid_robot']
)
]
# Real robot-specific launch
real_nodes = [
Node(
package='real_robot_driver',
executable='hardware_interface'
)
]
# Conditionally include based on argument
DeclareLaunchArgument('sim_mode', default_value='false'),
# ...
# Use IfCondition(sim_mode) to choose between sim_nodes and real_nodes
Parameter Management for Different Robot Configurations
Different humanoid robots may have different joint configurations:
# For Atlas robot
atlas_config:
ros__parameters:
joints:
- head_pan
- head_tilt
- left_arm_shoulder_pitch
- left_arm_shoulder_roll
# ... more joints
# For NAO robot
nao_config:
ros__parameters:
joints:
- HeadYaw
- HeadPitch
- LShoulderPitch
- LShoulderRoll
# ... more joints
Best Practices
Launch File Organization
- Use descriptive names for launch files
- Group related functionality in separate launch files
- Use include directives to compose complex launch systems
- Document launch arguments and their purposes
Parameter Management
- Group related parameters logically
- Use meaningful parameter names
- Provide appropriate default values
- Document parameter meanings and valid ranges
- Use parameter files for complex configurations
Performance Considerations
- Use composition for nodes that communicate frequently
- Consider process vs thread boundaries for performance
- Use appropriate QoS settings in launch files
- Monitor resource usage during launch
Summary
Launch files and parameters are essential tools for managing complex robotic systems. They allow you to configure and start multiple nodes with a single command, making it easier to manage humanoid robotics applications. Proper use of these tools leads to more maintainable and configurable robotic systems.