Skip to main content

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 or ros2 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.py runs them.
  • Launch arguments vs. parameters: a launch argument is a value you pass on the ros2 launch command 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 set succeeds 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.
  • FileNotFoundError for params.yaml at launch time — the config directory was not added to data_files in setup.py, or the workspace was not rebuilt after editing setup.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 launch reports "package not found" — the overlay was not sourced after the rebuild, or the launch file has a syntax error. Re-source install/setup.bash and check colcon build output 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_files in setup.py must list any non-Python resources (launch/, config/) or they will not be installed into share/.

Next​

Continue to TF2 to learn how coordinate frames are published and inspected — a concept used heavily by Mobility and Manipulation launch files.