ROS2——参数的使用
上回说到, Organization
给每个人免费送2个汉堡, 有一天Organization
正在营业中, 汉堡突然供不应求了, 领导决定临时改变规则, 之后的每个人只能领取一个汉堡. 但是此时节点已经在运行中, 该如何改变这个值呢? 这就需要用到参数parameters
参数简介
参数是节点的配置参数值。你可以认为参数是节点配置的一部分。参数为整数,浮点数,布尔值,字符串和列表。在ROS2中,每个节点都有自己的参数。所有参数都是可动态重新配置的,并且是基于ROS2服务构建的。
在这个案例中, 每个人领取的汉堡数量就可以是Organization
节点的一个参数.
下面, 我们将修改这段服务程序, 通过修改参数来改变人均汉堡数
修改服务程序
新建Organization_with_parameter.cpp
文件
代码由Organization.cpp
修改而来, 不同的地方均使用// CHANGE:
标注出了, 请读者自行与上节代码进行对比.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| #include "rclcpp/rclcpp.hpp" #include "service_interfaces/srv/calculate.hpp"
using std::placeholders::_1; using std::placeholders::_2;
class Organization : public rclcpp::Node {
public: Organization() : Node("Organization"), NumOfAll(100) { RCLCPP_INFO(this->get_logger(), "大家好, 我们是热心组织, 我们只给poorer发汉堡."); callback_group_organization = this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive); Organization_Server = this->create_service<service_interfaces::srv::Calculate>("Calculate", std::bind(&Organization::organization_callback,this,_1,_2), rmw_qos_profile_services_default, callback_group_organization); this->declare_parameter<int>("NumOfEachPerson", NumOfEachPerson); }
private: size_t NumOfAll;
int NumOfEachPerson = 2;
rclcpp::CallbackGroup::SharedPtr callback_group_organization; rclcpp::Service<service_interfaces::srv::Calculate>::SharedPtr Organization_Server;
void organization_callback(const service_interfaces::srv::Calculate::Request::SharedPtr request, const service_interfaces::srv::Calculate::Response::SharedPtr response) { if(request->status == "Poorer") { RCLCPP_INFO(this->get_logger(), "收到一个来自%s的请求,他家有%d个人.", request->status.c_str(), request->num_of_people); this->get_parameter("NumOfEachPerson", NumOfEachPerson); unsigned int NumOfRequired = request->num_of_people * NumOfEachPerson;
if(NumOfRequired > NumOfAll) { RCLCPP_INFO(this->get_logger(), "当前汉堡库里只剩%d个汉堡啦! 已经不够分了, 请明日再来.", NumOfRequired); response->success = false; } else { NumOfAll -= NumOfRequired; response->num_of_hamburger = NumOfRequired; response->success = true; RCLCPP_INFO(this->get_logger(), "成功送出%d个汉堡~ 还剩余%d个汉堡", NumOfRequired, NumOfAll); } } else { response->success = false; response->num_of_hamburger = 0; RCLCPP_INFO(this->get_logger(), "收到一个非法请求,这人是个%s, 不满足送汉堡资格.", request->status.c_str()); } } };
int main(int argc, char **argv) { rclcpp::init(argc, argv); auto node = std::make_shared<Organization>(); rclcpp::executors::MultiThreadedExecutor exector; exector.add_node(node); exector.spin(); rclcpp::shutdown(); return 0; }
|
Cmakelist.txt
添加:
1 2
| add_executable(Organization_with_parameters_node src/Organization_with_parameters.cpp) ament_target_dependencies(Organization_with_parameters_node rclcpp service_interfaces)
|
添加:Organization_with_parameters_node
1 2 3 4 5
| install(TARGETS ... Organization_with_parameters_node DESTINATION lib/${PROJECT_NAME} )
|
package.xml
不用修改
编译
--packages-select
指定编译customer_and_kfc
功能包
1
| colcon build --packages-select poor_and_organization
|
刷新环境
运行
新建一个终端窗口, 运行带参数的Organization服务端节点
1
| ros2 run poor_and_organization Organization_with_parameters_node
|
再另新建一个终端, 运行Poor客户端节点
一开始每人领取两个汉堡, 直接运行客户端:
1
| ros2 run poor_and_organization Poor_node Poorer 5
|
Organization服务端: 成功发出10个汉堡

Poor客户端: 成功领取10个汉堡

此时需要修改参数, 另起一个终端, 运行:
1
| ros2 param set /Organization NumOfEachPerson 1
|
提示如下即为成功

再次运行客户端
1
| ros2 run poor_and_organization Poor_node Poorer 50
|
Poor客户端: 50个人领取了50个汉堡

Organization服务端: 成功发出50个汉堡

由此可见, 参数成功被修改了, 但此时的参数不会被保留, 参数所在的节点重启后即恢复至初始值. 那如果一个节点的参数特别多, 修改完之后想将当前的参数保存下来供下次调用应该怎么操作呢? 请继续阅读.
参数常用命令
使用 ros2 param
查看参数列表

也可具体到某个节点
1
| ros2 param list /Organization
|
查看参数描述
1
| ros2 param describe /Organization NumOfEachPerson
|

获取参数值
ros2 param get <node_name> <parameter_name>
1
| ros2 param get /Organization NumOfEachPerson
|

设置参数值
ros2 param set <node_name> <parameter_name> <value>
1
| ros2 param set /Organization NumOfEachPerson 1
|
再次获取参数值, 发生了改变:

保存参数
ros2 param dump <node_name>
1
| ros2 param dump /Organization
|
在当前终端的根目录下, 可以看到增加了一个Organization.yaml
文件, 打开此文件
1 2 3 4
| /Organization: ros__parameters: NumOfEachPerson: 1 use_sim_time: false
|
有了这个参数文件, 就可以通过这个文件设置节点的参数
加载参数
节点启动后加载参数
ros2 param load <node_name> <parameter_file>
1
| ros2 param load /Organization ./Organization.yaml
|
返回如下表示加载成功:

节点启动前加载参数
ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>
1
| ros2 run poor_and_organization Organization_with_parameters_node --ros-args --params-file ./Organization.yaml
|
请读者尝试自行获取一下当前的NumOfEachPerson
值作为练习.