机器人的参数一般会提前设置好,这些参数都会放在yaml文件里,但有些参数是需要动态改变的,调试导航时尤其如此。于是ROS提供了rosparam命令和参数服务器这两个工具。rosparam
命令的方便之处在于它可以直接读取yaml文件中的参数,而不必自己找第三方库去文件中读取。
一般在package的文件夹里会建一个param
文件夹,也就是与launch
和msg
同一级,yaml文件就放在这个param
文件夹里。
使用rosparam load file.yaml
命令将多个参数加载到参数服务器,在用到时会从服务器中获取。但实际上,这个命令直接用得不多。要将一个yaml文件中的参数在节点启动时都加载到参数服务器,一般是在launch文件中使用rosparam
标签:1
2<rosparam file="$(find turtlebot_navigation)/param/move_base_params.yaml" command="load" />
<rosparam file="$(arg custom_param_file)" command="load" />
加载完成后,可以使用一些调试性的命令了。用rosparam list
查看所有参数。可以用rosparam get param
查看某参数的值,用rosparam set param value
设定参数的值。另外还可以用rosparam delete param
删除某个参数。
在launch文件里,如果参数paramA
是在某个node之内的,那么它的全名是/node/paramA
。如果希望全名是paramA
,那么不应在任何node内,一般写在launch开头。
使用rosparam get
时要注意,参数名称不只是yaml文件中的名称,而是一个完整名称,比如.yaml
中是这样的:1
2
3TrajectoryPlannerROS:
int_param: 2
max_vel_x: 0.15
要获得max_vel_x
的值,命令是rosparam get /move_base/TrajectoryPlannerROS/max_vel_x
,也就是/node/tag/param
启动ROS节点后, 用rosparam get param
可获知各个参数值,而且发现在关掉所有节点后,仍然能用rosparam get
获得参数值,可见它被存到参数服务器里了
程序中的param
加载参数的方法其实有三种,除了上面说的直接用rosparam load
命令和launch文件中使用load外,还可以在程序中使用param
和setParam
,getParam
函数,这里和yaml文件就没关系了。
1 | std::string s; |
getParam()函数可以从参数服务器获取参数值。如果成功,变量s和num的值将会被修改为参数值,函数返回true;如果不成功(譬如参数服务器没有设置这个参数),变量s和num将保持原值,函数会返回false。setParam()就是设置参数的值了。param()函数从参数服务器取参数值给变量。如果无法获取,则将默认值赋给变量,和param()函数的区别是还提供了一个默认值。
还有ros::NodeHandle::hasParam()
和ros::NodeHandle::deleteParam()
函数,后者可以在析构函数中使用。
如果在yaml文件中定义如下1
2
3waypoints:
X: [38, 38, 38, 38, 38, 38, 38 , 38.21, 39.25, 42.56, 48.97, 61]
Y: [-57, -45, -32.0, -18.5, -12.0, 0.0, 12, 35, 42.89, 80.41, 131.48, 139.47]
可以直接以vector
形式获取数据1
2vector<double> X;
nh.getParam("/frenet_planner/waypoints/X", X);
注意
使用yaml文件时,一定要注意格式的正确,但是最好不要用-符号,也就是不要用数组项,否则可能出问题,之前尝试使用一个第三方库读取yaml文件时,总是读取失败,发现只有加上-符号,也就是将参数作为数组项后才能正常读取。但再用rosparam get
读取这个文件中的参数就会出错,结果获得的全是默认值,不是当前值。用rosparam list
会发现加载的参数不全,原因是yaml文件中这样编辑:1
2
3
4TrajectoryPlannerROS:
-name: value
int_param: 2
max_vel_x: 0.15
不要加-name
一行,也就是反而不能使用标准的yaml格式