参数服务器通信 是ROS通信中一种比较特殊又比较简单的通信方式。参数服务器在ROS Master内部运行。一方向服务器设置参数,另一方则可以向服务器请求参数。
而参数服务器与topic与service不同,更加得静态,且参数服务器维护着一个数据字典,存储了参数与配置。
而与参数服务器沟通一般共有三种方式
- launch文件中设置
- 在代码中操作
- 在命令行调试
在launch文件中设置
写在<node>里面
1 2 3 4 5 6
| <launch> <node pkg="ego_planner" name="drone_1" type="ego_planner_node"> <param name="fsm/flight_type" value="1" /> </node> </launch>
|
ros会自动给参数加上节点得前缀,即该参数在服务器中全名变为 /drone_1/fsm/flight_type以此来防止冲突和支持多机协同
而为了读取这种“私有参数”,需要创建一个“私有句柄”
1 2 3 4
| ros::NodeHandle nh("~");
nh.param("fsm/flight_type", ...);
|
写在<node>外面(全局参数)
1 2 3 4 5 6 7
| <launch> <param name="global_gravity" value="9.8" />
<node pkg="ego_planner" name="drone_1" type="ego_planner_node"> </node> </launch>
|
同样句柄中则不需要加~
1 2 3 4
| ros::NodeHandle nh;
nh.param("global_gravity", ...);
|
如果两种参数都要使用该怎么办?通常可以声明两个句柄,一个公有句柄,一个私有句柄。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void init(ros::NodeHandle& nh, ros::NodeHandle& nh_private) { nh_private.param("fsm/flight_type", ...);
nh.param("global_radius", ...); }
int main(int argc, char** argv) { ros::init(argc, argv, "my_node");
ros::NodeHandle nh; ros::NodeHandle nh_private("~");
init(nh, nh_private); }
|
加载YAML文件
批量加载参数字典
1 2 3 4 5 6 7 8 9
| <launch> <rosparam file="$(find my_pkg)/config/params.yaml" command="load"/> <node pkg="my_pkg" type="my_node" name="node1"> <rosparam file="$(find my_pkg)/config/private_params.yaml" command="load"/> </node> </launch>
|
在代码中操作
CPP接口
在cpp中,主要通过ros::NodeHandle来操作
注意上文中提到的全局句柄和私有句柄的区别
获取参数
方式一: getParam,先声明变量再获取
1 2 3 4 5 6 7 8
| ros::NodeHandle nh; double radius;
if (nh.getParam("/global_radius", radius)) { ROS_INFO("Got radius: %f", radius); } else { ROS_WARN("Failed to get param 'global_radius'"); }
|
方式二: param 带有默认值
1 2 3
| int baud_rate; nh.param<int>("baud_rate", baud_rate, 57600);
|
设置与删除
1 2
| nh.setParam("new_param", "hello"); nh.deleteParam("old_param");
|
Python接口
获取参数
1 2 3 4 5 6 7 8 9 10 11
| import rospy
global_radius = rospy.get_param('/global_radius')
baud = rospy.get_param('baud_rate', 9600)
private_val = rospy.get_param('~private_param', 'default')
|
设置参数
1 2 3 4 5 6 7 8 9 10 11 12
| rospy.set_param('my_string', 'ros is cool')
if rospy.has_param('my_string'): print("Param exists")
try: rospy.delete_param('my_string') except KeyError: print("Param not found")
|
在命令行调试
- 列出所有参数
- 获取参数值
1 2
| rosparam get /background_r rosparam get /
|
- 设置参数值
1
| rosparam set /background_b 100
|
- 删除参数
1
| rosparam delete /background_b
|
- 保存/加载YAML
1 2 3
| rosparam dump params.yaml rosparam load params.yaml rosparam load params.yaml /my_namespace
|
参数使用例
例如在launch文件中声明
1
| <param name="loop_rate" value="20" />
|
然后在cpp中
1 2 3
| int rate_hz; nh.param("loop_rate", rate_hz, 10); ros::Rate loop_rate(rate_hz);
|