ROS launch

简介

如果rosrun是执行一个节点的命令,那么roslaunch是运行多个节点的概念。该命令允许运行多个确定的节点。其他功能还包括一些专为执行具有诸多选项的节点的ROS命令,比如包括更改功能包参数或节点名称、配置节点命名空间、设置ROS_ROOTROS_PACKAGE_PATH以及更改环境变量等。

roslaunch使用*.launch文件来设置可执行节点,它基于可扩展标记语言(XML),并提供XML标记形式的多种选项。像许多ROS包会有相应的启动配置,通过运行下面的指令来进行启动

roslaunch package_name file.launch

XML

计算次序

roslaunch与XML文件单一传递。include是按照深度优先遍历的顺序处理。标签tag进行串行处理并且最后的设置有效。因此,若一个参数被多次设置,最后指定的值将被使用。 比较推荐的是使用$(arg)/<arg>设置来进行重写行为。

替代参数(Substitution args)

launch文件支持替代参数,roslaunch将在启动节点之前对其进行解析。当前支持的替代参数有:

1) $(env ENVIRONMENT_VARIABLE):用环境变量替换变量的值。如果未设置环境变量,则启动将失败。此值不能被标记覆盖。

2) $(optenv ENVIRONMENT_VARIABLE):如果设置了环境变量的值,则替换该值。若提供default_value,则在未设置环境变量的情况下使用default_value。若未提供default_value,则将使用空字符串。default_value可以是多个单词,并用空格分隔。

例如:

<param name="foo" value="$(optenv NUM_CPUS 1)" />
<param name="foo" value="$(optenv CONFIG_PATH /home/marvin/ros_workspace)" />
<param name="foo" value="$(optenv VARIABLE ros rocks)" />

NUM_CPUS的default_value为1;VARIABLE的default_value为ros和rocks。

3) $(find pkg): 指定相对于软件包的路径。

例如:查找rospy子目录下的manifest.xml文件。

$(find rospy)/manifest.xml

4) $(anon name):根据名称生成匿名id,id不能重名。例如:

<node name="$(anon foo)" pkg="rospy_tutorials" type="talker.py" />

5) $(eval ):用于计算任意复杂的python表达式。例如:

<param name="circumference" value="$(eval 2.* 3.1415 * arg('radius'))"/>

6) $(dirname):返回启动文件所在目录的绝对路径。例如:

<include file="$(dirname)/other.launch" />

file指向当前launch文件所在目录下的other.launch文件。

7) $(arg foo): 计算由标签指定的值,在声明arg的同一启动文件中必须有对应的标签。例如

<param name="foo" value="$(arg my_foo)" />

将指定 my_foo 到 foo 参数, 另外一个例子:

<node name="add_two_ints_server" pkg="beginner_tutorials" type="add_two_ints_server" />

<node name="add_two_ints_client" pkg="beginner_tutorials" type="add_two_ints_client" args="$(arg a) $(arg b)" />

将会从 例子中启动server和client,作为参数值a和传递。产生的启动项目能用如下语句调用:

roslaunch beginner tutorials launch_file.launch a:=1 b:=5

If和unless属性

所有标签都支持if和unless属性,这些属性基于值的评估包含或不包含在标签内。 “ 1”和“ true”被视为真实值。 “ 0”和“ false”被视为错误值。 其他值将出错。

if=value (optional):如果value评估为true,则包含标记及其内容。
unless=value (optional):如果value的值为false,则包含标记及其内容。

<group if="$(arg foo)">
<!-- 此处的代码仅当foo为true时才被读取 -->
</group>

<!-- 满足unless条件时不会设置此参数 -->
<param name="foo" value="bar" unless="$(arg foo)" />

launch文件案例

简单案例

以下案例具备最基本的启动文件配置。它启动一个单独的“talker”节点,该节点是“rospy_tutorials”软件包的一部分。 该节点将使用当前配置的ROS环境(即ROS_ROOT等)在本地计算机上启动。

<launch>
<node name="talker" pkg="rospy_tutorials" type="talker" />
</launch>

重映射机制

ROS提供一种重映射的机制,简单来说就是取别名,类似于C++中的别名机制,不需要修改别人功能包的接口,只需要将接口名称重映射一下,取个别名。launch文件中的标签可以帮我们实现这个重映射的功能。 比如turtlebot的键盘控制节点,发布的速度控制指令话题可能是/turtlebot/cmd_vel,但是我们自己的机器人订阅的速度控制话题是/cmd_vel,这个时候使用remap就可以轻松解决问题,将/turtlebot /cmd_vel重映射为/cmd_vel,机器人就可以接收到速度控制指令了:

<remap from="/turtlebot/cmd_vel"to="/cmd_vel"/>

重映射机制在ROS中的使用非常广泛,也非常重要,方法不止这一种,也可以在终端rosrun命令中实现重映射;

复杂案例

<launch>
<!-- local machine already has a definition by default.
This tag overrides the default definition with
specific ROS_ROOT and ROS_PACKAGE_PATH values -->
<machine name="local_alt" address="localhost" default="true" ros-root="/user/ros/" ros-package-path="/user/ros/ros-pkg" />
<!-- a basic listener node -->
<node name="listener-1" pkg="rospy_tutorials" type="listener" />
<!-- pass args to the listener node -->
<node name="listener-2" pkg="rospy_tutorials" type="listener" args="-foo arg2" />
<!-- a respawn-able listener node -->
<node name="listener-3" pkg="rospy_tutorials" type="listener" respawn="true" />
<!-- start listener node in the 'wg1' namespace -->
<node ns="wg1" name="listener-wg1" pkg="rospy_tutorials" type="listener" respawn="true" />
<!-- start a group of nodes in the 'wg2' namespace -->
<group ns="wg2">
<!-- remap applies to all future statements in this scope. -->
<remap from="chatter" to="hello"/>
<node pkg="rospy_tutorials" type="listener" name="listener" args="--test" respawn="true" />
<node pkg="rospy_tutorials" type="talker" name="talker">
<!-- set a private parameter for the node -->
<param name="talker_1_param" value="a value" />
<!-- nodes can have their own remap args -->
<remap from="chatter" to="hello-1"/>
<!-- you can set environment variables for a node -->
<env name="ENV_EXAMPLE" value="some value" />
</node>
</group>
</launch>

参数服务器

可以在参数服务器上设置参数,这些参数将在启动任何节点之前存储在参数服务器上。如果值是明确的,则可以省略type属性。支持的类型为str,int,double,bool。例子如下

<launch>
<param name="somestring1" value="bar" />
<!-- force to string instead of integer -->
<param name="somestring2" value="10" type="str" />

<param name="someinteger1" value="1" type="int" />
<param name="someinteger2" value="2" />

<param name="somefloat1" value="3.14159" type="double" />
<param name="somefloat2" value="3.0" />

<!-- you can set parameters in child namespaces -->
<param name="wg/childparam" value="a child namespace parameter" />

<!-- upload the contents of a file to the server -->
<param name="configfile" textfile="$(find roslaunch)/example.xml" />
<!-- upload the contents of a file as base64 binary to the server -->
<param name="binaryfile" binfile="$(find roslaunch)/example.xml" />

</launch>

参考

[1]. 《ROS机器人编程—从基本概念到机器人应用程序编程实战》

[2]. ROS入门(二):launch文件解析

[3]. ROS探索总结(五十六)—— launch文件

CMakeLists Eigen FCPX GNU Gazebo Git Interest KDL Life Linux Matrix ODE ROS Ros UML Ubuntu VcXsrv algorithm algorithms axis-angle bode calibration chrome control cpp data_struct dots figure gdb latex launch life linux mac math matlab memory motor moveit operator optimal algorithm python robot robotics ros ros2 rtb simulation stl thread tools twist urdf velocity vim web work wsl
知识共享许可协议