• ROS三种通信方式之参数通信


    一、参数服务器的理论模型

    参数服务器的理论模型是最简单的,其实就是Master作为一个公共容器可以保存参数,Talker可以向Master中设置参数,Listener可以获取参数。

    参数可使用数据类型:

    - 32-bit integers
    - booleans
    - strings
    - doubles
    - iso8601 dates
    - lists
    - base64-encoded binary data
    - 字典
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里需要注意,参数服务器并不是为了高性能诞生的,所以不要存储二进制大数据,如图片等。

    二、参数服务器的实现C++

    2.1、新增/修改参数

    #include "ros/ros.h"
    
    int main(int argc, char *argv[]) {
        setlocale(LC_ALL,"");
    
        ros::init(argc,argv,"Set_Param_test");
    
        // 创建列表容器
        std::vector<std::string> stus;
        stus.push_back("zhangsan");
        stus.push_back("李四");
        stus.push_back("王五");
        stus.push_back("孙大脑袋");
    
        // 创建字典
        std::map<std::string,std::string> friends;
        friends["guo"] = "huang";
        friends["yuang"] = "xiao";
    
        /*第一种设置参数方式*/
        ros::NodeHandle nh;
        nh.setParam("nh_int",10); //整型
        nh.setParam("nh_double",3.14); //浮点型
        nh.setParam("nh_bool",true); //bool
        nh.setParam("nh_string","hello NodeHandle"); //字符串
        nh.setParam("nh_vector",stus); // vector
        nh.setParam("nh_map",friends); // map
    
        //修改演示(相同的键,不同的值)
        nh.setParam("nh_int",10000);
    
        /*第二种设置参数方式*/
        ros::param::set("param_int",20);
        ros::param::set("param_double",3.14);
        ros::param::set("param_string","Hello Param");
        ros::param::set("param_bool",false);
        ros::param::set("param_vector",stus);
        ros::param::set("param_map",friends);
    
        //修改演示(相同的键,不同的值)
        ros::param::set("param_int",20000);
    
        return 0;
    }
    
    • 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

    2.2、获取参数

    #include "ros/ros.h"\
    #include "String.h"
    
    int main(int argc, char *argv[]) {
        setlocale(LC_ALL,"");
    
        ros::init(argc,argv,"Get_Param_test");
    
        // 在ROS中提供了两套API来完成参数操作
    
        //     ros::NodeHandle
    
        //     param(键,默认值) 
        //         存在,返回对应结果,否则返回默认值
    
        //     getParam(键,存储结果的变量)
        //         存在,返回 true,且将值赋值给参数2
        //         若果键不存在,那么返回值为 false,且不为参数2赋值
    
        //     getParamCached键,存储结果的变量)--提高变量获取效率
        //         存在,返回 true,且将值赋值给参数2
        //         若果键不存在,那么返回值为 false,且不为参数2赋值
    
        //     getParamNames(std::vector)
        //         获取所有的键,并存储在参数 vector 中 
    
        //     hasParam(键)
        //         是否包含某个键,存在返回 true,否则返回 false
    
        //     searchParam(参数1,参数2)
        //         搜索键,参数1是被搜索的键,参数2存储搜索结果的变量
    
        // ros::param ----- 与 NodeHandle 类似
    
        ros::NodeHandle nh;
        // param 函数
        int res1 = nh.param("nh_int",100); // 键存在
        int res2 = nh.param("nh_int2",100); // 键不存在
        ROS_INFO("param获取结果:%d,%d",res1,res2);
    
        // getParam 函数
        int nh_int_value;
        double nh_double_value;
        bool nh_bool_value;
        std::string nh_string_value;
        std::vector<std::string> stus;
        std::map<std::string, std::string> friends;
    
        nh.getParam("nh_int",nh_int_value);
        nh.getParam("nh_double",nh_double_value);
        nh.getParam("nh_bool",nh_bool_value);
        nh.getParam("nh_string",nh_string_value);
        nh.getParam("nh_vector",stus);
        nh.getParam("nh_map",friends);
    
        ROS_INFO("getParam获取的结果:%d,%.2f,%s,%d",
                nh_int_value,
                nh_double_value,
                nh_string_value.c_str(),
                nh_bool_value
                );
        for (auto &&stu : stus) {
            ROS_INFO("stus 元素:%s",stu.c_str());        
        }
    
        for (auto &&f : friends) {
            ROS_INFO("map 元素:%s = %s",f.first.c_str(), f.second.c_str());
        }
    
        // getParamCached()
        nh.getParamCached("nh_int",nh_int_value);
        ROS_INFO("通过缓存获取数据:%d",nh_int_value);
    
        //getParamNames()
        std::vector<std::string> param_names1;
        nh.getParamNames(param_names1);
        for (auto &&name : param_names1) {
            ROS_INFO("名称解析name = %s",name.c_str());        
        }
    
        ROS_INFO("----------------------------");
        ROS_INFO("存在 nh_int 吗? %d",nh.hasParam("nh_int"));
        ROS_INFO("存在 nh_intttt 吗? %d",nh.hasParam("nh_intttt"));
    
        std::string key;
        nh.searchParam("nh_int",key);
        ROS_INFO("搜索键:%s",key.c_str());
    }
    
    • 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
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    2.3、删除参数

    #include "ros/ros.h"
    
    int main(int argc, char *argv[]) {   
        setlocale(LC_ALL,"");
        ros::init(argc,argv,"delete_param");
    
        ros::NodeHandle nh;
        bool r1 = nh.deleteParam("nh_int");
        ROS_INFO("nh 删除结果:%d",r1);
    
        bool r2 = ros::param::del("param_int");
        ROS_INFO("param 删除结果:%d",r2);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    三、常用命令rosparam

    rosparam包含rosparam命令行工具,用于使用YAML编码文件在参数服务器上获取和设置ROS参数。

    rosparam set      设置参数
    rosparam get      获取参数
    rosparam load     从外部文件加载参数
    rosparam dump     将参数写出到外部文件
    rosparam delete   删除参数
    rosparam list     列出所有参数
    
    rosnode ping      测试到节点的连接状态
    rosnode list      列出活动节点
    rosnode info      打印节点信息
    rosnode machine   列出指定设备上节点
    rosnode kill      杀死某个节点
    rosnode cleanup   清除不可连接的节点
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.1、rosparam set

    设置参数

    rosparam set name huluwa
    
    • 1

    3.2、rosparam get

    获取参数

    rosparam get name
    
    • 1

    3.3、rosparam delete

    删除参数

    rosparam delete name
    
    • 1

    3.4、rosparam load

    从外部文件加载参数(先准备 yaml 文件)

    rosparam load xxx.yaml
    
    • 1

    3.5、rosparam dump

    将参数写出到外部文件

    rosparam dump yyy.yaml
    
    • 1

    四、小乌龟实操

    获取参数列表:

    rosparam list
    
    • 1

    响应结果:

    /turtlesim/background_b
    /turtlesim/background_g
    /turtlesim/background_r
    
    • 1
    • 2
    • 3

    C++

    #include "ros/ros.h"
    
    
    int main(int argc, char *argv[])
    {
        ros::init(argc,argv,"haha");
    
        ros::NodeHandle nh("turtlesim");
        //ros::NodeHandle nh;
    
        // ros::param::set("/turtlesim/background_r",0);
        // ros::param::set("/turtlesim/background_g",0);
        // ros::param::set("/turtlesim/background_b",0);
    
        nh.setParam("background_r",0);
        nh.setParam("background_g",0);
        nh.setParam("background_b",0);
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    2023 ICPC 网络赛 第二场 部分题解 (待完善)
    如何用jxTMS开发一个功能(三)
    Hackthebox系列 Starting point Tier0 Meow记录
    用Python操作PPT的办公自动化教程
    SAP顾问英语自学的免费且有效的方法汇总!--一文搞定英语学习
    UE4在蓝图中使用自己定义的对象蓝图
    《C++ Primer》第3章 字符串、向量和数组(三)
    实现一个todoList可直接操作数据(上移、下移、置顶、置底)
    JUnit单元测试
    钟汉良日记:你相信神话吗?你会背《正气歌》吗
  • 原文地址:https://blog.csdn.net/weixin_43903639/article/details/126258081