1. Significance of use
The use of parameter server aims to improve the flexibility and configurability of ROS nodes, and its significance can be understood from two aspects:
In the robot system, parameter transmission is very important. When the robot is working, we need to set the parameters of the robot (such as sensor parameters and algorithm parameters). Some parameters (such as the contour of the robot, the height of the sensor) can be set when the robot is started, and some parameters need to be changed dynamically (especially during debugging). Whether it is the setting of the sensor or the adjustment of the control parameters, a convenient parameter debugging interface needs to be reserved. ROS provides a parameter server to meet this requirement. We can set the parameters in the parameter server and obtain them from the parameter server when the parameters are needed. Using the parameter server to configure the parameters of the system is globally visible, which is convenient for us to retrieve and change the configuration status of the system.
The parameter server provides another way of information exchange between ROS nodes (commonly used methods are also messages and services). The main idea is to use a centralized parameter server (parameter server) to maintain the value of a variable set, and the node can actively query the value of the parameter of interest.
The rosparam command can operate the parameters on the ROS parameter server. Through the rosparam -h command, you can see the following methods:
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 列出参数服务器中的参数
2. Use points
ROS provides us with roslaunch .launch interface, command line interface, roscpp interface and rospy interface for operating parameters. The main points of use are as follows:
2.1 roslaunch .launch interface
This interface is used to configure the parameters at startup. The advantages of using the launch file to configure the parameters: 1. You can know the parameters used by the node and the given initial value without viewing the source program; 2. To modify the initial value of the parameter, you can save it to the launch file without modifying and Recompile the source program.
2.1.1 Use <param>
tags to directly define parameters
<param name="publish_frequency" type="double" value="10.0" />
Use tags to <rosparam>
configure parameters
2.1.2 Reading parameters from YAML file:
Generally, we can save the parameters that need to be set in a yaml file, and use the rosparam load [file path\file name] command to load multiple parameters to the parameter server at once.
For example, a parameter file named param.yaml, the content is:
#There are some params which will be loaded
yaml_param_string1: abcd123
yaml_param_string2: 567efg
yaml_param_num1: 123.123
yaml_param_num2: 1234567
yaml_param_set:
param_set_string1: zzzzz
param_set_num1: 999
param_set_string2: a6666
param_set_num2: 2333
param_subset:
param_set_string1: qwer
param_set_num1: 5432
param_set_string2: a12s3
param_set_num2: 1111
Load parameters in the terminal:
$ rosparam load param.yaml
Then, enter the command:
$ rosparam list
As you can see, all the parameters have been loaded:
/rosdistro
/roslaunch/uris/host_clp_virtual_machine__46453
/rosversion
/run_id
/yaml_param_num1
/yaml_param_num2
/yaml_param_set/param_set_num1
/yaml_param_set/param_set_num2
/yaml_param_set/param_set_string1
/yaml_param_set/param_set_string2
/yaml_param_set/param_subset/param_set_num1
/yaml_param_set/param_subset/param_set_num2
/yaml_param_set/param_subset/param_set_string1
/yaml_param_set/param_subset/param_set_string2
/yaml_param_string1
/yaml_param_string2
Parameter value can be set by rosparam set [parameter name] [parameter value];
You can view the parameter value through rosparam get [parameter name];
It can also be loaded into the parameter server through the rosparam tag in the launch file:
You can refer to the process of starting the move_base node by turtlebot's navigation. The parameters saved in the yaml file are loaded into the parameter server through the rosparam tag.
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<rosparam file="$(find turtlebot_navigation)/param/costmap_common_params.yaml" command="load" ns="global_costmap" />
<rosparam file="$(find turtlebot_navigation)/param/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find turtlebot_navigation)/param/local_costmap_params.yaml" command="load" />
<rosparam file="$(find turtlebot_navigation)/param/global_costmap_params.yaml" command="load" />
<rosparam file="$(find turtlebot_navigation)/param/dwa_local_planner_params.yaml" command="load" />
<rosparam file="$(find turtlebot_navigation)/param/move_base_params.yaml" command="load" />
<rosparam file="$(find turtlebot_navigation)/param/global_planner_params.yaml" command="load" />
<rosparam file="$(find turtlebot_navigation)/param/navfn_global_planner_params.yaml" command="load" />
<!-- external params file that could be loaded into the move_base namespace -->
<rosparam file="$(arg custom_param_file)" command="load" />
<!-- reset frame_id parameters using user input data -->
<param name="global_costmap/global_frame" value="$(arg global_frame_id)"/>
<param name="global_costmap/robot_base_frame" value="$(arg base_frame_id)"/>
<param name="local_costmap/global_frame" value="$(arg odom_frame_id)"/>
<param name="local_costmap/robot_base_frame" value="$(arg base_frame_id)"/>
<param name="DWAPlannerROS/global_frame_id" value="$(arg odom_frame_id)"/>
<remap from="cmd_vel" to="navigation_velocity_smoother/raw_cmd_vel"/>
<remap from="odom" to="$(arg odom_topic)"/>
<remap from="scan" to="$(arg laser_topic)"/>
</node>
2.1.3 Delete parameters
<rosparam command="delete" param="my/param" />
2.1.4 Direct assignment of parameters
<rosparam param="a_list">[1, 2, 3, 4]</rosparam>
or
<rosparam>
a: 1
b: 2
</rosparam>
2.2 Command line interface
This interface allows us to flexibly view and configure parameters through command line parameters.
example
$ rosparam list /namespace
$ rosparam get parameter_name
$ rosparam set parameter_name value
$ rosparam delete parameter_name
2.3 roscpp parameter interface
This interface allows us to customize how the ROS node handles parameters. There are two sets of roscpp parameter APIs: one set is in the ros::param namespace, the other set is encapsulated in the handle, and accessed through the ros::NodeHandle interface:
1. 为参数设置默认值
nh.param<<variable_type>>("<param_name>", variable, <default_value>);
ros::param::param<<variable_type>>("<param_name>", variable, <default_value>);
The function of the above code is to initialize the variable variable with the parameter named <param_name> and the value <default_value>.
2. Obtain a parameter value from the parameter server.
ros::NodeHandle::getParam("<param_name>", variable)
ros::param::get("<param_name>", variable)
The function of the above code is to obtain the value of the parameter named <param_name> from the parameter server, and assign it to the variable
cache to obtain
ros::NodeHandle::getParamCached() and ros::param::getCached() provide local caching of parameter data. Using these versions informs the Parameter Server that this node would like to be notified when the parameter is changed, and prevents the node from having to re-lookup the value with the parameter server on subsequent calls.
Cached parameters are a significant speed increase (after the first
call), but should be used sparingly to avoid overloading the master. Cached parameters are also currently less reliable in the case of intermittent connection problems between your node and the master.
Configuration parameter
ros::NodeHandle::setParam("<param_name>",<param_value>)
ros::param::set("<param_name>",<param_value>)
Assign the parameter <param_name> to <param_value>
Determine whether the parameter exists
ros::NodeHandle::hasParam("<param_name>")
ros::param::has("<param_name>")
Determine whether the parameter <param_name> exists
Delete parameter
ros::NodeHandle::deleteParam("<param_name>")
ros::param::del("<param_name>")
Delete parameter <param_name>
In the ROS code, we can also perform some parameter operations:
#include <ros/ros.h>
int main(int argc, char** argv)
{
ros::init(argc, argv, "param_demo");
ros::NodeHandle n;
ros::NodeHandle pn("~my_namespce");
std::string s;
int num;
n.param<std::string>("string_param", s, "haha");
pn.param<int>("int_param", num, 666);
//输出被初始化后的变量值
ROS_INFO("string_param_init: %s", s.c_str());
ROS_INFO("int_param_init: %d", num);
//设置参数的值
n.setParam("string_param", "hehe");
pn.setParam("int_param", 222);
//设置循环的频率为1Hz
ros::Rate loop_rate(1);
while(ros::ok())
{
//获取参数的值
n.getParam("string_param", s);
pn.getParam("int_param", num);
//输出参数
ROS_INFO("string_param: %s", s.c_str());
ROS_INFO("int_param: %d", num);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
After compiling, first use roscore to start ros, and then use rosrun to run the node. The result of the operation is:
[ INFO] [1508962647.123025215]: string_param_init: haha
[ INFO] [1508962647.123388114]: int_param_init: 666
[ INFO] [1508962647.126034003]: string_param: hehe
[ INFO] [1508962647.126118085]: int_param: 222
[ INFO] [1508962648.127348007]: string_param: hehe
[ INFO] [1508962648.127499096]: int_param: 222
[ INFO] [1508962649.129554752]: string_param: hehe
[ INFO] [1508962649.130092222]: int_param: 222
[ INFO] [1508962650.128275652]: string_param: hehe
[ INFO] [1508962650.128455601]: int_param: 222
[ INFO] [1508962651.127771182]: string_param: hehe
[ INFO] [1508962651.128003505]: int_param: 222
[ INFO] [1508962652.128101292]: string_param: hehe
[ INFO] [1508962652.128249473]: int_param: 222
[ INFO] [1508962653.127405633]: string_param: hehe
[ INFO] [1508962653.127529541]: int_param: 222
[ INFO] [1508962654.126999255]: string_param: hehe
[ INFO] [1508962654.127161917]: int_param: 222
[ INFO] [1508962655.129154583]: string_param: hehe
[ INFO] [1508962655.129287685]: int_param: 222
……
At this point, enter the command:
$ rosparam list
As you can see, the parameter already exists in the parameter server. The results are as follows:
/param_demo/my_namespce/int_param
/rosdistro
/roslaunch/uris/host_clp_virtual_machine__33415
/rosversion
/run_id
/string_param
Code explanation:
The default global namespace is used when defining the NodeHandle object n, and the private namespace is used when defining the NodeHandle object pn:
ros::init(argc, argv, "param_demo");
ros::NodeHandle n;
ros::NodeHandle pn("~my_namespce");
Therefore, "string_param" is a global parameter, and "int_param" is a parameter under the namespace my_namespace.
There are two lines of code next:
n.param<std::string>("string_param", s, "haha");
pn.param<int>("int_param", num, 666)
The official document describes the ros::NodeHandle::param() function as follows:
The param() function takes the parameter value from the parameter server to the variable. If it cannot be obtained, the default value is assigned to the variable. The function of this function is similar to the getParam() function, but the difference is that the param() function also provides a default value.
//设置参数的值
n.setParam("string_param", "hehe");
pn.setParam("int_param", 222);
Set the value of the parameter. If you comment these two lines of code, the rosparam list command will not see "string_param" and "int_param" because the parameter server does not set these two parameters.
n.getParam("string_param", s);
pn.getParam("int_param", num);
The getParam() function can obtain parameter values from the parameter server. If it succeeds, the values of the variables s and num will be modified to the parameter values, and the function returns true; if it is unsuccessful (for example, the parameter server does not set this parameter), the variables s and num will remain the original values and the function will return false.
Shut down the node that was run for the first time (do not shut down roscore), and then run the node for the second time. The result is:
[ INFO] [1508962846.716579651]: string_param_init: hehe
[ INFO] [1508962846.716882790]: int_param_init: 222
[ INFO] [1508962846.719913219]: string_param: hehe
[ INFO] [1508962846.720229965]: int_param: 222
[ INFO] [1508962847.721341491]: string_param: hehe
[ INFO] [1508962847.721696804]: int_param: 222
[ INFO] [1508962848.724312549]: string_param: hehe
[ INFO] [1508962848.724606197]: int_param: 222
[ INFO] [1508962849.723765176]: string_param: hehe
[ INFO] [1508962849.724541585]: int_param: 222
[ INFO] [1508962850.721549217]: string_param: hehe
[ INFO] [1508962850.722647030]: int_param: 222
[ INFO] [1508962851.722353260]: string_param: hehe
[ INFO] [1508962851.722608120]: int_param: 222
[ INFO] [1508962852.725476354]: string_param: hehe
[ INFO] [1508962852.726797059]: int_param: 222
[ INFO] [1508962853.723994285]: string_param: hehe
[ INFO] [1508962853.724691083]: int_param: 222
……
Comparing the results of the second run with the results of the first run, the values of string_param_init and int_param_init have changed. This is because after running the node for the first time, the parameters string_param and num_param already exist in the parameter server, so when the node is run for the second time, the default values "haha" and "666" will not be used, so the output result is "hehe" "And 222.
In addition, when the node is running, we use the rosparam set command to modify the value of the parameter, and we can observe the change of the output value.
Original link:
https://blog.csdn.net/wanghuiquan0712/article/details/78763144
https://blog.csdn.net/u014695839/article/details/78348600
https://blog.csdn.net/wengge987/article/details/50620121