2 ROS1通讯编程基础(3)

2.5 参数服务器编程

2.5.1 参数服务器理论模型

参数服务器的理论模型如图所示:ROS Master 作为一个公共容器保存参数,Setter可以向容器中设置参数,Getter可以获取参数,即通过Setter和Getter实现对参数服务器的增删改查操作。注意:参数服务器不是为高性能而设计的,因此最好用于存储静态的非二进制的简单数据,如int、bool、string、doubles、iso8601 dates(时间数据)、lists和字典等。

图片.png

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

  • ①Setter设置参数:Setter通过 RPC 向参数服务器发送参数(包括参数名与参数值),ROS Master 将参数保存到参数列表中。
  • ②Getter获取参数:Getter通过 RPC 向参数服务器发送参数查找请求,请求中包含要查找的参数名。
  • ③ROS Master向Getter发送参数值:ROS Master 根据步骤2请求提供的参数名查找参数值,并将查询结果通过 RPC 发送给 Getter。

2.5.2参数服务器增删改查编程

参数服务器类型主要为:(key,value)类型,因此在编程上C++或者是Python可以采用map函数或者字典的用法去简化编程。

此外C++在参数服务器的API中提供了两套方法进行参数的操作,即ros::NodeHandleros::param,下面编程中依次对其进行使用。

2.5.2.1 新建功能包

  1. 新建功能包,在工作空间下新建功能包param_server并预设依赖项rospy roscpp std_msgs,并在功能包param_server下创建scripts文件夹用于存放Python文件,如图所示:

图片.png

2.5.2.2 C++代码实现参数服务器增加操作

  1. 采用C++编写代码,两种API的具体操作见注释
    1. 编写代码

catkin_ws/src/param_server/src/add_modparam_cpp.cpp

#include "ros/ros.h"
using namespace std;

/*
两套API对参数的增加或者修改的操作是类似的,主要采用set函数进行
    ros::NodeHandle
        setParam("键",值)

    ros::param
        set("键","值")
*/

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

    // API1---使用NodeHandle-------------------------------------------------
    ros::NodeHandle nh;
    nh.setParam("nh_int",10); //整型
    nh.setParam("nh_double",3.14); //浮点型
    //修改演示替换掉键的值
    nh.setParam("nh_int",10000);

    //API2---使用param--------------------------------------------------------
    ros::param::set("param_int",20);
    ros::param::set("param_double",3.14);
    //修改演示替换掉键的值
    ros::param::set("param_int",20000);

    return 0;
}
    1. 对CMakeList.txt进行设置,因为没有调用自定义文件,因此只需要设置add_executabletarget_link_libraries两项:

catkin_ws/src/param_server/CMakeList.txt

add_executable(add_modparam_cpp_node src/add_modparam_cpp.cpp)
target_link_libraries(add_modparam_cpp_node ${catkin_LIBRARIES})
    1. 编译运行查看参数。

图片.png

2.5.2.3 Python代码实现参数服务器增加操作

  1. 编写Python代码,API只有一种,编写完赋予可执行权限。
    1. 编写代码add_modparam_py.py

catkin_ws/src/param_server/scripts/add_modparam_py.py

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import rospy

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

    # 设置各种类型参数
    rospy.set_param("p_int",10)
    rospy.set_param("p_double",3.14)
    # 修改
    rospy.set_param("p_int",100)
    rospy.loginfo("参数设置成功,采用命令rosparam list 查看param 列表")
    rospy.loginfo("自定义参数只有:p_int,p_double")
    rospy.loginfo("查看参数值采用rosparam get 参数名,如rosparam get /p_int")
    1. 在scripts文件夹输入sudo chmod +x *.py赋予可执行权限
    1. 编译执行,查看输出结果

图片.png

2.5.2.4 C++代码删除参数操作

  1. 采用C++编写代码,代码见注释
    1. 编写删除参数操作,delparam_cpp.cpp代码

catkin_ws/src/param_server/src/delparam_cpp.cpp

#include "ros/ros.h"

/* 
    ros::NodeHandle
        deleteParam("键")
        根据键删除参数,删除成功,返回 true,否则(参数不存在),返回 false

    ros::param
        del("键")
        根据键删除参数,删除成功,返回 true,否则(参数不存在),返回 false

*/

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

    ROS_INFO("希望删除nh_int和param_int两个参数");
    ROS_INFO("删除成功,返回 true,否则(参数不存在),返回 false");

    ros::NodeHandle nh;
    bool r1 = nh.deleteParam("nh_int");
    ROS_INFO("nh 删除结果:%d",r1);

    bool r2 = ros::param::del("param_int");
    ROS_INFO("param 删除结果:%d",r2);

    return 0;
}
    1. 对CMakeList.txt进行设置,同理只需要设置add_executabletarget_link_libraries两项:

catkin_ws/src/param_server/CMakeList.txt

add_executable(delparam_cpp_node src/delparam_cpp.cpp)
target_link_libraries(delparam_cpp_node ${catkin_LIBRARIES})
    1. 编译运行查看结果。

图片.png

2.5.2.5 Python代码删除参数操作

  1. 编写Python代码,编写完赋予可执行权限。
    1. 编写代delparams_py.py

catkin_ws/src/param_server/scripts/delparams_py.py

#! /usr/bin/env python
# -*- coding: utf-8 -*-

"""
    rospy.delete_param("键")
    键存在时,可以删除成功,键不存在时,会抛出异常
"""
import rospy

if __name__ == "__main__":
    rospy.init_node("delete_param_py")
    rospy.loginfo("尝试删除p_int,删除成功返回数值,删除失败提示输出")

    try:
        rospy.delete_param("p_int")
    except Exception as e:
        rospy.loginfo("删除失败")
    1. 在scripts文件夹输入sudo chmod +x *.py赋予可执行权限
    1. 编译执行,查看输出结果

图片.png

2.5.2.6 修改参数操作

修改参数操作和增加参数操作一致,只需要覆盖掉同key的value即可。

2.5.2.7 C++代码查询参数操作

  1. 采用C++编写代码,具体操作见注释
    1. 编写查询参数操作,getparam_cpp.cpp代码

catkin_ws/src/param_server/src/getparam_cpp.cpp

#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存储搜索结果的变量

*/

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

    // ros::NodeHandle--------------------------------------------------------
    ros::NodeHandle nh;
    // param 函数,其余函数操作查看API
    int get1 = nh.param("nh_int",100); // 键存在
    ROS_INFO("获取param参数nh_int的值:%d",get1);

    // ros::param--------------------------------------------------------
    int get2 = ros::param::param("param_int",20); //存在
    ROS_INFO("获取param参数param_int的值:%d",get2);

    return 0;
}
    1. 对CMakeList.txt进行设置,同理只需要设置add_executabletarget_link_libraries两项:

catkin_ws/src/param_server/CMakeList.txt

add_executable(getparam_cpp_node src/getparam_cpp.cpp)
target_link_libraries(getparam_cpp_node ${catkin_LIBRARIES})
    1. 编译运行查看结果。

图片.png

2.5.2.8 Python代码查询参数操作

  1. 编写Python代码,编写完赋予可执行权限。
    1. 编写代getparam_py.py

catkin_ws/src/param_server/scripts/getparam_py.py

#! /usr/bin/env python
# -*- coding: utf-8 -*-

""" 
        get_param
        get_param_cached
        get_param_names
        has_param
        search_param
"""

import rospy

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

    #获取参数
    int_value = rospy.get_param("p_int",10000)
    rospy.loginfo("获取的数据:%d",int_value)
    1. 在scripts文件夹输入sudo chmod +x *.py赋予可执行权限
    1. 编译执行,查看输出结果

图片.png

2.5.3 参数服务器编程总结

参数服务器使用多用于数据的共享,其编程逻辑主要在于创建句柄,然后通过内置的API函数进行参数增删改查,其中增加参数的操作和修改参数的操作方法是一样的,难点在于对参数的查询,函数太多,可以根据实际情况查阅API进行编程。

参考文献:B站视频:【奥特学园】ROS机器人入门课程《ROS理论与实践》零基础教程

ROS-WIKI:Parameter Server

ROS-WIKI:C++的API

ROS-WIKI:Python的API

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值