Parameters and Launch
This page adds parameters to the publisher from Publisher/Subscriber, moves configuration into a YAML file, and starts both nodes together with a launch file that can override values from the command line.
Overview
So far, simple_publisher hardcodes its publish rate and message text. Here you will declare those values as parameters with defaults in code, load startup overrides from a YAML file, and start both nodes with a single launch file.
Why It Matters
Hardcoded values force a rebuild (or at least a restart with edited source) for every configuration change. Parameters and launch files let you change behavior — publish rate, topic names, frame IDs, which nodes start together — without touching code, which is how real deployments (and the rest of this site's Mobility and Manipulation examples) are configured.
Prerequisites
Completed Publisher/Subscriber: a working my_ros2_tutorial package with simple_publisher.py and simple_subscriber.py.
Core Concepts
- Declaring a parameter:
self.declare_parameter('name', default_value)inside a node's__init__. By default, a parameter must be declared before it can be read or set. - Reading a parameter:
self.get_parameter('name').value(or.get_parameter_value()for the typed accessor). - YAML parameter files: a file mapping node name ->
ros__parameters-> key/value pairs, loaded at startup by a launch file orros2 run ... --ros-args --params-file. - Launch files: Python scripts (most common in ROS 2) that describe which nodes to start, with which parameters, remappings, and arguments.
ros2 launch <package> <file>.launch.pyruns them. - Launch arguments vs. parameters: a launch argument is a value you pass on the
ros2 launchcommand line; the launch file then uses it to set one or more node parameters. This lets one launch file be reused with different configurations.
Hands-on Steps
1. Add a Parameter to the Publisher
Edit ~/ros2_ws/src/my_ros2_tutorial/my_ros2_tutorial/simple_publisher.py so __init__ declares and uses two parameters instead of hardcoded values:
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class SimplePublisher(Node):
def __init__(self):
super().__init__('simple_publisher')
self.declare_parameter('publish_rate', 1.0)
self.declare_parameter('message_text', 'Hello ROS 2')
publish_rate = self.get_parameter('publish_rate').value
self.message_text = self.get_parameter('message_text').value
self.publisher_ = self.create_publisher(String, 'tutorial_chatter', 10)
self.timer = self.create_timer(1.0 / publish_rate, self.timer_callback)
self.count = 0
def timer_callback(self):
msg = String()
msg.data = f'{self.message_text}: {self.count}'
self.publisher_.publish(msg)
self.get_logger().info(f'Publishing: "{msg.data}"')
self.count += 1
def main(args=None):
rclpy.init(args=args)
node = SimplePublisher()
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
publish_rate is in Hz; the timer period is derived as 1.0 / publish_rate.
2. Create a YAML Parameter File
Create ~/ros2_ws/src/my_ros2_tutorial/config/params.yaml:
simple_publisher:
ros__parameters:
publish_rate: 2.0
message_text: "Hello from YAML"
The top-level key (simple_publisher) must match the node's name.
3. Create a Launch File
Create ~/ros2_ws/src/my_ros2_tutorial/launch/tutorial.launch.py:
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
def generate_launch_description():
config_file = os.path.join(
get_package_share_directory('my_ros2_tutorial'),
'config',
'params.yaml'
)
publish_rate_arg = DeclareLaunchArgument(
'publish_rate',
default_value='2.0',
description='Publisher rate in Hz, overrides the YAML value'
)
publisher_node = Node(
package='my_ros2_tutorial',
executable='simple_publisher',
name='simple_publisher',
parameters=[
config_file,
{'publish_rate': LaunchConfiguration('publish_rate')}
]
)
subscriber_node = Node(
package='my_ros2_tutorial',
executable='simple_subscriber',
name='simple_subscriber'
)
return LaunchDescription([
publish_rate_arg,
publisher_node,
subscriber_node
])
Parameters are applied in the order listed. The YAML file is loaded first, and the following dictionary overrides publish_rate using the launch argument. Because the launch argument has a default value, publish_rate is always supplied by the launch file in this example.
4. Register the Launch and Config Directories in setup.py
Open ~/ros2_ws/src/my_ros2_tutorial/setup.py and add the launch and config directories to data_files so they are installed and discoverable via get_package_share_directory:
import os
from glob import glob
from setuptools import find_packages, setup
package_name = 'my_ros2_tutorial'
setup(
# ... existing fields (name, version, packages, etc.) ...
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
(os.path.join('share', package_name, 'launch'), glob('launch/*.launch.py')),
(os.path.join('share', package_name, 'config'), glob('config/*.yaml')),
],
# ... remaining fields ...
)
Only add the two new tuples for launch and config — keep the existing data_files entries generated by ros2 pkg create.
5. Build, Source, and Launch
cd ~/ros2_ws
colcon build --packages-select my_ros2_tutorial --symlink-install
source install/setup.bash
ros2 launch my_ros2_tutorial tutorial.launch.py
Try overriding the rate from the command line:
ros2 launch my_ros2_tutorial tutorial.launch.py publish_rate:=5.0
Expected Result
With no command-line override, the launch argument defaults to 2.0 Hz. The message text is loaded from the YAML file. With publish_rate:=5.0, the publisher runs at approximately 5 Hz.
Useful Commands
# Parameters of a running node
ros2 param list /simple_publisher
ros2 param get /simple_publisher publish_rate
ros2 param set /simple_publisher publish_rate 3.0
ros2 param dump /simple_publisher # dump current values as YAML
# Launch
ros2 launch my_ros2_tutorial tutorial.launch.py --show-args
ros2 launch my_ros2_tutorial tutorial.launch.py publish_rate:=5.0
Common Problems
ros2 param setsucceeds but node behavior does not change — this example reads its parameters only once during initialization. Changing publish_rate does not recreate the timer, and changing message_text does not update the cached instance value. Restart the node to apply new values, or add parameter-update handling if runtime changes are required.FileNotFoundErrorforparams.yamlat launch time — theconfigdirectory was not added todata_filesinsetup.py, or the workspace was not rebuilt after editingsetup.py. Re-check step 4 and rebuild.- Launch argument override has no effect — the parameters list order matters; a dictionary listed before the YAML file would be overridden by it instead of overriding it. Confirm the YAML file comes first in the
parameters=[...]list. ros2 launchreports "package not found" — the overlay was not sourced after the rebuild, or the launch file has a syntax error. Re-sourceinstall/setup.bashand checkcolcon buildoutput for errors.
Key Takeaways
- Declare parameters with defaults in code, then use YAML files and launch configuration to provide startup overrides when needed.
- YAML parameter files are namespaced by node name under
ros__parameters. - Launch files start multiple nodes together and apply parameters, arguments, and remappings declaratively.
data_filesinsetup.pymust list any non-Python resources (launch/,config/) or they will not be installed intoshare/.
Next
Continue to TF2 to learn how coordinate frames are published and inspected — a concept used heavily by Mobility and Manipulation launch files.