ROS高效进阶第一章 -- 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在大型项目中的使用技巧

2 正文

ROS高效入门系列 博客中,我为各个样例编写了launch启动文件,这种启动方式,不需要单独启动节点管理器,而且能一把拉起来多个节点,省时省力。

2.1 简单点的launch

(1)创建 learning_launch软件包以及相关文件

cd ~/catkin_ws/src
catkin_create_pkg learning_launch rospy roscpp

cd beginner_tutorials
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,这两项是必须的。
(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

猜你喜欢

转载自blog.csdn.net/cy1641395022/article/details/131220943