Skip to content

Feature request: ros2 launch --dump-params to statically export resolved node parameters #549

@Tiryoh

Description

@Tiryoh

Description

Add a --dump-params option to ros2 launch that evaluates a launch file in a
process-suppressed "dry-run" mode and prints, in standard ROS 2 params-file YAML
format, the parameter sets that would be passed to each Node /
ComposableNode action — without actually starting any process.

ros2 launch --dump-params <package> <launch_file> [launch arguments...]

Expected output (single YAML document on stdout):

/amcl:
  ros__parameters:
    base_frame_id: base_footprint
    gui_publish_rate: 50.0
    laser_model_type: likelihood_field
/move_base:
  ros__parameters:
    ...

This is the ROS 2 equivalent of ROS 1's roslaunch --dump-params, adapted to
the ROS 2 parameter model.

This is a focused follow-up to the long-standing umbrella issue
ros2/launch#441 (open since 2020,
help wanted), narrowed to --dump-params only so its design and review stay
tractable. --nodes and --args can be tracked separately. Filing here rather
than ros2/launch because the affected code paths (ros2launch CLI verb,
Node / ComposableNode actions, SetParameter, to_parameters_list) all
live in launch_ros.

Motivation

ROS 1's roslaunch --dump-params writes all parameters the launch file would
push to the Parameter Server as YAML:

$ roslaunch turtlebot3_navigation turtlebot3_navigation.launch --dump-params | head -n 10
/amcl/base_frame_id: base_footprint
/amcl/gui_publish_rate: 50.0
/amcl/initial_pose_a: 0.0
/amcl/kld_err: 0.02
/amcl/laser_lambda_short: 0.1
/amcl/laser_likelihood_max_dist: 2.0
/amcl/laser_max_beams: 180
/amcl/laser_max_range: 3.5
/amcl/laser_model_type: likelihood_field
/amcl/laser_sigma_hit: 0.2

This is useful for:

  • CI / review — diffing the effective parameter set across branches or
    environments to catch misconfigurations before deployment.
  • Auditing / documentation — producing an authoritative parameter snapshot
    per launch file without running the robot or any drivers.
  • Tooling — linters, config validators, and deployment systems consuming
    the output programmatically.

In ROS 2, the only current way to obtain the resolved per-node parameter set is
to actually start the system and run ros2 param dump <node>, which is
impractical in CI or when target hardware is absent.

ros2 launch --print / --print-description show the launch description tree
but do not resolve the parameter values that end up at each node.

Design / Implementation Considerations

Evaluation mode

The launch description is visited in a dry-run mode that resolves all
actions (OpaqueFunction, IncludeLaunchDescription, GroupAction, ...) to
discover the realized set of Node / ComposableNode / LoadComposableNodes
actions, but suppresses process spawning and composable-node load service
calls
(ExecuteProcess, container service requests).

Output

A single YAML document on stdout, standard params-file format:

  • Key: launch-time-resolved fully qualified node name (namespace + name
    after substitution and PushRosNamespace). __node / __ns remaps passed
    via remappings / ros_arguments are applied to the dumped key so that the
    output is directly usable as --params-file.
  • Exit-zero guarantee: when the command exits 0, stdout is valid params
    YAML parseable by the standard loader.

Merge order (must match runtime)

  1. SetParameter / SetParametersFromFile global-scope params,
  2. the parameters=[...] list in order, files and dicts freely interleaved,
  3. -p key:=value entries in ros_arguments / arguments.

YAML wildcard (/**) entries are overridden by exact-FQN entries regardless
of file order (matching rcl).

ComposableNode

Dumped via the same to_parameters_list transformation the runtime uses to
build the load-service request, preserving wildcard / exact-FQN semantics.

Dynamic / unresolvable constructs

  • OpaqueFunction: executed (it can create nodes); any ExecuteProcess
    returned is intercepted, not spawned.
  • EventHandler / Timer / lifecycle-driven actions: not dumped; reported
    on stderr as skipped: triggered by runtime event.
  • Substitutions that genuinely require runtime state (LocalSubstitution,
    custom substitutions reading external state): non-zero exit with a stderr
    diagnostic listing the offending action; stdout remains empty.
  • The design deliberately avoids in-YAML sentinels (e.g. <unresolved>) since
    they would silently corrupt downstream params-file consumers.

Duplicate FQN handling

  • Identical final param sets → coalesce.
  • Divergent param sets → non-zero exit with diagnostic (avoids YAML key
    collision / silent merging).
  • A future --allow-duplicates could emit a multi-document stream if a real
    use case appears.

Acceptance criteria

  • CLI: ros2 launch --dump-params <pkg> <file> [args...] accepted; same
    launch-argument syntax as ros2 launch.
  • Output: single YAML on stdout; top-level keys are launch-resolved FQNs;
    values follow ros__parameters: schema.
  • Merge order matches runtime (SetParameter → ordered parameters list →
    -p in ros_arguments); FQN beats wildcard regardless of file order.
  • __node / __ns remaps applied to the dumped key.
  • ComposableNode / LoadComposableNodes dumped via the same
    transformation as the runtime service request.
  • Dry-run: no ExecuteProcess spawned, no composable-node load service
    called.
  • Dynamic-only actions skipped with stderr diagnostics; runtime-only
    substitutions cause non-zero exit with stderr diagnostics.
  • Duplicate FQN with divergent params → non-zero exit; identical →
    coalesce.
  • Exit 0 ⇒ stdout is valid params-file YAML.
  • Smoke test: the dumped YAML, passed back as --params-file, yields the
    same effective parameter values at the running node.

Additional Information

Alternatives considered

  • ros2 launch --print-description — structural only; no resolved values.
  • Running the system + ros2 param dump — requires a runnable target.
  • Parsing the launch file manually — brittle; duplicates launch evaluation.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions