1. Significado do uso
O uso do servidor de parâmetros é projetado para melhorar a flexibilidade e configurabilidade dos nós ROS, e sua importância pode ser entendida a partir de dois aspectos:
No sistema do robô, a transmissão dos parâmetros é muito importante.Quando o robô está funcionando, precisamos definir os parâmetros do robô (como parâmetros do sensor e parâmetros do algoritmo). Alguns parâmetros (como o contorno do robô, a altura do sensor) podem ser definidos quando o robô é iniciado e alguns parâmetros precisam ser alterados dinamicamente (especialmente durante a depuração). Quer seja a configuração do sensor ou o ajuste dos parâmetros de controle, uma interface de depuração de parâmetro conveniente precisa ser reservada. ROS fornece um servidor de parâmetros para atender a este requisito, podemos definir os parâmetros no servidor de parâmetros e obtê-los do servidor de parâmetros quando os parâmetros são necessários. O uso do servidor de parâmetros para configurar os parâmetros do sistema é globalmente visível, o que é conveniente para nós recuperar e alterar o status de configuração do sistema.
O servidor de parâmetros fornece outra forma de troca de informações entre nós ROS (os métodos comumente usados também são mensagens e serviços). A ideia principal é usar um servidor de parâmetros centralizado (servidor de parâmetros) para manter o valor de um conjunto de variáveis, e o nó pode consultar ativamente o valor do parâmetro de interesse.
O comando rosparam pode operar os parâmetros no servidor de parâmetros ROS. Por meio do comando rosparam -h, você pode ver os seguintes métodos:
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 pontos
ROS nos fornece interface roslaunch .launch, interface de linha de comando, interface roscpp e interface rospy para parâmetros operacionais. Os principais pontos de uso são os seguintes:
2.1 interface roslaunch .launch
Esta interface é usada para configurar os parâmetros na inicialização. As vantagens de usar o arquivo de inicialização para configurar os parâmetros: 1. Você pode saber os parâmetros usados pelo nó e o valor inicial fornecido sem visualizar o programa de origem; 2. Para modificar o valor inicial do parâmetro, você pode salvá-lo em o arquivo de inicialização sem modificar e recompilar o programa de origem.
2.1.1 Use <param>
tags para definir parâmetros diretamente
<param name="publish_frequency" type="double" value="10.0" />
Use tags para <rosparam>
configurar parâmetros
2.1.2 Parâmetros de leitura do arquivo YAML:
Geralmente, podemos salvar os parâmetros que precisam ser definidos em um arquivo yaml e usar o comando rosparam load [caminho do arquivo \ nome do arquivo] para carregar vários parâmetros no servidor de parâmetros de uma vez.
Por exemplo, um arquivo de parâmetro denominado param.yaml, o conteúdo é:
#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
Parâmetros de carga no terminal:
$ rosparam load param.yaml
Em seguida, digite o comando:
$ rosparam list
Como você pode ver, todos os parâmetros foram carregados:
/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
O valor do parâmetro pode ser definido por rosparam set [nome do parâmetro] [valor do parâmetro];
Você pode visualizar o valor do parâmetro por meio de rosparam get [nome do parâmetro];
Ele também pode ser carregado no servidor de parâmetros por meio da tag rosparam no arquivo de inicialização:
Você pode consultar o processo de navegação do turtlebot para iniciar o nó move_base. Os parâmetros salvos no arquivo yaml são carregados no servidor de parâmetros por meio da tag rosparam.
<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 Excluir parâmetros
<rosparam command="delete" param="my/param" />
2.1.4 Atribuição direta de parâmetros
<rosparam param="a_list">[1, 2, 3, 4]</rosparam>
ou
<rosparam>
a: 1
b: 2
</rosparam>
2.2 Interface de linha de comando
Essa interface nos permite visualizar e configurar parâmetros de maneira flexível por meio de parâmetros de linha de comando.
exemplo
$ rosparam list /namespace
$ rosparam get parameter_name
$ rosparam set parameter_name value
$ rosparam delete parameter_name
2.3 interface de parâmetro roscpp
Essa interface nos permite personalizar como o nó ROS trata os parâmetros. Existem dois conjuntos de APIs de parâmetro roscpp: um conjunto está no namespace ros :: param, o outro conjunto é encapsulado no identificador e acessado por meio da interface ros :: NodeHandle:
1. 为 参数 设置
默认值nh.param <<variable_type>> ("<param_name>", variável, <default_value>);
ros :: param :: param <<variable_type>> ("<param_name>", variável, <default_value>);
A função do código acima é inicializar a variável variável com o parâmetro denominado <param_name> e o valor <default_value>.
2. Obtenha um valor de parâmetro do servidor de parâmetro.
ros :: NodeHandle :: getParam ("<param_name>", variável)
ros :: param :: get ("<param_name>", variável)
A função do código acima é obter o valor do parâmetro denominado <param_name> do servidor de parâmetro e atribuí-lo ao
cache de variável para obter
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.
Parâmetro de configuração
ros::NodeHandle::setParam("<param_name>",<param_value>)
ros::param::set("<param_name>",<param_value>)
Atribua o parâmetro <param_name> a <param_value>
Determine se o parâmetro existe
ros::NodeHandle::hasParam("<param_name>")
ros::param::has("<param_name>")
Determine se o parâmetro <param_name> existe
Excluir parâmetro
ros::NodeHandle::deleteParam("<param_name>")
ros::param::del("<param_name>")
Excluir parâmetro <param_name>
No código ROS, também podemos realizar algumas operações de parâmetro:
#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;
}
Depois de compilar, primeiro use o roscore para iniciar o ros e, em seguida, use o rosrun para executar o nó. O resultado da operação é:
[ 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
……
Neste ponto, digite o comando:
$ rosparam list
Como você pode ver, o parâmetro já existe no servidor de parâmetros. Os resultados são os seguintes:
/param_demo/my_namespce/int_param
/rosdistro
/roslaunch/uris/host_clp_virtual_machine__33415
/rosversion
/run_id
/string_param
Explicação do código:
O namespace global padrão é usado ao definir o objeto NodeHandle n, e o namespace privado é usado ao definir o objeto NodeHandle pn:
ros::init(argc, argv, "param_demo");
ros::NodeHandle n;
ros::NodeHandle pn("~my_namespce");
Portanto, "string_param" é um parâmetro global e "int_param" é um parâmetro no namespace my_namespace.
Existem duas linhas de código a seguir:
n.param<std::string>("string_param", s, "haha");
pn.param<int>("int_param", num, 666)
O documento oficial descreve a função ros :: NodeHandle :: param () da seguinte maneira:
A função param () leva o valor do parâmetro do servidor de parâmetro para a variável. Se não puder ser obtido, o valor padrão é atribuído à variável. A função dessa função é semelhante à função getParam (), mas a diferença é que a função param () também fornece um valor padrão.
//设置参数的值
n.setParam("string_param", "hehe");
pn.setParam("int_param", 222);
Defina o valor do parâmetro. Se você comentar essas duas linhas de código, o comando rosparam list não verá "string_param" e "int_param" porque o servidor de parâmetro não define esses dois parâmetros.
n.getParam("string_param", s);
pn.getParam("int_param", num);
A função getParam () pode obter valores de parâmetro do servidor de parâmetro. Se for bem-sucedido, os valores das variáveis s e num serão modificados para os valores dos parâmetros, e a função retornará verdadeiro; se não for bem-sucedida (por exemplo, o servidor de parâmetro não define este parâmetro), as variáveis s e num permanecerá com os valores originais e a função retornará falso.
Desligue o nó que foi executado pela primeira vez (não desligue o roscore) e, em seguida, execute o nó pela segunda vez. O resultado é:
[ 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
……
Comparando os resultados da segunda execução com os resultados da primeira execução, os valores de string_param_init e int_param_init mudaram. Isso ocorre porque depois de executar o nó pela primeira vez, os parâmetros string_param e num_param já existem no servidor de parâmetros, então quando o nó for executado pela segunda vez, os valores padrão "haha" e "666" não serão usado, então o resultado de saída é "hehe" "E 222.
Além disso, quando o nó está em execução, usamos o comando rosparam set para modificar o valor do parâmetro e podemos observar a mudança do valor de saída.
Link original:
https://blog.csdn.net/wanghuiquan0712/article/details/78763144
https://blog.csdn.net/u014695839/article/details/78348600
https://blog.csdn.net/wengge987/article/details/50620121