Skip to content

Commit 87bf20a

Browse files
authored
Add ParameterDescriptor to 'Using parameters in a class (C++)' (ros2#2865)
* Rename node name in "Using parameters" C++ tutorial to be consistent with Python tutorial. Signed-off-by: Tan Chian Fern <[email protected]> Signed-off-by: Chris Lalancette <[email protected]>
1 parent 77646ce commit 87bf20a

File tree

2 files changed

+126
-90
lines changed

2 files changed

+126
-90
lines changed

source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-CPP.rst

Lines changed: 101 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -70,37 +70,45 @@ Inside the ``ros2_ws/src/cpp_parameters/src`` directory, create a new file calle
7070

7171
.. code-block:: C++
7272

73-
#include <rclcpp/rclcpp.hpp>
7473
#include <chrono>
75-
#include <string>
7674
#include <functional>
75+
#include <string>
76+
77+
#include <rclcpp/rclcpp.hpp>
7778

7879
using namespace std::chrono_literals;
7980

80-
class ParametersClass: public rclcpp::Node
81+
class MinimalParam : public rclcpp::Node
8182
{
82-
public:
83-
ParametersClass()
84-
: Node("parameter_node")
85-
{
86-
this->declare_parameter<std::string>("my_parameter", "world");
87-
timer_ = this->create_wall_timer(
88-
1000ms, std::bind(&ParametersClass::respond, this));
89-
}
90-
void respond()
91-
{
92-
this->get_parameter("my_parameter", parameter_string_);
93-
RCLCPP_INFO(this->get_logger(), "Hello %s", parameter_string_.c_str());
94-
}
95-
private:
96-
std::string parameter_string_;
97-
rclcpp::TimerBase::SharedPtr timer_;
83+
public:
84+
MinimalParam()
85+
: Node("minimal_param_node")
86+
{
87+
this->declare_parameter("my_parameter", "world");
88+
89+
timer_ = this->create_wall_timer(
90+
1000ms, std::bind(&MinimalParam::timer_callback, this));
91+
}
92+
93+
void timer_callback()
94+
{
95+
std::string my_param =
96+
this->get_parameter("my_parameter").get_parameter_value().get<std::string>();
97+
98+
RCLCPP_INFO(this->get_logger(), "Hello %s!", my_param.c_str());
99+
100+
std::vector<rclcpp::Parameter> all_new_parameters{rclcpp::Parameter("my_parameter", "world")};
101+
this->set_parameters(all_new_parameters);
102+
}
103+
104+
private:
105+
rclcpp::TimerBase::SharedPtr timer_;
98106
};
99107

100-
int main(int argc, char** argv)
108+
int main(int argc, char ** argv)
101109
{
102110
rclcpp::init(argc, argv);
103-
rclcpp::spin(std::make_shared<ParametersClass>());
111+
rclcpp::spin(std::make_shared<MinimalParam>());
104112
rclcpp::shutdown();
105113
return 0;
106114
}
@@ -110,68 +118,103 @@ Inside the ``ros2_ws/src/cpp_parameters/src`` directory, create a new file calle
110118
The ``#include`` statements at the top are the package dependencies.
111119

112120
The next piece of code creates the class and the constructor.
113-
The first line of this constructor creates our parameter.
114-
Our parameter has the name ``my_parameter`` and is assigned the default value ``world``.
115-
Next, ``timer_`` is initialized, which causes the ``respond`` function to be executed once a second.
121+
The first line of this constructor creates a parameter with the name ``my_parameter`` and a default value of ``world``.
122+
The parameter type is inferred from the default value, so in this case it would be set to a string type.
123+
Next the ``timer_`` is initialized with a period of 1000ms, which causes the ``timer_callback`` function to be executed once a second.
116124

117125
.. code-block:: C++
118126

119-
class ParametersClass: public rclcpp::Node
127+
class MinimalParam : public rclcpp::Node
120128
{
121-
public:
122-
ParametersClass()
123-
: Node("parameter_node")
124-
{
125-
this->declare_parameter<std::string>("my_parameter", "world");
126-
timer_ = this->create_wall_timer(
127-
1000ms, std::bind(&ParametersClass::respond, this));
128-
}
129-
130-
The first line of our ``respond`` function gets the parameter ``my_parameter`` from the node, and stores it in ``parameter_string_``.
131-
The ``RCLCPP_INFO`` function ensures the message is logged.
129+
public:
130+
MinimalParam()
131+
: Node("minimal_param_node")
132+
{
133+
this->declare_parameter("my_parameter", "world");
134+
135+
timer_ = this->create_wall_timer(
136+
1000ms, std::bind(&MinimalParam::timer_callback, this));
137+
}
138+
139+
The first line of our ``timer_callback`` function gets the parameter ``my_parameter`` from the node, and stores it in ``my_param``.
140+
Next the ``RCLCPP_INFO`` function ensures the message is logged.
141+
The ``set_parameters`` function then sets the parameter ``my_parameter`` back to the default string value ``world``.
142+
In the case that the user changed the parameter externally, this ensures it is always reset back to the original.
132143

133144
.. code-block:: C++
134145

135-
void respond()
146+
void timer_callback()
136147
{
137-
this->get_parameter("my_parameter", parameter_string_);
138-
RCLCPP_INFO(this->get_logger(), "Hello %s", parameter_string_.c_str());
148+
std::string my_param =
149+
this->get_parameter("my_parameter").get_parameter_value().get<std::string>();
150+
151+
RCLCPP_INFO(this->get_logger(), "Hello %s!", my_param.c_str());
152+
153+
std::vector<rclcpp::Parameter> all_new_parameters{rclcpp::Parameter("my_parameter", "world")};
154+
this->set_parameters(all_new_parameters);
139155
}
140156

141-
Last is the declaration of ``timer_`` and ``parameter_string_``
157+
Last is the declaration of ``timer_``
142158

143159
.. code-block:: C++
144160

145161
private:
146-
std::string parameter_string_;
147162
rclcpp::TimerBase::SharedPtr timer_;
148163

149-
Following our ``ParametersClass`` is our ``main``.
150-
Here ROS 2 is initialized, and ``rclcpp::spin`` starts processing data from the node.
164+
Following our ``MinimalParam`` is our ``main``.
165+
Here ROS 2 is initialized, an instance of the ``MinimalParam`` class is constructed, and ``rclcpp::spin`` starts processing data from the node.
151166

152167
.. code-block:: C++
153168

154-
int main(int argc, char** argv)
169+
int main(int argc, char ** argv)
155170
{
156171
rclcpp::init(argc, argv);
157-
rclcpp::spin(std::make_shared<ParametersClass>());
172+
rclcpp::spin(std::make_shared<MinimalParam>());
158173
rclcpp::shutdown();
159174
return 0;
160175
}
161176

177+
2.1.1 (Optional) Add ParameterDescriptor
178+
""""""""""""""""""""""""""""""""""""""""
179+
Optionally, you can set a descriptor for the parameter.
180+
Descriptors allow you to specify a text description of the parameter and its constraints, like making it read-only, specifying a range, etc.
181+
For that to work, the code in the constructor has to be changed to:
182+
183+
.. code-block:: C++
184+
185+
// ...
186+
187+
class MinimalParam : public rclcpp::Node
188+
{
189+
public:
190+
MinimalParam()
191+
: Node("minimal_param_node")
192+
{
193+
auto param_desc = rcl_interfaces::msg::ParameterDescriptor{};
194+
param_desc.description = "This parameter is mine!";
195+
196+
this->declare_parameter("my_parameter", "world", param_desc);
197+
198+
timer_ = this->create_wall_timer(
199+
1000ms, std::bind(&MinimalParam::timer_callback, this));
200+
}
201+
202+
The rest of the code remains the same.
203+
Once you run the node, you can then run ``ros2 param describe /minimal_param_node my_parameter`` to see the type and description.
204+
162205

163206
2.2 Add executable
164207
~~~~~~~~~~~~~~~~~~
165208

166209
Now open the ``CMakeLists.txt`` file. Below the dependency ``find_package(rclcpp REQUIRED)`` add the following lines of code.
167210

168-
.. code-block:: console
211+
.. code-block:: cmake
169212
170-
add_executable(parameter_node src/cpp_parameters_node.cpp)
171-
ament_target_dependencies(parameter_node rclcpp)
213+
add_executable(minimal_param_node src/cpp_parameters_node.cpp)
214+
ament_target_dependencies(minimal_param_node rclcpp)
172215
173216
install(TARGETS
174-
parameter_node
217+
minimal_param_node
175218
DESTINATION lib/${PROJECT_NAME}
176219
)
177220
@@ -245,13 +288,13 @@ Now run the node:
245288

246289
.. code-block:: console
247290
248-
ros2 run cpp_parameters parameter_node
291+
ros2 run cpp_parameters minimal_param_node
249292
250293
The terminal should return the following message every second:
251294

252295
.. code-block:: console
253296
254-
[INFO] [parameter_node]: Hello world
297+
[INFO] [minimal_param_node]: Hello world!
255298
256299
Now you can see the default value of your parameter, but you want to be able to set it yourself.
257300
There are two ways to accomplish this.
@@ -265,7 +308,7 @@ Make sure the node is running:
265308

266309
.. code-block:: console
267310
268-
ros2 run cpp_parameters parameter_node
311+
ros2 run cpp_parameters minimal_param_node
269312
270313
Open another terminal, source the setup files from inside ``ros2_ws`` again, and enter the following line:
271314

@@ -278,10 +321,10 @@ To change it simply run the following line in the console:
278321

279322
.. code-block:: console
280323
281-
ros2 param set /parameter_node my_parameter earth
324+
ros2 param set /minimal_param_node my_parameter earth
282325
283326
You know it went well if you get the output ``Set parameter successful``.
284-
If you look at the other terminal, you should see the output change to ``[INFO] [parameter_node]: Hello earth``
327+
If you look at the other terminal, you should see the output change to ``[INFO] [minimal_param_node]: Hello earth!``
285328

286329
3.2 Change via a launch file
287330
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -299,8 +342,8 @@ In there, create a new file called ``cpp_parameters_launch.py``
299342
return LaunchDescription([
300343
Node(
301344
package="cpp_parameters",
302-
executable="parameter_node",
303-
name="custom_parameter_node",
345+
executable="minimal_param_node",
346+
name="custom_minimal_param_node",
304347
output="screen",
305348
emulate_tty=True,
306349
parameters=[
@@ -309,7 +352,7 @@ In there, create a new file called ``cpp_parameters_launch.py``
309352
)
310353
])
311354
312-
Here you can see that we set ``my_parameter`` to ``earth`` when we launch our node ``parameter_node``.
355+
Here you can see that we set ``my_parameter`` to ``earth`` when we launch our node ``minimal_param_node``.
313356
By adding the two lines below, we ensure our output is printed in our console.
314357

315358
.. code-block:: console
@@ -381,7 +424,7 @@ The terminal should return the following message every second:
381424

382425
.. code-block:: console
383426
384-
[parameter_node-1] [INFO] [custom_parameter_node]: Hello earth
427+
[INFO] [custom_minimal_param_node]: Hello earth!
385428
386429
Summary
387430
-------

0 commit comments

Comments
 (0)