【ROS参数服务器】

参数服务器是以共享方式实现不同节点间数据交互的通信方式。主要用于存储多节点共享的数据,类似于全局变量。ROS中的参数服务器主要包含三个角色,分别是ROS Master(节点管理者)、Talker(参数设置者)、Listener(参数使用者),其中Talker和Listener均通过RPC协议进行数据的交互,ROS Master根据Listener提供的请求,查询参数,并通过RPC协议将其发送给Listener,由于通信协议的限制,参数服务器适用于不是高性能的场景,一般用于存储一些非二进制的静态简单数据。

在这里插入图片描述

C++实现参数服务器
1 Talker(参数设置者)
#include "ros/ros.h"
/**
 * @brief 
 * 实现参数服务器数据的增加和修改
 * 即 设置一个参数,然后修改其值
 * @param argc 
 * @param argv 
 * @return int 
 */
int main(int argc,char *argv[]){
    setlocale(LC_ALL,"");
    //初始化ros节点
    ros::init(argc,argv,"set_param_c");
    //创建句柄
    ros::NodeHandle nh;
    //使用句柄创建参数服务器
    nh.setParam("type","ceshi");
    nh.setParam("radius",1.0);
    //使用ros::param来设置参数
    ros::param::set("type_param","ceshi_1");
    ros::param::set("radius_param",1.2);
    return 0;
}

1.1 CmakeLists.txt的配置,这个和普通节点的配置一样了
在这里插入图片描述
在这里插入图片描述
1.2 测试
打开终端,启动主节点 roscore

roscore

打开终端,启动配置好的C++节点

source ./devel/setup.bash
#该步骤会自动将参数发布至 rosparam list
rosrun plumbing_param_server ps_set_node

打开终端,使用rosparam list 查看话题
在这里插入图片描述
然后可以使用下面命令对参数进行操作

rosparam get /type# 得到参数ceshi

在这里插入图片描述

 rosparam set /type 123#可以修改 /type的值

在这里插入图片描述

2 Listener(参数获取)

记录nodeHandler参数的获取方法,定义 param_server_get.cpp 文件,然后内容如下:

#include "ros/ros.h"

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

    //nodehandler实现
    //1 param(键,默认值),键值不存在,则返回默认值
    double radius = nh.param("radius",0.01);
    ROS_INFO("the radius param=%.2f",radius);
    //2. getParam(键,存储的返回值变量)
    //如果键存在,则返回true,且将返回值赋值给变量
    double res = 0.0;
    bool flag = nh.getParam("radius",res);
    if(flag){
        ROS_INFO("the res is :%.2f",res);
    }else{
        ROS_INFO("the res not exists..");
    }
    //3. getParamCached(键,存储的返回值变量) 从缓存中获取数据
    //如果之前获取过,则返回true,一般速度较快 并将 值赋值给返回值变量
    flag = nh.getParamCached("radius",res);
    if(flag){
        ROS_INFO("the cached res is :%.2f",res);
    }else{
        ROS_INFO("the cached res not exists..");
    }
    //4 getParamNames(std::vector<std::string>)
    std::vector<std::string> names;
    nh.getParamNames(names);
    for(auto &&name : names){
        ROS_INFO("the param name is: %s",name.c_str());
    }
    //5 hasParam(string) 有 true 无 false
    bool flag1 = nh.hasParam("radius");
    bool flag2 = nh.hasParam("tt");
    ROS_INFO("the flag1 res: %d, the flag2 res: %d",flag1,flag2);
    //searchParam("keyName",res)
    // 如果 keyName存在,则将keyName 返回给res
    std::string r;
    nh.searchParam("radius",r);
    ROS_INFO("the res %s",r.c_str());
    return 0;
}

2.1 将上面的 param_server_get,cpp 配置到 CmakeLists.txt
在这里插入图片描述
在这里插入图片描述
2.2 打开终端,先启动 roscore
2.3 启动 Talker 节点,发布参数

source ./devel/setup.bash
rosrun plumbing_param_server ps_set_node

2.4 启动Listener节点,获取参数

source ./devel/setup.bash
rosrun plumbing_param_server ps_get_node

在这里插入图片描述
在这里插入图片描述

3. 使用ros::param获取参数

如果以上使用NodeHandler获取参数看懂了,下面使用ros::param进行获取其实是大差不差,可以看下图的 API
在这里插入图片描述
部分源代码:

#include "ros/ros.h"

int main(int argc,char *argv[]){
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"get_para");
    // ros::param下面的参数获取
    double re = ros::param::param("radius",0.2);
    ROS_INFO("rosParam res: %.2f",re);
    //等价于std::vector<std::string> nameRes;
    ros::V_string nameRes;
    ros::param::getParamNames(nameRes);
    for(auto &&name : nameRes){
        ROS_INFO("the name :%s",name.c_str());
    }
    return 0;
}

执行过程和上面的一样,可以看到最终的执行结果
在这里插入图片描述

3 删除节点

创建 param_server_del.cpp 文件

#include "ros/ros.h"

int main(int argc,char *argv[]){
    ros::init(argc,argv,"del_para");
    ros::NodeHandle nh;

    //nh.deleteParam
    bool flag = nh.deleteParam("radius");
    if(flag){
        ROS_INFO("delete complete...");
    }else{
        ROS_INFO("Wrong...");
    }
    //ros:param::del
    bool flag1 = ros::param::del("radius");
    if(flag1){
        ROS_INFO("delete  success");
    }else{
        ROS_INFO("delete wrong");
    }
    return 0;
}

先运行 param_server_set.cpp 节点,然后再进行按照键值删除。注意不要忘了配置CMakeLists.txt,和上面的配置方法相同, 配置完全后,再进行运行即可。

Python实现参数服务器
1 设置参数
#! /usr/bin/env python
# -*- coding:utf-8 -*-
import rospy

if __name__=="__main__":
    #初始化node
    rospy.init_node("set_param_server_p")
    #设置参数
    rospy.set_param("type_p","set_server")
    rospy.set_param("radius",1.0)
    rospy.set_param("p_list",[1,2,3])

1.1 在 CMakeLists.txt 中设置 Python 脚本的执行
在这里插入图片描述
1.2 编译,随后切换到 scripts文件目录,使用以下命令:

chmod +x *.py #修改python 文件的可执行权限

1.3 打开终端 运行 roscore
1.4 运行新建立的节点

source ./devel/setup.bash
rosrun plumbing_param_s(你的项目名) param_server_set.py#即可设置参数 
2 获取参数
#! /usr/bin/env python
# -*- coding:utf-8 -*-
import rospy
'''
get_param_cached
get_param_names
has_param
search_param
'''
if __name__=="__main__":
    rospy.init_node("param_server_get")

    type_p = rospy.get_param("type_p","aa")
    rospy.loginfo("info : %s",type_p)

    type_p = rospy.get_param_cached("type_p","aa")
    rospy.loginfo("info : %s",type_p)

    names = rospy.get_param_names()
    for name in names:
        rospy.loginfo("res: %s",name)
    if rospy.has_param("type_p"):
        rospy.loginfo("the type_p : %s",rospy.get_param("type_p"))
    else:
        rospy.loginfo("wrong ... ")
    
    key = rospy.search_param("type_p")
    rospy.loginfo(key)

执行过程和上面的 set.py 同

3 删除参数
#! /usr/bin/env python
# -*- coding:utf-8 -*-
import rospy

if __name__=="__main__":
    rospy.init_node("del_p")

    try:
        rospy.delete_param("type_p")
    except Exception as e:
        rospy.loginfo("key is not exists")

执行过程和上面的 set.py 同

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值