ROS 8: 参数的使用与编程
在ROS Master中有一个参数服务器,它是一个全局字典,用来保存各个节点的配置参数的,这些参数是各个节点都可以全局访问的。
可以简单理解为,这是一个用来存放全局变量的空间
有关参数的使用,有如下命令行工具
一、参数的命令行工具
我们在命令行会使用rosparam,用于从ROS参数服务器获取、设置和删除参数。
rosparam is a command-line tool for getting, setting, and deleting parameters from the ROS Parameter Server.
Commands:
        rosparam set    set parameter
        rosparam get    get parameter
        rosparam load   load parameters from file
        rosparam dump   dump parameters to file
        rosparam delete delete parameter
        rosparam list   list parameter names如果参数比较多的时候,我们会用*.yaml文件来存参数。
以下是rosparam在命令行的工具使用介绍
- 
列出参数 rosparam list- 如果此时你运行turtlesim,你可以使用rosparam list看到参数名:
 /rosversion /run_id /turtlesim/background_b /turtlesim/background_g /turtlesim/background_r- 
如果你设置了命名空间,还需要在后面加上命名空间的名字,如: rosparam list /namespace这里的命名空间可以类比为c++中的 using namespace xxx中的xxx具体内容放在第三Part介绍 
 
- 如果此时你运行turtlesim,你可以使用
- 
显示某个参数值 rosparam get <param_key>
- 
设置某个参数值 rosparam set <param_key> <param_value>比如要修改turtlesim的background对应的RGB值,输入: rosparam set /turtlesim/background_g 255然后turtlesim需要收到一次 /clear请求,才会重新读取背景值rosservice call /clear "{}"如果此时你正在运行上述代码,你就可以看到,海龟仿真器的背景颜色已经修改了。 -v:显示详细输出。 -t <text_file>, --textfile <text_file> :将参数设置为文本文件的内容。 -b <binary_file>, --binfile <binary_file> :将参数设置为二进制文件的内容。参数服务器将值存储为XML-RPC二进制类型(基64编码)。 
- 
保存参数到文件 rosparam dump <file_name>
- 
从文件读取参数 rosparam load <file_name>此时,在工作空间使用 rosparam dump param.yaml指令,ros就会把当前的参数配置保存到该yaml文件中。使用 rosparam load param.yaml就可以加载以前保存好的参数yaml文件会存储类似于以下的内容, rosdistro: 'melodic ' roslaunch: uris: xxx: http://xxx:44429/ rosversion: '1.14.10 ' run_id: 80cf1b56-0e4b-11ed-9d12-000c29d50405 turtlesim: background_b: 255 background_g: 255 background_r: 255
- 
删除参数 rosparam delete <param_key>删除当前系统载入的参数。 
二、参数在编程上的使用
c++代码实现
1、设置参数
ros::NodeHandle::setParam() 
ros::param::set()
在c++中,在代码中获取参数时,除了上述代码使用的ros::param::get方法之外,还可以使用句柄来获取参数:ros::NodeHandle::getParam() 。需要的参数是一样的:
//ros::NodeHandle::setParam()
ros::NodeHandle nh;
nh.setParam("/global_param", 5);
nh.setParam("relative_param", "my_string");
nh.setParam("bool_param", false);都是需要输入参数名和存放的变量名
//ros::param::set()
ros::param::set("/global_param", 5);
ros::param::set("relative_param", "my_string");
ros::param::set("bool_param", false);需要注意的是,如果使用NodeHandle,还需要注意他对应的命名空间。
对于命名空间来说,节点名前面直接加个/号,代表着这个节点是放在全局的,比如/turltesim。如果需要使用对应命名空间里的节点,需要写上空间名,如:/my/turtlesim
2、检查参数是否存在
- ros::NodeHandle::hasParam()
ros::NodeHandle nh;
if (nh.hasParam("my_param")){...}- ros::param::has()
if (ros::param::has("my_param")){...}3、删除参数
- ros::NodeHandle::deleteParam()
ros::NodeHandle nh;
nh.deleteParam("my_param");- ros::param::del()
ros::param::del("my_param");4、访问私有参数
根据使用的是“句柄”接口还是“裸”接口,访问私有参数的方式是不一样的。在句柄接口中,您必须创建一个新的ros::NodeHandle以私有命名空间作为其命名空间:
ros::NodeHandle nh("~");
std::string param;
nh.getParam("private_name", param);在裸界面中,可以使用描述私有参数的相同符号来访问它们,例如:
std::string param;
ros::param::get("~private_name", param);5、搜索参数键
- ros::NodeHandle::searchParam()
std::string key;
if (nh.searchParam("bar", key))
{
  std::string val;
  nh.getParam(key, val);
}- ros::param::search()
std::string key;
if (ros::param::search("bar", key))
{
  std::string val;
  ros::param::get(key, val);
}6、demo
模仿本案例开头的修改turtlesim背景案例,我们所需要的头文件有:
#include <ros/ros.h>
#include <string>
#include <std_srvs/Empty.h>主函数:
int main(int argc,char **argv){
    // 初始化ros
    ros::init(argc,argv,"param_code");
    ros::NodeHandle param_node;
    int red,green,blue;
    //参数获取,类比命令行rosparam的get
    ros::param::get("/turtlesim/background_r",red);
    ros::param::get("/turtlesim/background_g",green);
    ros::param::get("/turtlesim/background_b",blue);
    ROS_INFO("Get Backgroud Color[%d, %d, %d]", red, green, blue);
    //参数设置,类比命令行rosparam的set
    ros::param::set("/turtlesim/background_r",255);
    ros::param::set("/turtlesim/background_g",255);
    ros::param::set("/turtlesim/background_b",255);
    ROS_INFO("Set Backgroud Color[255, 255, 255]");
    //参数获取,类比命令行rosparam的get
    ros::param::get("/turtlesim/background_r",red);
    ros::param::get("/turtlesim/background_g",green);
    ros::param::get("/turtlesim/background_b",blue);
    ROS_INFO("Get Backgroud Color[%d, %d, %d]", red, green, blue);
    // 参考我们上面讨论的参数使用方法,我们知道turtlesim需要接受/clear请求才会更新turtlesim的参数。
    //调用/clear服务,用来刷新背景颜色
    ros::service::waitForService("/clear");
    ros::ServiceClient clear_background = param_node.serviceClient<std_srvs::Empty>("/clear");
    std_srvs::Empty srv;
    clear_background.call(srv);
    sleep(1);
    return 0;
}程序编译:
打开功能包的CMakeLists,使用如下语句即可使用catkin_make
add_executable(learn_param src/learn_param.cpp)
target_link_libraries(learn_param ${catkin_LIBRARIES})python代码实现
1、获取参数
rospy.get_param(参数名称) 
如果使用get_param()来获取名称空间,则会返回一个字典,其中的键等于该名称空间中的参数值。
global_name = rospy.get_param("/global_name")
relative_name = rospy.get_param("relative_name")
private_param = rospy.get_param('~private_name')
default_param = rospy.get_param('default_param', 'default_value')
# fetch a group (dictionary) of parameters
gains = rospy.get_param('gains')
p, i, d = gains['p'], gains['i'], gains['d']2、设置参数
rospy.set_param(参数名称,参数值)
# 使用rospy和原始python对象
rospy.set_param('a_string', 'baz')
rospy.set_param('~private_int', 2)
rospy.set_param('list_of_floats', [1., 2., 3., 4.])
rospy.set_param('bool_True', True)
rospy.set_param('gains', {'p': 1, 'i': 2, 'd': 3})
# 使用rosparam和yaml字符串
rosparam.set_param('a_string', 'baz')
rosparam.set_param('~private_int', '2')
rosparam.set_param('list_of_floats', "[1., 2., 3., 4.]")
rosparam.set_param('bool_True', "true")
rosparam.set_param('gains', "{'p': 1, 'i': 2, 'd': 3}")
rospy.get_param('gains/p') #should return 13、参数存在
rospy.has_param(param_name)
如果存在该参数,返回True,否则False。
if rospy.has_param('to_delete'):
	rospy.delete_param('to_delete')4、删除参数
rospy.delete_param(参数名称)
其实就是从参数服务器删除参数
try:
	rospy.delete_param('to_delete')
except KeyError:
	print("value not set")5、搜索参数键
rospy.search_param(参数名称)
查找最接近的参数名,从私有名称空间开始,向上一直搜索到全局名称空间。
param_name = rospy.search_param('global_example')
v = rospy.get_param(param_name)如果上面的代码出现在/foo/bar节点中,
rospy.search_param会试着按照以下顺序找到参数
/foo/bar/global _example
/foo/global _example
/global _example
6、获取参数名
rospy.get_param_names()
7、demo
以下demo和c++的功能完全一样。
# -*- coding: utf-8 -*-
import rospy
from std_srvs.srv import Empty
import sys
def param_set():
    rospy.init_node('param_py')
    # 读取背景颜色参数
    red   = rospy.get_param('/background_r')
    green = rospy.get_param('/background_g')
    blue  = rospy.get_param('/background_b')
    rospy.loginfo("Get Backgroud Color[%d, %d, %d]", red, green, blue)
    # 设置背景颜色参数
    rospy.set_param('/background_r',100)
    rospy.set_param('/background_g',100)
    rospy.set_param('/background_b',100)
    rospy.loginfo("Set Backgroud Color[100, 100, 100]")
    # 读取背景颜色参数
    red   = rospy.get_param('/background_r')
    green = rospy.get_param('/background_g')
    blue  = rospy.get_param('/background_b')
    rospy.loginfo("Get Backgroud Color[%d, %d, %d]", red, green, blue)
    rospy.wait_for_service('/clear')
    try:
        clear_background = rospy.ServiceProxy('/clear', Empty)
        # 请求服务调用,输入请求数据
        response = clear_background()
        return response
    except rospy.ServiceException, e:
        print "Service call failed: %s"%e
if __name__ == '__main__':
    param_set() 
                     
                     
                        
                        