This article describes ROS 2 nodes command line arguments and their syntax.
Authors: Michel Hidalgo
Date Written: 2019-09
Last Modified: 2021-08
As it was the case in ROS 1, ROS 2 nodes allow configuration via command line arguments to a certain degree. In ROS 2, this interface had to become more complex to cope with a larger set of configuration options, an ambiguity in remapping rules and parameter assignment syntax (as a result of the leading underscore name convention for hidden resources), a one-to-many relationship between executables and nodes, to name a few.
Because of this, increasingly precise addressing mechanisms as well as leading double underscores (__
) in some positional arguments, both natural extensions of existing ROS 1 command line features, are combined with ROS 2 specific command line flags.
Flags, in contrast with other custom syntax alternatives, are:
Unfortunately, since these flags coexist with user-defined ones, additional guarding and extraction devices must be put in place – one of the reasons why these were avoided entirely in ROS 1 command lines.
To prevent ROS specific command line flags from colliding with user-defined ones, the former are scoped using the --ros-args
flag and a trailing double dash token (--
):
ros2 run some_package some_node [<user-defined-arg-0>...<user-defined-arg-N>] \
--ros-args [<ros-specific-arg-0>...] -- [<user-defined-arg-N+1>...]
Note that --ros-args --
i.e. an empty set is a valid invocation.
If no user defined arguments are provided after ROS specific arguments are, the double dash token (--
) may be elided:
ros2 run some_package some_node [<user-defined-arg-0>...] --ros-args [<ros-specific-arg-0>...]
Note that a sole trailing --ros-args
remains a valid invocation.
More than one set of ROS specific flags may appear in the same command line:
ros2 run some_package some_node --ros-args [<ros-specific-arg-0>...<ros-specific-arg-N>] -- \
[<user-defined-arg-0>...] --ros-args [<ros-specific-arg-N+1>...]
This way, multiple sources, potentially unaware of each other, can append flags to the command line with no regard for previous sets.
As a quick summary of ROS command line capabilities:
--remap from:=to
or -r from:=to
.--param name:=value
or -p name:=value
where value is in YAML format.--params-file path/to/file.yaml
and a parameters YAML file.--log-level LEVEL_NAME
.--log-config-file path/to/file.config
and a log configuration file.rosout
, use --enable-rosout-logs
or --disable-rosout-logs
stdout
, use --enable-stdout-logs
or --disable-stdout-logs
--enable-external-lib-logs
or --disable-external-lib-logs
--enclave value
or -e value
where value is fully qualified enclave path.For name remapping and parameter assignment, specific nodes can be targeted by prepending the option value with the node name followed by a colon :
, as in --remap my_node:from:=to
and --param my_node:name:=value
.
Remapping rules may be introduced using the --remap
/-r
option.
This option takes a single from:=to
remapping rule.
As an example, to remap from foo
to bar
for some_ros_executable
, one may execute:
ros2 run some_package some_ros_executable --ros-args --remap foo:=bar
or its shorter equivalent:
ros2 run some_package some_ros_executable --ros-args -r foo:=bar
As is, this remapping rule applies to each and every node that some_ros_executable
spawns unless explicitly ignored in code.
To limit it to some_node
, one may execute:
ros2 run some_package some_ros_executable --ros-args -r some_node:foo:=bar
Parameter assignment may be achieved using the --param
/-p
option.
This option takes a single name:=value
assignment statement, where value
is in YAML format and thus YAML type inference rules apply.
As an example, to assign a string value test
to a parameter string_param
for some_ros_executable
, one may execute:
ros2 run some_package some_ros_executable --ros-args --param string_param:=test
or its shorter equivalent:
ros2 run some_package some_ros_executable --ros-args -p string_param:=test
As is, this parameter assignment applies to each and every node that some_ros_executable
spawns unless explicitly ignored in code.
To limit it to some_node
, one may execute:
ros2 run some_package some_ros_executable --ros-args -p some_node:string_param:=test
Multiple parameter assignments can be performed at once using the --params-file
option.
This option takes a YAML file with the following structure:
node0_name:
ros__parameters:
param0_name: param0_value
...
paramN_name: paramN_value
...
nodeM_name:
ros__parameters:
...
Multiple nodes in a single executable can be targeted this way. Note that YAML type inference rules for parameter values apply.
As an example, to assign a string value foo
to a parameter string_param
for some_node
and a string value bar
to that same parameter string_param
but for another_node
upon running some_ros_executable
that contains both, one may execute:
ros2 run some_package some_ros_executable --ros-args --params-file params_file.yaml
where params_file.yaml
reads:
some_node:
ros__parameters:
string_param: foo
another_node:
ros__parameters:
string_param: bar
Wildcards can be used for node names and namespaces as described in Remapping Names.
*
matches a single token delimeted by slashes (/
).
**
matches zero or more tokens delimeted by slashes.
Partial matches are not allowed (e.g. foo*
).
For example,
/**:
ros__parameters:
string_param: foo
will set the parameter string_param
on all nodes,
/**/some_node:
ros__parameters:
string_param: foo
will set the parameter string_param
on nodes named some_node
in any namespace,
/foo/*:
ros__parameters:
string_param: foo
will set the parameter string_param
on any node in the namespace /foo
.
Minimum logging level can be externally set either globally or per logger using the --log-level
option.
As an example, to set a global logging level to DEBUG
for some_ros_executable
, one may execute:
ros2 run some_package some_ros_executable --ros-args --log-level DEBUG
Loggers can be set using the --log-level
option as well:
ros2 run some_package some_ros_executable --ros-args --log-level talker1:=DEBUG --log-level talker2:=WARN --log-level rclcpp:=DEBUG
The minimum logging level of a specific logger will override the globally specified minimum logger level. If a logging level is specified more than once in the passed command line arguments, the last one prevails.
See rcutils
and rcl
logging documentation for reference on existing logging levels.
External logging may be configured using the --log-config-file
option.
This option takes a single configuration file, whose format depends on the actual external logging library being used.
As an example, to pass some_log.config
configuration file to some_ros_executable
, one may execute:
ros2 run some_package some_ros_executable --ros-args --log-config-file some_log.config
Logging to rosout
, stdout
and an external logging library can be independently enabled or disabled.
As an example, to disable logging to rosout
and stdout
but not to an external logging library for some_ros_executable
, one may execute:
ros2 run some_package some_ros_executable --ros-args --disable-rosout-logs --disable-stdout-logs --enable-external-lib-logs
Logging is fully enabled by default, thus --enable-*
options are usually redundant unless a --disable-*
option found earlier in the command line is being overridden.
Enclave assignment may be achieved using the --enclave
/-e
option.
This option takes a single string value
assignment statement, where value
is a fully qualified enclave path used to locate the respective security artifacts within the configured keystore.
As an example, to assign an enclave path /foo/bar
one may execute:
ros2 run some_package some_ros_executable --ros-args --enclave="/foo/bar"
or its shorter equivalent:
ros2 run some_package some_ros_executable --ros-args -e "/foo/bar"
As is, this enclave assignment applies to each and every Domain Participant that some_ros_executable
spawns unless explicitly ignored in code or overridden via security environment variables.
Command line argument extraction happens within rcl
.
When an instance of the --ros-args
flag is found in argv
, until either a double dash token (--
) is found or the end of the argument array is reached, all arguments that follow are taken as ROS specific arguments to be parsed as such.
Remaining arguments can still be accessed by the user via rcl
API.
At the time of writing, most ROS specific arguments target and are thus parsed by rcl
.
This is the case for name remapping rules or parameter assignments flags, to name a few.
However, to support ROS specific arguments that target upper ROS layers e.g. a ROS client library like rclcpp
, arguments unknown to rcl
are left unparsed but accessible by these layers, which in turn can continue parsing or eventually warn the user if unknown arguments remain.
Other, alternative designs were under discussion.
Stop using the same :=
operator for parameter assignments and name remapping rules and introduce additional operators e.g. :=
for parameter assignment and ~=
for name remapping.
This keeps the command line verbosity at a minimum and avoids the need for flags, but is error prone.
Rely on full name addressing to disambiguate operator significance e.g. rosparam://this:=that
would result in a that
string value being assigned to parameter this
while rosremap://this:=that
would result in name this
being remapped to name that
.
Other URL schemes, specific to each interface type e.g. rostopic
and rosservice
, may also be used to further scope remapping rules.
This signficantly increases command line verbosity, but still avoids the need for flags.
Remove the need for double dash tokens (--
), conventionally used to signify the end of CLI options for a command, by adding the --ros-
prefix to all ROS specific command line flags e.g. --ros-remap
, --ros-param
, etc.
In exchange, it makes argument extraction slightly more difficult as all options must be known ahead of time, whereas --ros-args
-based namespacing can achieve the same with a couple rules.
It also increases command line verbosity.