• 10.ROS编程学习:参数管理机制c++实现


    目录

    一、参数管理机制

    二、参数增

    1.创建demo01_param_set.cpp

    2.通过roscpp下的ROS句柄,放入(“键”,“值”)

    3.通过roscpp下的param,放入(“键”,“值”)

    4.CMakeList.txt配置

    5.编译+rosrun运行 

    6.参数服务器参数查看

     三、参数改

    1.通过覆盖进行参数改

    2.参数服务器参数查看

     四、参数读

    1.第一种方式 param

    2.第二种方式 getParam

    3.第三种方式 getParamCached

    4.第四种方式gatParamNames

    5.第五种方式hasParam

    6.第6种方式searchParam

    五、参数删

    1.第一种方法 deleteParam

    2.第二种方法del

    参考:赵虚左的课程+古月的ROS机器人开发实践

    一、参数管理机制

    参数管理机制原理图

     其中通信机制不涉及TCP/UDP通信,用的是RPC,导致低性能,故参数最好是存储静态的非二进制的简单数据。

    实现目的:对参数服务器数据增删改查。

    二、参数增

    1.创建demo01_param_set.cpp

    1. #include "ros/ros.h"
    2. int main(int argc, char *argv[])
    3. {
    4. setlocale(LC_ALL,"");
    5. ros::init(argc,argv,"set_param_c");
    6. ros::NodeHandle n;
    7. n.setParam("zhonglei","zhonglei_neirong_1");
    8. n.setParam("banjing",0.15);
    9. ros::param::set("zhonglei_1","zhonglei_neirong_2");
    10. ros::param::set("banjing_1",0.18);
    11. ROS_INFO("参数服务器参数增加成功!");
    12. return 0;
    13. }
    setlocale(LC_ALL,"");

    防止中文乱码。

    1. ros::init(argc,argv,"set_param_c");
    2. ros::NodeHandle n;

    初始化节点,初始化句柄

    1. n.setParam("zhonglei","zhonglei_neirong_1");
    2. n.setParam("banjing",0.15);
    3. ros::param::set("zhonglei_1","zhonglei_neirong_2");
    4. ros::param::set("banjing_1",0.18);
    5. ROS_INFO("参数服务器参数增加成功!");

     两种增加参数方式:

    2.通过roscpp下的ROS句柄,放入(“键”,“值”)

    1. ros::NodeHandle n;
    2. n.setParam("zhonglei","zhonglei_neirong_1");
    3. n.setParam("banjing",0.15);

    3.通过roscpp下的param,放入(“键”,“值”)

    1. ros::param::set("zhonglei_1","zhonglei_neirong_2");
    2. ros::param::set("banjing_1",0.18);
        ROS_INFO("参数服务器参数增加成功!");

    控制台输出。

    4.CMakeList.txt配置

    1. add_executable(demo01_param_set src/demo01_param_set.cpp)
    2. target_link_libraries(demo01_param_set
    3. ${catkin_LIBRARIES}
    4. )

    5.编译+rosrun运行 

    6.参数服务器参数查看

    rosparam list
    1. /banjing
    2. /banjing_1
    3. /rosdistro
    4. /roslaunch/uris/host_rosmelodic_virtual_machine__34955
    5. /rosversion
    6. /run_id
    7. /zhonglei
    8. /zhonglei_1

    其中如下是系统自带的参数

    1. /rosdistro
    2. /roslaunch/uris/host_rosmelodic_virtual_machine__34955
    3. /rosversion
    4. /run_id

     增加部分,键的查看

    1. /banjing
    2. /banjing_1
    3. /zhonglei
    4. /zhonglei_1

    值的查看

    rosparam get /banjing

     三、参数改

    1.通过覆盖进行参数改

    1. n.setParam("banjing",0.15);
    2. n.setParam("banjing",0.33);
    3. ros::param::set("banjing_1",0.18);
    4. ros::param::set("banjing_1",0.30);

    键是之前存在的,利用覆盖来进行修改。键之前不存在,会增加一对键和值。

    2.参数服务器参数查看

    利用之前的方法

    rosparam list
    rosparam get /????

     四、参数读

    创建demo01_param_get.cpp

    1.第一种方式 param

    1. #include "ros/ros.h"
    2. int main(int argc, char *argv[])
    3. {
    4. setlocale(LC_ALL,"");
    5. ros::init(argc,argv,"get_param_c");
    6. ros::NodeHandle n;
    7. double jiaodu = n.param("banjing", 1.25);
    8. double jiaoduu = n.param("banjing_2",2.25);
    9. ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
    10. return 0;
    11. }

    主要操作

    1. ros::init(argc,argv,"get_param_c");
    2. ros::NodeHandle n;
    3. double jiaodu = n.param("banjing", 1.25);

    其中读取利用n.param,第一个参数为键名,第二个参数是没找到键名时给的默认值。

        double jiaoduu = n.param("banjing_2",2.25);

    故意找不到,看看是否输出默认值。

    CMakeList.txt配置

    1. add_executable(demo01_param_get src/demo01_param_get.cpp)
    2. target_link_libraries(demo01_param_get
    3. ${catkin_LIBRARIES}
    4. )

    编译+rosrun运行 

    其中banjing键输出了修改后的值,而banjing_2由于之前没增加,故读取默认值。

    2.第二种方式 getParam

    1. #include "ros/ros.h"
    2. int main(int argc, char *argv[])
    3. {
    4. setlocale(LC_ALL,"");
    5. ros::init(argc,argv,"get_param_c");
    6. ros::NodeHandle n;
    7. double jiaodu = n.param("banjing", 1.25);
    8. double jiaoduu = n.param("banjing_2",2.25);
    9. ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
    10. double jiaodu_1 = 0.0;
    11. bool result = n.getParam("banjing",jiaodu_1);
    12. if (result)
    13. {
    14. ROS_INFO("获取的参数为:%.2f",jiaodu_1);
    15. }
    16. else
    17. {
    18. ROS_INFO("被查询的变量不存在。");
    19. }
    20. double jiaodu_2 = 0.0;
    21. bool result1 = n.getParam("banjingg",jiaodu_2);
    22. if (result1)
    23. {
    24. ROS_INFO("获取的参数为:%.2f",jiaodu_2);
    25. }
    26. else
    27. {
    28. ROS_INFO("被查询的变量不存在。");
    29. }
    30. return 0;
    31. }

    关键部分

    1. double jiaodu_1 = 0.0;
    2. bool result = n.getParam("banjing",jiaodu_1);
    3. if (result)
    4. {
    5. ROS_INFO("获取的参数为:%.2f",jiaodu_1);
    6. }
    7. else
    8. {
    9. ROS_INFO("被查询的变量不存在。");
    10. }

    getParam函数,参数为要查询的键名和值的赋值对象。返回值是布尔类型,判断是否查询成功。

    同时也测试了没找到键名的情况。

    编译+rosrun运行 

    3.第三种方式 getParamCached

     和getParamCached用法一样,但是性能提升了。

    1. #include "ros/ros.h"
    2. int main(int argc, char *argv[])
    3. {
    4. setlocale(LC_ALL,"");
    5. ros::init(argc,argv,"get_param_c");
    6. ros::NodeHandle n;
    7. double jiaodu = n.param("banjing", 1.25);
    8. double jiaoduu = n.param("banjing_2",2.25);
    9. ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
    10. double jiaodu_1 = 0.0;
    11. bool result = n.getParamCached("banjing",jiaodu_1);
    12. if (result)
    13. {
    14. ROS_INFO("获取的参数为:%.2f",jiaodu_1);
    15. }
    16. else
    17. {
    18. ROS_INFO("被查询的变量不存在。");
    19. }
    20. double jiaodu_2 = 0.0;
    21. bool result1 = n.getParamCached("banjingg",jiaodu_2);
    22. if (result1)
    23. {
    24. ROS_INFO("获取的参数为:%.2f",jiaodu_2);
    25. }
    26. else
    27. {
    28. ROS_INFO("被查询的变量不存在。");
    29. }
    30. return 0;
    31. }

    编译+rosrun运行 

    4.第四种方式gatParamNames

    1. #include "ros/ros.h"
    2. int main(int argc, char *argv[])
    3. {
    4. setlocale(LC_ALL,"");
    5. ros::init(argc,argv,"get_param_c");
    6. ros::NodeHandle n;
    7. double jiaodu = n.param("banjing", 1.25);
    8. double jiaoduu = n.param("banjing_2",2.25);
    9. ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
    10. double jiaodu_1 = 0.0;
    11. bool result = n.getParamCached("banjing",jiaodu_1);
    12. if (result)
    13. {
    14. ROS_INFO("获取的参数为:%.2f",jiaodu_1);
    15. }
    16. else
    17. {
    18. ROS_INFO("被查询的变量不存在。");
    19. }
    20. double jiaodu_2 = 0.0;
    21. bool result1 = n.getParamCached("banjingg",jiaodu_2);
    22. if (result1)
    23. {
    24. ROS_INFO("获取的参数为:%.2f",jiaodu_2);
    25. }
    26. else
    27. {
    28. ROS_INFO("被查询的变量不存在。");
    29. }
    30. std::vector names;
    31. n.getParamNames(names);
    32. for (auto &&name : names)
    33. {
    34. ROS_INFO("遍历到的元素:%s",name.c_str());
    35. }
    36. return 0;
    37. }

    关键部分 

    1. std::vector names;
    2. n.getParamNames(names);
    3. for (auto &&name : names)
    4. {
    5. ROS_INFO("遍历到的元素:%s",name.c_str());
    6. }

     通过gatParamNames读取所有的键名,并保存在names中。

    编译+rosrun运行 

    5.第五种方式hasParam

    1. #include "ros/ros.h"
    2. int main(int argc, char *argv[])
    3. {
    4. setlocale(LC_ALL,"");
    5. ros::init(argc,argv,"get_param_c");
    6. ros::NodeHandle n;
    7. double jiaodu = n.param("banjing", 1.25);
    8. double jiaoduu = n.param("banjing_2",2.25);
    9. ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
    10. double jiaodu_1 = 0.0;
    11. bool result = n.getParamCached("banjing",jiaodu_1);
    12. if (result)
    13. {
    14. ROS_INFO("获取的参数为:%.2f",jiaodu_1);
    15. }
    16. else
    17. {
    18. ROS_INFO("被查询的变量不存在。");
    19. }
    20. double jiaodu_2 = 0.0;
    21. bool result1 = n.getParamCached("banjingg",jiaodu_2);
    22. if (result1)
    23. {
    24. ROS_INFO("获取的参数为:%.2f",jiaodu_2);
    25. }
    26. else
    27. {
    28. ROS_INFO("被查询的变量不存在。");
    29. }
    30. std::vector names;
    31. n.getParamNames(names);
    32. for (auto &&name : names)
    33. {
    34. ROS_INFO("遍历到的元素:%s",name.c_str());
    35. }
    36. bool cunzai1 = n.hasParam("banjing");
    37. bool cunzai2 = n.hasParam("banjingg");
    38. ROS_INFO("banjing存在?%d,banjingg存在?%d",cunzai1,cunzai2);
    39. return 0;
    40. }

    关键部分

    1. bool cunzai1 = n.hasParam("banjing");
    2. bool cunzai2 = n.hasParam("banjingg");
    3. ROS_INFO("banjing存在?%d,banjingg存在?%d",cunzai1,cunzai2);
    4. return 0;

    查找键名,并返回布尔值,判断键的存在。

    编译+rosrun运行 

    6.第6种方式searchParam

    1. #include "ros/ros.h"
    2. int main(int argc, char *argv[])
    3. {
    4. setlocale(LC_ALL,"");
    5. ros::init(argc,argv,"get_param_c");
    6. ros::NodeHandle n;
    7. double jiaodu = n.param("banjing", 1.25);
    8. double jiaoduu = n.param("banjing_2",2.25);
    9. ROS_INFO("参数服务器参数读取成功!,成功读取的banjing = %.2f,由于键输入错误或者不存在时,输出默认值:banjing_2 = %.2f",jiaodu,jiaoduu);
    10. double jiaodu_1 = 0.0;
    11. bool result = n.getParamCached("banjing",jiaodu_1);
    12. if (result)
    13. {
    14. ROS_INFO("获取的参数为:%.2f",jiaodu_1);
    15. }
    16. else
    17. {
    18. ROS_INFO("被查询的变量不存在。");
    19. }
    20. double jiaodu_2 = 0.0;
    21. bool result1 = n.getParamCached("banjingg",jiaodu_2);
    22. if (result1)
    23. {
    24. ROS_INFO("获取的参数为:%.2f",jiaodu_2);
    25. }
    26. else
    27. {
    28. ROS_INFO("被查询的变量不存在。");
    29. }
    30. std::vector names;
    31. n.getParamNames(names);
    32. for (auto &&name : names)
    33. {
    34. ROS_INFO("遍历到的元素:%s",name.c_str());
    35. }
    36. bool cunzai1 = n.hasParam("banjing");
    37. bool cunzai2 = n.hasParam("banjingg");
    38. ROS_INFO("banjing存在?%d,banjingg存在?%d",cunzai1,cunzai2);
    39. std::string key;
    40. n.searchParam("banjing",key);
    41. ROS_INFO("搜索结果:%s",key.c_str());
    42. return 0;
    43. }

    关键部分

    1. std::string key;
    2. n.searchParam("banjing",key);
    3. ROS_INFO("搜索结果:%s",key.c_str());
    4. return 0;

     编译+rosrun运行 

     7.第7种方式 ros::param::xxxxx

    根据代码提示与句柄的方式一一对应,而且这种方式与句柄的方式使用方法相同。

    五、参数删

    把刚刚创建的没意义的键与值删除掉

    rosparam list

     用两种方式删除掉

    1. /banjing
    2. /banjing_1
    3. /zhonglei
    4. /zhonglei_1

    1.第一种方法 deleteParam

    1. #include "ros/ros.h"
    2. int main(int argc, char *argv[])
    3. {
    4. setlocale(LC_ALL,"");
    5. ros::init(argc,argv,"del_param_c");
    6. ros::NodeHandle n;
    7. bool flag1 = n.deleteParam("banjing");
    8. if(flag1)
    9. {
    10. ROS_INFO("删除成功");
    11. }
    12. else
    13. {
    14. ROS_INFO("删除失败");
    15. }
    16. return 0;
    17. }

    关键部分

    1. ros::NodeHandle n;
    2. bool flag1 = n.deleteParam("banjing");

    句柄的方式,调用deleteParam函数,其中参数为键名,返回值为是否删除成功的布尔值。

    CMakeList.txt配置

    1. add_executable(demo01_param_del src/demo01_param_del.cpp)
    2. target_link_libraries(demo01_param_del
    3. ${catkin_LIBRARIES}
    4. )

    编译+rosrun运行 

     看看是否删除成功

    rosparam list

    2.第二种方法del

    1. #include "ros/ros.h"
    2. int main(int argc, char *argv[])
    3. {
    4. setlocale(LC_ALL,"");
    5. ros::init(argc,argv,"del_param_c");
    6. ros::NodeHandle n;
    7. bool flag1 = n.deleteParam("banjing");
    8. if(flag1)
    9. {
    10. ROS_INFO("删除成功");
    11. }
    12. else
    13. {
    14. ROS_INFO("删除失败");
    15. }
    16. bool flag2 = ros::param::del("banjing_1");
    17. if(flag2)
    18. {
    19. ROS_INFO("第二种方法删除成功");
    20. }
    21. else
    22. {
    23. ROS_INFO("第二种方法删除失败");
    24. }
    25. return 0;
    26. }

    此程序在上一个程序上修改,而且在上一个程序运行后运行,由上一个程序结果可知banjing节点已经删除了,故再次删除就会由于找不到键,而导致删除失败。

    关键部分

    bool flag2 = ros::param::del("banjing_1");

    参数为键名,返回值为是否删除成功的布尔值。

    编译+rosrun运行

    结果符合预期。

    下一步把剩下两个键也给删掉,使ros的参数服务器参数回到初始状态。

    1. #include "ros/ros.h"
    2. int main(int argc, char *argv[])
    3. {
    4. setlocale(LC_ALL,"");
    5. ros::init(argc,argv,"del_param_c");
    6. ros::NodeHandle n;
    7. bool flag1 = n.deleteParam("zhonglei");
    8. if(flag1)
    9. {
    10. ROS_INFO("删除成功");
    11. }
    12. else
    13. {
    14. ROS_INFO("删除失败");
    15. }
    16. bool flag2 = ros::param::del("zhonglei_1");
    17. if(flag2)
    18. {
    19. ROS_INFO("第二种方法删除成功");
    20. }
    21. else
    22. {
    23. ROS_INFO("第二种方法删除失败");
    24. }
    25. return 0;
    26. }

  • 相关阅读:
    【牛客刷题日记】— Javascript 通关秘籍(2)
    云原生 - 轻量应用服务器 & 云服务器的区别
    【云原生之kubernetes实战】在kubernetes集群下部署Rainbond平台
    GIT 实用命令速记
    猿创征文 |【C++】面向对象之微观部分——类的组成(中)
    mysql详解之redolog的关键——幂等性
    小米K8s运维-云原生方向(面经分享)
    Vue3 快速入门及巩固基础
    Cesium:实现卷帘效果
    数据加密技术在数据安全中的作用
  • 原文地址:https://blog.csdn.net/wzfafabga/article/details/127413670