ROS学习笔记7——ROS通信机制3(参数服务器)

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

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

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

ROS学习笔记7——ROS通信机制3(参数服务器)_第1张图片

二、角色

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

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

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

三、流程

1、Talker 设置参数

setParam("foo",1)

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

2、Listener 请求获取参数

getParam("foo")

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

3、ROS Master 向 Listener 发送参数值

{foo:1}

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

四、C++实现参数服务器参数的增删改查操作

ros在NodeHandle和param下都有一套增删改查的命令。

4.1 参数服务器增、改参数

#include "ros/ros.h"

/*
    需要实现参数的新增和修改
    需求:
        首先设置机器人的共享参数,“名字”、“半径”
        再修改半径
    实现:
        1、ros::NodeHandle
            setParam("键",值)
        2、ros::param
            set("键","值")
*/

int main(int argc, char *argv[])
{
    /* code */
    setlocale(LC_ALL,"");
    //初始化节点
    ros::init(argc,argv,"add_modify_param");
    //创建节点句柄
    ros::NodeHandle nh;
    //---------参数增-----------
    //方案1、nh
    nh.setParam("name","robot1");
    nh.setParam("radius",0.15);
    //方案2、ros::param
    ros::param::set("name_param","robot2");
    ros::param::set("radius_param",0.2);

    //---------参数改:其实就是用增的命令覆盖原来的数据-----------
    //方案1、nh
    // nh.setParam("radius",0.155);
    //方案2、ros::param
    // ros::param::set("radius_param",0.25);

    return 0;
}

4.2 参数服务器获取参数

#include "ros/ros.h"

/*
    参数查询
    实现:
    1、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存储搜索结果的变量

    2、ros::param ----- 与 NodeHandle 类似
    
*/

int main(int argc, char *argv[])
{
    /* code */
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"get_param");
    ros::NodeHandle nh;

    //ros::NodeHandle------------------
    //1、param(键,默认值)
    double radius = nh.param("radius",0.5);
    ROS_INFO("1/ radius = %.2f",radius);
    //2、getParam(键,存储结果的变量)
    //3、getParamCached(键,存储结果的变量)
    double radius2;
    //bool result = nh.getParam("radius",radius2);
    bool result = nh.getParamCached("radius",radius2);
    if(result)
    {
        ROS_INFO("2/3/ radius = %.2f",radius);
    }else{
        ROS_INFO("查询变量不存在!");
    }
    //4、getParamNames(std::vector)
    std::vector names;
    nh.getParamNames(names);
    for(auto &&name : names)
    {
        ROS_INFO("4/ 遍历到的元素:%s",name.c_str());
    }
    //5、hasParam(键)
    bool flag1 = nh.hasParam("radius");
    bool flag2 = nh.hasParam("radiuss");
    ROS_INFO("5/ radius 存在吗?%d",flag1);
    ROS_INFO("5/ radiuss 存在吗?%d",flag2);
    //6、searchParam(参数1,参数2)
    std::string key;
    nh.searchParam("radius",key);
    ROS_INFO("6/ 搜索结果:%s",key.c_str());

    return 0;
}

4.3 参数服务器删除参数

#include "ros/ros.h"
/*
    参数删除:
    1、ros::NodeHandle
        delParam()
        删除成功true
        删除失败false

    2、ros::param
        del()
*/

int main(int argc, char *argv[])
{
    /* code */
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"del_param");
    ros::NodeHandle nh;
    //NodeHandle-------------------------
    //1、delParam()
    bool flag1 = nh.deleteParam("radius");
    if(flag1)
    {
        ROS_INFO("radius删除成功");
    }else{
        ROS_INFO("radius删除失败");
    }

    //param
    bool flag2 = ros::param::del("radius_param");
    if(flag2)
    {
        ROS_INFO("radius_param删除成功");
    }else{
        ROS_INFO("radius_param删除失败");
    }

    return 0;
}

你可能感兴趣的:(学习,笔记)