前言
在任何机器人系统中,参数传递都是一个十分重要的功能,不论是传感器的设置,还是控制参数的调整,都需要留出方便的参数调试接口,有的参数只在启动程序启动时更改,有的参数却希望在运行时能够被动态修改,在ROS中,可以通过参数服务来实现上面的想法。
命令行工具
首先熟悉一下rosparam指令,用rosparam -h可以获得如下帮助
用上面几个指令可以方便地用命令行获得或更改参数。
参考代码
下面通过一段简单的代码片段来熟悉一下如何向ROS程序传递参数
代码分析
我们来分析一下上面的代码片段,首先是参数的初始化
上面的代码表示名称为”string_param”,值为”default_string”的参数初始化化std::string 类型变量s,用名称为”int_param”,值为666的参数初始化std::int类型变量num。
|
|
这两句代码是设置参数的值,如果程序中注释掉这两句代码,会产生这样的后果:
每次新开启机器时,第一次运行这个节点,s和num的值为我们设置的默认值,但是如果我们用rosparam set指令修改对应参数的值时,参数的值会保存在参数服务器中,默认的初始化值就不在有效,也就是说重新启动这个节点,参数值一直都是修改后的值。
另外注释掉这两句代码,运行节点时用rosparam list是查看不到”string_param”和”int_param”两个参数的,并且对这两个参数用rosparam get是无效的,但rosparam set仍然有效,可能会带来一些不方便。
如果不注释这两句代码,则运行节点时用rosparam list可以在参数列表中看到”string_param”和”int_param”两个参数,同样可以使用get和set指令。但会带来一个问题,就是不管用rosparam set指令将参数设为何值,重新运行节点时参数都被初始化位以上两句代码中给定的值。
所以两种方法各有优缺点,分场合使用,或者可以使用更方便的launch文件来配置参数,下文将会提到。
|
|
从参数服务器中读取参数值并显示,可以用rosparam set指令更改参数值。
现在留意一下这个定义
私有节点的定义可以参考http://wiki.ros.org/roscpp/Overview/NodeHandles
私有节点在参数传递中十分有用,通常我们定义的普通节点是全局的,这样在多个节点具有相同名称的参数时将会产生问题,设想这样一种情况,两个不同的传感器但是都具有一个名为”frequerncy”的参数,当我们用rosparam set将它设置为10hz时,可能会影响到我们并不想配置的那个传感器。所以,我们用私有节点来解决这个问题。私有节点实际上就是给节点指定了它所在的命名空间。例如,我们可以用rosparam list指令查看这个节点中的参数,可以看到
|
|
如果私有节点定义为
|
|
则会看到
|
|
在上文提到的参数初始化方式中,如果在程序中给定默认值,则想要改变默认值将需要重新编译程序,如果要频繁更改参数的话这种方式就十分不方便,我们还可以在launch文件中对参数进行设置,避免这个麻烦,参考以下示例
|
|
不过在使用中要注意的是,似乎不能对全局节点和私有节点的参数同时初始化,所有尽量都使用私有节点来传递参数。
用launch文件初始化参数的优势是明显的,可以不查看源程序就可以知道节点用到的参数以及给定的初始值,并且找到一个合适的参数后,可以将它保存到launch文件而不必修改和重新编译源程序。