ROS高级组件之 launch 文件
1 资料
从本文开始,我们学习ros进阶课程。之前,我们完成了ros入门课程的学习,见 ROS高效入门系列。入门学习的侧重点是ros本身的基础组件学习,不涉及任何算法。而从本文开始,我们将基于ros,学习机器人建模和仿真,以及机器人相关的各种算法。最终能在仿真环境下,完成整个机器人系统的搭建和测试。
本文是ros进阶系列第一章的第一节,讲解复杂的launch文件。搞机器人的都知道,好多算法和模型都已经很成熟了,不怎么写代码,而主要是写launch文件。
本文参考资料如下:
(1)ROS高效入门系列博客:ROS高效入门第二章 – 基本概念和常用命令学习,基于小乌龟样例
(2)古月居:ROS探索总结-54.launch文件
(3)《机器人操作系统(ROS)浅析》[美] Jason M. O’Kane 著 肖军浩 译 第六章
(4)ros Tutorials : 使用rqt_console和roslaunch
(5)ros Tutorials : Roslaunch在大型项目中的使用技巧
本系列博客汇总:ROS高效进阶系列。
2 正文
在 ROS高效入门系列 博客中,我为各个样例编写了launch启动文件,这种启动方式,不需要单独启动节点管理器,而且能一把拉起来多个节点,省时省力。
2.1 简单点的launch
(1)创建 learning_launch软件包以及相关文件
cd ~/catkin_ws/src
catkin_create_pkg learning_launch rospy roscpp
cd learning_launch
mkdir config
touch config/param.yaml
mkdir launch
touch launch/mimic_draw_cycle.launch launch/mimic_draw_square.launch launch/double_mimic_draw_cycle_square.launch
(2)mimic_draw_cycle.launch
该样例基于turtlesim,创建两个 turtlesim_node,并使他们一起画圆。该样例还使用了 turtlesim 的 mimic,其能使一个 turtlesim_node 的行为跟随另一个。
注释中提到了计算图源名称的概念,具体可以参考:ROS高效入门第三章 – 自定义ROS消息,编写C++ pub+sub样例,理解计算图源名称
<launch> // <launch>和</launch>标签是launch文件的起止
// <group>是组标签,group使用命名空间 ns 区分
// 两个 turtlesim_node 分为位于各自的group内,其名称会使用命名空间进行区分
<group ns="turtlesim1">
// <node> 用于启动节点
// pkg:节点所在的软件包
// name: 节点运行时名称
// type: 节点的可执行文件名称
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
<group ns="turtlesim2">
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
<node pkg="turtlesim" name="mimic" type="mimic">
// <remap>重映射ros的计算图源名称
// 这句是把 mimic 的带 input 的计算图源,一律改为带 turtlesim1/turtle1,其实主要是几个 topic 名的改动
// 这说明<remap>不一定需要写全计算图源名称
<remap from="input" to="turtlesim1/turtle1"/>
<remap from="output" to="turtlesim2/turtle1"/>
</node>
<node
// required 表示这个节点对于整个系统是必不可少的,一旦挂了,系统将整体推出
// args 用于向节点传递参数
pkg="rostopic" type="rostopic" name="rostopic" required="true"
args="pub /turtlesim1/turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'"
/>
</launch>
运行结果
(3)mimic_draw_square.launch
该样例基于turtlesim,创建两个 turtlesim_node,并使他们一起画正方形。该样例也使用了 turtlesim 的 mimic。
<launch>
<group ns="turtlesim1">
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
<group ns="turtlesim2">
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
<node pkg="turtlesim" name="mimic" type="mimic">
<remap from="input" to="turtlesim1/turtle1"/>
<remap from="output" to="turtlesim2/turtle1"/>
</node>
<node pkg="turtlesim" type="draw_square" name="draw_square_cmd" required="true">
// 这里把topic进行了重映射,不然下游的 turtlesim_node 和 mimic 收不到
<remap from="/turtle1/cmd_vel" to="/turtlesim1/turtle1/cmd_vel"/>
<remap from="/turtle1/pose" to="/turtlesim1/turtle1/pose"/>
</node>
</launch>
运行结果
2.2 比较复杂的launch
double_mimic_draw_cycle_square 是把上面2.1的两个例子合并成一个,用一个launch文件把他们拉起来。这个样例主要使用了 launch 的 include 和全局参数设置功能,对于复杂的 launch,这两项是必须的。
全局参数的概念看:ROS高效入门第二章 – 基本概念和常用命令学习,基于小乌龟样例
计算图源名称的概念看:ROS高效入门第三章 – 自定义ROS消息,编写C++ pub+sub样例,理解计算图源名称
(1)double_mimic_draw_cycle_square.launch
<launch>
<group ns="turtlesim1">
// <include>标签的功能就跟C语言的一样,将子文件原地展开
// $(find learning_launch)是在ros的全局路径中,找到learning_launch包
<include file="$(find learning_launch)/launch/two_turtlesim.launch"/>
</group>
<group ns="turtlesim2">
<include file="$(find learning_launch)/launch/two_turtlesim.launch"/>
</group>
<node
pkg="rostopic" type="rostopic" name="rostopic" output="screen" required="true"
args="pub /turtlesim1/sim_node1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'"
/>
<node pkg="turtlesim" type="draw_square" name="draw_square_cmd" output="screen" required="true">
<remap from="/turtle1/cmd_vel" to="/turtlesim2/sim_node1/cmd_vel"/>
<remap from="/turtle1/pose" to="/turtlesim2/sim_node1/pose"/>
// <rosparam>标签,支持通过yaml文件,批量设置参数,这里是给当前node设置
<rosparam file="$(find learning_launch)/config/param.yaml" command="load"/>
</node>
</launch>
(2)two_turtlesim.launch
<launch>
// <param>标签用于设置单个参数
<param name="turtle_number" value="2"/>
// <arg>标签用于定于launch中的变量,供后面使用,与<node>的args区分!
<arg name="TurtlesimName1" default="Tom"/>
<arg name="TurtlesimName2" default="Jerry"/>
// <node>的respawn表示当前节点如果挂了,会被自动拉起来,即可重启
<node pkg="turtlesim" type="turtlesim_node" name="sim_node1" respawn="true">
<remap from="turtle1" to="sim_node1"/>
// 使用 arg 变量,设置节点参数
<param name="turtle_name" value="$(arg TurtlesimName1)"/>
</node>
<node pkg="turtlesim" type="turtlesim_node" name="sim_node2" respawn="true">
<remap from="turtle1" to="sim_node2"/>
<param name="turtle_name" value="$(arg TurtlesimName2)"/>
</node>
<node pkg="turtlesim" name="mimic" type="mimic" output="screen" required="true" >
<remap from="input" to="sim_node1"/>
<remap from="output" to="sim_node2"/>
</node>
</launch>
(3)param.yaml
param_a: 123
param_b: "ycao"
test_group:
param_c: 456
param_d: "miao"
(4)编译并运行
查看设置的全局参数
3 总结
ros Tutorials 给出了几个 大型launch文件的编写技巧:Roslaunch在大型项目中的使用技巧,后面会逐步体会。
本文的样例托管在本人的github上:learning_launch