Bootstrap

(五)ROS通信编程——参数服务器

前言

参数服务器在ROS中主要用于实现不同节点之间的数据共享(P2P)。参数服务器相当于是独立于所有节点的一个公共容器,可以将数据存储在该容器中,被不同的节点调用,当然不同的节点也可以往其中存储数据,关于参数服务器的典型应用场景如下:导航实现时,会进行路径规划,比如: 全局路径规划,设计一个从出发点到目标点的大致路径。本地路径规划,会根据当前路况生成时时的行进路径。上述场景中,全局路径规划和本地路径规划时,就会使用到参数服务器:路径规划时,需要参考小车的尺寸,我们可以将这些尺寸信息存储到参数服务器,全局路径规划节点与本地路径规划节点都可以从参数服务器中调用这些参数(有些路径限宽限高)。参数服务器,一般适用于存在数据共享的一些应用场景。我们将小车尺寸放到一个参数服务器中,这样各个节点使用小车尺寸判断是否能通行直接从参数服务器里取就行

动作编程通信:数据共享模式

1.参数服务器的理论模型

1.演员列表

ROS管理者(其中有一个管理参数的公共容器)、参数的设置方、参数的调用方

2.流程

1.参数的设置方提交参数到管理者,管理者将参数保存至一个参数列表

2.参数的调用者向管理者发送一个参数调用请求

3.管理者到参数列表中查找相关参数,将参数值返回给调用者

3.注意

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

参数服务器可以使用的数据类型:32-bit integers、booleans、strings、doubles、iso8601 dates、lists、base64-encoded binary data、字典。

2.参数服务器的实现(c++)

1.创建一个参数的实例

在工作空间下的源码空间src中建立功能包 plumbing_param_server,并建立依赖包 roscpp、rospy,std_msgs.定位到新建功能包下的src文件,新建文件 demo_param_set.cpp

1.参数新增
#include "ros/ros.h"
 
/*
需要实现参数的新增和修改
1.需求:首先设置机器人的共享参数,类型、半径、再修改半径
2.通过两套api实现  ros::NodeHandle  setParam    ros::param set
*/
 
int main(int argc, char  *argv[])
{
    ros::init(argc,argv,"setpara_c");
    ros::NodeHandle nh;
 
    //参数增加
    //方案1:参数名字,参数值
    nh.setParam("type","xiaoHuang");
    nh.setParam("radius",0.15);
 
    //方案2:参数名字,参数值
    ros::param::set("type_param","xiaobai");
    ros::param::set("radius_param",0.1);
    return 0;
}
2.参数修改

直接在原有的基础上进行修改

   //修改 方案一:参数覆盖
    nh.setParam("radius",0.2);
    
    //修改 方案二
    ros::param::set("radius_param",0.25);
#include "ros/ros.h"
 
/*
需要实现参数的新增和修改
1.需求:首先设置机器人的共享参数,类型、半径、再修改半径
2.通过两套api实现  ros::NodeHandle  setParam    ros::param set
*/
 
int main(int argc, char  *argv[])
{
    ros::init(argc,argv,"setpara_c");
    ros::NodeHandle nh;
 
    //参数增加
    //方案1:参数名字,参数值
    nh.setParam("type","xiaoHuang");
    nh.setParam("radius",0.2);
 
    //方案2:参数名字,参数值
    ros::param::set("type_param","xiaobai");
    ros::param::set("radius_param",0.25);
    return 0;
}
 3.参数获取

在功能包的源码空间src下创建文件demo_param_get.cpp

#include "ros/ros.h"
 
/*
演示参数查询
*/
 
int main(int argc, char  *argv[])
{
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"get_param_c");
    ros::NodeHandle nh;
 
    //ros::NodeHandle----------------------------------------
    //1.param(键,默认值)   存在,返回对应结果,否则返回默认值(0.5)
    double radius = nh.param("radius",0.5);
    ROS_INFO("radius = %.2f",radius);
 
    //2.getParam(键,存储结果的变量):键存在返回值是true,并且将值赋给参数2。不存在为false,不为参数二赋值
    double radius2;
    bool result = nh.getParam("radius",radius2);
    if(result)
    {
        ROS_INFO("获取的半径是 radius = %.2f",radius2);
    }
    else
    {
        ROS_INFO("被查询的变量不存在");
    }
 
    //3.getParamCached(键,存储结果的变量)  --从缓存获取,效率更高,结果与3一样的
 
    //4.getParamNames(std::vector<std::string>) 获取所有的键名称,并存储在参数 vector 中
    std::vector<std::string> names;
    nh.getParamNames(names);
    for(auto && name:names)
    {
        ROS_INFO("遍历到的元素:%s",name.c_str());
    }
    
    //5.hasParam(键) 是否包含某个键 是返回true 否则返回false
    bool flag1  = nh.hasParam("radius");
    bool flag2 = nh.hasParam("sjsjsjs");
    ROS_INFO("参数一存在吗?%d",flag1);
    ROS_INFO("参数二存在吗?%d",flag2);
 
    //6.searchParam(参数一,参数二)  参数一是搜索的键,参数二存储键的名称
    std::string key ;
    nh.searchParam("radius",key);
    ROS_INFO("搜索结果%s",key.c_str());
    return 0;
}

一些修改的API模板

/*
    参数服务器操作之查询_C++实现:
    在 roscpp 中提供了两套 API 实现参数操作
    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 ----- 与 NodeHandle 类似
*/
4.参数删除

在功能包的源码空间src下创建文件demo_param_delete.cpp

#include "ros/ros.h"
/*
仍然两种方式实现
*/
 
int main(int argc, char  *argv[])
{
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"param_del");
    ros::NodeHandle nh;
 
    //删除一
    bool flag1 = nh.deleteParam("radius");
    if(flag1)
    {
        ROS_INFO("success");
    }
    else{
        ROS_INFO("Failed");
    }
    //删除二
    bool flag2 = ros::param::del("radius_param");
     if(flag2)
    {
        ROS_INFO("success");
    }
    else{
        ROS_INFO("Failed");
    }
    return 0;
}

2.修改CmakeLists.txt配置文件

3.编译catkin_make

4.运行可执行文件

别忘了source

5.检验

rosparam list命令:列出所有参数列表

结束语

以上就是我学习到的内容,如果对您有帮助请多多支持我,如果哪里有问题欢迎大家在评论区积极讨论,我看到会及时回复。

;