ROS2 Parameters Introduction
ROS2 Parameters are one means to change certain values in a node during runtime. They are associated initialized, set, and retrieved at the level of individual nodes, and hence their lifetimes are the same as their nodes’ lifetimes.
Each parameter has a key, value, and a descriptor.
- The key is a string
- The value is one of the following types:
bool, int64, float64, string, byte[], bool[], int64[], float64[] string[]
- The descriptor is a parameter’s description
Here is an example of how we can use them:
- Initialize / declare
-
Command Delare params?
1 2 3 4 5
from rclpy.node import Node class ParameterNode(Node): def __init__(self): super().__init__('parameter_node') self.declare_parameter('shared_value', 42.0)
-
When a parameter needs to take in different types, use
ParameterDescriptor
with the dynamic_typing member variable set to true1 2 3
from rcl_interfaces.msg import ParameterDescriptor descriptor = ParameterDescriptor(dynamic_typing=True) self.declare_parameter('dynamic_param', 0, descriptor)
-
In CLI:
-
ros2 param list
shows all parameters:1 2 3
/teleop_turtle: qos_overrides./parameter_events.publisher.depth use_sim_time
-
-
- Get
param_value = self.get_parameter_or(param_name, None)
-
For parameters that can’t be known ahead of time, they can be instantiated as
allow_undeclared_parameters = True
1 2 3 4 5 6 7 8 9 10 11
```python class MyNode(Node): def __init__(self): super().__init__('my_node', allow_undeclared_parameters=True) def get_dynamic_param(self, param_name): param_value = self.get_parameter_or(param_name, None) return param_value def main(args=None): ... node.get_dynamic_param('undeclared_param') # Should print a warning and return None ```
- In CLI:
ros2 param get <node_name> <parameter_name>
ros2 param list
: a CLI python helper that pings a running node to retrive their parameters. It callslist_parameter
service of each node.- So there could be a an exception like
Exception while calling service of node 'my_node': None
where the node is busy
-
View all params of a node, and they can be saved into an yaml:
1 2 3 4
``` ros2 param dump <node_name> ros2 param dump /turtlesim > turtlesim.yaml ```
- Set.
-
In code?
1 2 3 4 5 6 7
```python from rclpy.parameter import Parameter class MyNode(Node): def update_param(self, key, val): param = Parameter(key, Parameter.Type.INTEGER, val) self.set_parameters([param]) ```
-
In CLI:
ros2 param set <node_name> <parameter_name> <value>
-
Load from a yaml file:
1 2 3
``` ros2 param load <node_name> <parameter_file> ```
-
Load parameters on start up:
1 2 3
``` ros2 run <package_name> <executable_name> --ros-args --params-file <file_name> ```
-
Rclcpp Parameters
Overriding ROS 2 Parameters
You can expose and override parameters in two parts:
- Inside your node (
RunImuNode
): in the constructor, declare each parameter (with an optional default) and read it into a member:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class RunImuNode : public rclcpp::Node
{
public:
explicit RunImuNode(const rclcpp::NodeOptions &opts = {})
: Node("run_imu_node", opts)
{
// 1) Declare parameters (here with defaults)
this->declare_parameter<bool>("is_millig", true);
this->get_parameter("is_millig", is_millig_);
}
private:
bool is_millig_;
};
- From “user” or test code: when you instantiate the node, supply overrides via NodeOptions:
1
2
3
4
5
6
7
rclcpp::NodeOptions options;
options.parameter_overrides({
{"is_millig", false},
});
auto run_imu_node =
std::make_shared<RunImuNode>(options);
Passing --ros-args -p <ARG>
to a ROS 2 GTest
You can make your test binary accept ROS 2 parameters (e.g. visualize
) without touching your node by:
- Providing a custom
main()
: Capture the fullargc/argv
(including--ros-args
) and use them for bothrclcpp::init()
and Google Test:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <gtest/gtest.h>
#include <rclcpp/rclcpp.hpp>
// Store all CLI args so we can forward them later
static std::vector<std::string> g_test_args;
int main(int argc, char ** argv)
{
::testing::InitGoogleTest(&argc, argv);
// Copy original args (including --ros-args)
g_test_args.assign(argv, argv + argc);
rclcpp::init(argc, argv);
int ret = RUN_ALL_TESTS();
rclcpp::shutdown();
return ret;
}
- Forwarding the ROS 2 args into your node. In your test fixture’s
SetUp()
, pass alongg_test_args
viaNodeOptions::arguments()
, then declare and read your test-only parameter:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
std::vector<std::string> g_test_args;
class TestIntegrateIMU : public ::testing::Test {
protected:
bool visualize_{false};
void SetUp() override {
// 1) Build options with the exact same CLI args
rclcpp::NodeOptions options;
options.arguments(g_test_args);
run_imu_node_ = std::make_shared<RunImuNode>(options);
// 4) Declare & read the test-only “visualize” flag
run_imu_node_->declare_parameter("visualize", false);
run_imu_node_->get_parameter("visualize", visualize_);
// …
}
};
- Run test with:
./test_integrate_imu --ros-args -p visualize:=true