ROS2——参数的使用

ROS2——参数的使用

上回说到, Organization给每个人免费送2个汉堡, 有一天Organization正在营业中, 汉堡突然供不应求了, 领导决定临时改变规则, 之后的每个人只能领取一个汉堡. 但是此时节点已经在运行中, 该如何改变这个值呢? 这就需要用到参数parameters

参数简介

参数是节点的配置参数值。你可以认为参数是节点配置的一部分。参数为整数,浮点数,布尔值,字符串和列表。在ROS2中,每个节点都有自己的参数。所有参数都是可动态重新配置的,并且是基于ROS2服务构建的。

在这个案例中, 每个人领取的汉堡数量就可以是Organization节点的一个参数.

下面, 我们将修改这段服务程序, 通过修改参数来改变人均汉堡数

修改服务程序

新建Organization_with_parameter.cpp文件

代码由Organization.cpp修改而来, 不同的地方均使用// CHANGE:标注出了, 请读者自行与上节代码进行对比.

#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);
        
        // CHANGE: 声明参数
        this->declare_parameter<int>("NumOfEachPerson", NumOfEachPerson);
    }

private:
    size_t NumOfAll;

    // CHANGE: 声明每个人分得的汉堡数, 默认为2
    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);
            
            // CHANGE: 更新参数
            this->get_parameter("NumOfEachPerson", NumOfEachPerson);
            
            // CHANGE: 计算应给汉堡数量,由参数给定
            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

添加:

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

install(TARGETS
  ...
  Organization_with_parameters_node
  DESTINATION lib/${PROJECT_NAME}
)

package.xml

不用修改

编译

--packages-select指定编译customer_and_kfc功能包

colcon build --packages-select poor_and_organization

刷新环境

source ~/.bashrc

运行

新建一个终端窗口, 运行带参数的Organization服务端节点

ros2 run poor_and_organization Organization_with_parameters_node

再另新建一个终端, 运行Poor客户端节点

一开始每人领取两个汉堡, 直接运行客户端:

ros2 run poor_and_organization Poor_node Poorer 5

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

Parameters-Organization1

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

Parameters-change-Poor1

此时需要修改参数, 另起一个终端, 运行:

ros2 param set /Organization NumOfEachPerson 1

提示如下即为成功

Parameters-change

再次运行客户端

ros2 run poor_and_organization Poor_node Poorer 50

Poor客户端: 50个人领取了50个汉堡

Parameters-change-Poor2

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

Parameters-Organization2

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

参数常用命令

使用 ros2 param

查看参数列表

ros2 param list
Parameters-ros2-param-list

也可具体到某个节点

ros2 param list /Organization

查看参数描述

ros2 param describe /Organization NumOfEachPerson
Parameters-ros2-param-describe-Organization-NumOfEachPerson

获取参数值

ros2 param get <node_name> <parameter_name>

ros2 param get /Organization NumOfEachPerson
Parameters-ros2-param-get-Organization-NumOfEachPerson-2

设置参数值

ros2 param set <node_name> <parameter_name> <value>

ros2 param set /Organization NumOfEachPerson 1

再次获取参数值, 发生了改变:

Parameters-ros2-param-get-Organization-NumOfEachPerson-1

保存参数

ros2 param dump <node_name>

ros2 param dump /Organization

在当前终端的根目录下, 可以看到增加了一个Organization.yaml文件, 打开此文件

/Organization:
  ros__parameters:
    NumOfEachPerson: 1
    use_sim_time: false

有了这个参数文件, 就可以通过这个文件设置节点的参数

加载参数

节点启动后加载参数

ros2 param load <node_name> <parameter_file>

ros2 param load /Organization ./Organization.yaml

返回如下表示加载成功:

Parameters-ros2-param-load-Organization-Organization-yaml
节点启动前加载参数

ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>

ros2 run poor_and_organization Organization_with_parameters_node --ros-args --params-file ./Organization.yaml 

请读者尝试自行获取一下当前的NumOfEachPerson值作为练习.

更多教程欢迎进入我的博客学习~

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

范子琦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值