参数服务器

本文介绍ROS中的参数服务器,包括其作用、应用场景及如何通过C++实现参数的增删改查等操作。

前言

参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器,可以将数据存储在该容器中,被不同的节点调用,当然不同的节点也可以往其中存储数据,关于参数服务器的典型应用场景如下:

导航实现时,会进行路径规划,比如: 全局路径规划,设计一个从出发点到目标点的大致路径。本地路径规划,会根据当前路况生成时时的行进路径

上述场景中,全局路径规划和本地路径规划时,就会使用到参数服务器:

  • 路径规划时,需要参考小车的尺寸,我们可以将这些尺寸信息存储到参数服务器,全局路径规划节点与本地路径规划节点都可以从参数服务器中调用这些参数

参数服务器,一般适用于存在数据共享的一些应用场景

概念

以共享的方式实现不同节点之间数据交互的通信模式。

作用

存储一些多节点共享的数据,类似于全局变量

案例

实现参数增删改查操作

参数服务器理论模型

参数服务器实现是最为简单的,该模型如下图所示,该模型中涉及到三个角色:

  • ROS Master (管理者)
  • Talker (参数设置者)
  • Listener (参数调用者)

ROS Master 作为一个公共容器保存参数,Talker 可以向容器中设置参数,Listener 可以获取参数。

 整个流程由以下步骤实现:

1.Talker 设置参数

Talker 通过 RPC 向参数服务器发送参数(包括参数名与参数值),ROS Master 将参数保存到参数列表中。

2.Listener 获取参数

Listener 通过 RPC 向参数服务器发送参数查找请求,请求中包含要查找的参数名

3.ROS Master 向 Listener 发送参数值

ROS Master 根据步骤2请求提供的参数名查找参数值,并将查询结果通过 RPC 发送给 Listener

参数可使用数据类型:

  • 32-bit integers

  • booleans

  • strings

  • doubles

  • iso8601 dates

  • lists

  • base64-encoded binary data

  • 字典

注意:参数服务器不是为高性能而设计的,因此最好用于存储静态的非二进制的简单数据

参数操作A(C++)

需求:实现参数服务器参数的增删改查操作

在 C++ 中实现参数服务器数据的增删改查,可以通过两套 API 实现:

  • ros::NodeHandle

  • ros::param

下面为具体操作演示

1.参数服务器新增(修改)参数

#include "ros/ros.h"
 
/*
        需要实现参数的新增与修改:
        需求:首先设置机器人的共享参数,类型,半径(0.15m)   
                  再修改半径(0.2m)
        实现:
                 ros::NodeHandle
                      setParam("键",值)
                 ros::param
                      set("键",值)
        修改:只需要继续调研setParam或set函数,保证键是已经存在的,那么值会覆盖
*/

int main(int argc, char *argv[])
{
      //初始化ROS节点
      ros::init(argc,argv,"set_param_c");
      //创建ROS节点句柄
      ros::NodeHandle nh;
      //参数增
      //方案1:nh
      nh.setParam("type","xiaoHuang");
      nh.setParam("radius",0.15);
      //方案2:ros::param
      ros::param::set("type_param","xiaoBai");
      ros::param::set("radius_param",0.15);
      //参数改
      //方案1:nh
      nh.setParam("radius",0.2);
      //方案2:ros::param
      ros::param::set("radius_param",0.25);
      return 0;
}

2.参数服务器获取参数

#include "ros/ros.h"

/*
       演示参数查询
       实现:
              ros::NodeHandle --------------------------------------------
                    param(键,默认值) 
                        存在,返回对应结果,否则返回默认值

                    getParam(键,存储结果的变量)
                         存在,返回 true,且将值赋值给参数2
                         若果键不存在,那么返回值为 false,且不为参数2赋值

                    getParamCached键,存储结果的变量)--提高变量获取效率
                         存在,返回 true,且将值赋值给参数2
                         如果键不存在,那么返回值为 false,且不为参数2赋值

                    getParamNames(std::vector<std::string>)
                         获取所有的键,并存储在参数 vector 中 

                    hasParam(键)
                         是否包含某个键,存在返回 true,否则返回 false

                    searchParam(参数1,参数2)
                         搜索键,参数1是被搜索的键,参数2存储搜索结果的变量

              ros::param --------------------------------------------------
*/
int main(int argc, char *argv[])
{
      //设置编码
      setlocale(LC_ALL,"");
      //初始化ROS节点
      ros::init(argc,argv,"get_param_c");
      //创建节点句柄
      ros::NodeHandle nh;
      //ros::NodeHandle --------------------------------------------
      //1.param
      double radius = nh.param("radius",0.5);
      ROS_INFO("radius = %.2f",radius);
      //2.getParam
      double radius2 = 0.0;
      //bool result = nh.getParam("radius",radius2);
      //3.getParamCached 与 getParam类似,只是性能上有提升,一般测试下,看不出来
      bool result = nh.getParamCached("radius",radius2);
      if(result)
      {
           ROS_INFO("获取的半径是:%.2f",radius2);
      }
      else
      {
           ROS_INFO("被查询的变量不存在");
      }
       
      //4.getParamNames
      std::vector<std::string> names;
      nh.getParamNames(names);
      for(auto &&name : names)
      {
      ROS_INFO("遍历的元素:%s",name.c_str());
      }

      //5.hasParam
      bool flag1 = nh.hasParam("radius");
      bool flag2 = nh.hasParam("radiusxxx");
      ROS_INFO("radius 存在吗? %d",flag1);
      ROS_INFO("radiusxxx 存在吗? %d",flag2);

      //6.serchParam
      std::string key;
      nh.searchParam("radiusxxx",key);
      ROS_INFO("搜索结果:%s",key.c_str());

      //ros::param ------------------------------------------------------------
      double radius_param = ros::param::param("radiusxxx",100.5);
      ROS_INFO("radius_param = %.2f",radius_param);
      
      std::vector<std::string>names_param;
      ros::param::getParamNames(names_param);
      for(auto &&name : names_param)
      {
           ROS_INFO("键:%s",name.c_str());
      }

      return 0;
}

3.参数服务器删除参数

#include "ros/ros.h"
/*
      演示参数删除:
      实现:
             ros::NodeHandle
                    deleteParam()
             ros::param
                    del()
*/
 int main(int argc, char *argv[])
{
      setlocale(LC_ALL,"");
      ros::init(argc,argv,"param_del_c");
      ros::NodeHandle nh;
      //删除:NodeHandle-------------------------------
      bool flag1 = nh.deleteParam("radius");
      if(flag1)
      {
      ROS_INFO("删除成功!");
      }
      else{
      ROS_INFO("删除失败!");
      }
  
      //删除:ros::param-------------------------------
      
      bool flag2 = nh.deleteParam("radius_param");
      if(flag2)
      {
      ROS_INFO("radius_param 删除成功!");
      }
      else{
      ROS_INFO("radius_param 删除失败!");
      }    
  
      return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值