多无人车协同探索开源包启动文件介绍(上)
在之前介绍的《多无人车协同探索开源包部署教程及常见报错解决方式》中运行多无人车协同探索时,先后运行了两个launch文件 multiple_tb3_house.launch 和three_robots.launch ,本文来进一步看一下这两个启动文件以及其调用的move_base .launch 和multi_tb3_mapmerge.launch 都做哪些操作以及如何根据自己的需要进行相应的修改。
由于内容较多,拆分成(上)、(下)两篇博客,链接如下:
多无人车协同探索开源包启动文件介绍(上)
多无人车协同探索开源包启动文件介绍(下)
一、multiple_tb3_house.launch 详细介绍
multiple_tb3_house.launch用于启动一个包含三个TurtleBot3机器人的多机器人系统,并在Gazebo仿真环境中运行。下面是对各个部分的详细解释:
1. 参数定义(Arguments)
<arg name="model" default="waffle_pi" doc="model type [burger, waffle, waffle_pi]"/>
<arg name="move_forward_only" default="false"/>
<arg name="configuration_basename" default="turtlebot3_lds_2d.lua"/>
- 这些
<arg>
元素定义了可以传递给启动文件的参数。 model
:指定机器人模型的类型(如burger
、waffle
或waffle_pi
)。move_forward_only
:一个布尔值参数,用于控制机器人是否只能前进(默认为false
)。configuration_basename
:用于配置机器人的激光雷达(Lidar)设置的Lua文件。
2. TurtleBot3机器人初始位姿配置
每个机器人都通过多个<arg>
元素来定义其名称、位置和方向:
<arg name='third_tb3' default="tb3_0"/>
<arg name="third_tb3_x_pos" default=" 0.9"/>
<arg name="third_tb3_y_pos" default=" 3.3"/>
<arg name="third_tb3_z_pos" default=" 0.0"/>
<arg name="third_tb3_yaw" default=" 0.0"/>
<arg name='first_tb3' default="tb3_1"/>
<arg name="first_tb3_x_pos" default="0.9"/>
<arg name="first_tb3_y_pos" default=" 1.7"/>
<arg name="first_tb3_z_pos" default=" 0.0"/>
<arg name="first_tb3_yaw" default=" 0.0"/>
<arg name='second_tb3' default="tb3_2"/>
<arg name="second_tb3_x_pos" default=" 0.9"/>
<arg name="second_tb3_y_pos" default=" 2.5"/>
<arg name="second_tb3_z_pos" default=" 0.0"/>
<arg name="second_tb3_yaw" default=" 0.0"/>
- 这些参数分别定义了三个机器人的名称和位置(
x
、y
、z
坐标)以及航向(yaw
角度)。
-----------------------------------------------☆☆☆常改动参数☆☆☆-----------------------------------------------------
这组参数用于设定机器人的初始位姿,是经常用到的需要修改的参数之一,下面动图的实例中,我将tb3_0机器人的初始位置的x和y坐标从0.9,3.3 改到了 5.9,1.3,可以看到该机器人的初始位置发生了改变
-----------------------------------------------------------------------------------------------------------------------------------------
3. Gazebo仿真环境配置
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find ros_multi_tb3)/worlds/turtlebot3_house_mod.world"/>
<arg name="paused" value="false"/>
<arg name="use_sim_time" value="true"/>
<arg name="gui" value="false"/>
<arg name="headless" value="false"/>
<arg name="debug" value="false"/>
</include>
- 这一部分中的
empty_world.launch
文件,一般是默认的,会根据传递的参数自动启动 Gazebo 的服务器和客户端(gzserver 和 gzclient),不需要修该。 world_name
用于启动Gazebo仿真环境并加载一个自定义的世界文件(turtlebot3_house_mod.world
)。- 启用了仿真时间(
use_sim_time="true"
),并且禁用了图形界面(gui="false"
)。
-----------------------------------------------☆☆☆常改动参数☆☆☆-----------------------------------------------------
这组参数中最常改动的参数是用于设定加载的仿真环境文件的world_name参数,下面动图的实例中,我将项目默认的仿真环境文件,换成了我之前创建的放在功能包racecar_description的worlds文件夹下的名为complex.world的文件,效果如下所示
下面的例子中将
<arg name="world_name" value="$(find ros_multi_tb3)/worlds/turtlebot3_house_mod.world"/>
改为了
<arg name="world_name" value="$(find racecar_description)/worlds/complex.world"/>
这组参数中的gui参数有时候也需要根据需求进行修该,项目默认给定的值是false,这意味着 Gazebo 启动时不会显示图形界面(即使有 gzclient 启动)即看不到gazebo的界面,这样做主要是为了节省计算资源。如果你希望将 Gazebo 的可视化界面显示出来,应该将 gui 设置为 true
-----------------------------------------------------------------------------------------------------------------------------------------
4. 设定机器人模型和状态发布(每个机器人)
每个机器人都有一个<group>
部分,包含以下几个关键组件:
<group ns = "$(arg first_tb3)">
-
URDF描述:加载机器人的描述文件(
.xacro
文件),定义机器人模型。<param name="robot_description" command="$(find xacro)/xacro $(find ros_multi_tb3)/urdf/turtlebot3_waffle_pi.urdf.xacro botname:=$(arg first_tb3)" />
-
机器人状态发布器:将机器人的状态信息(如关节状态)发布到ROS网络中。
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" output="screen"> <param name="publish_frequency" type="double" value="50.0" /> <param name="tf_prefix" value="$(arg first_tb3)" /> </node>
-
模型生成:在Gazebo中生成机器人模型,设置其位置(
x
、y
、z
)和航向(yaw
)。<node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-urdf -model $(arg first_tb3) -x $(arg first_tb3_x_pos) -y $(arg first_tb3_y_pos) -z $(arg first_tb3_z_pos) -Y $(arg first_tb3_yaw) -param robot_description" />
-----------------------------------------------☆☆☆关于命名空间ns☆☆☆-----------------------------------------------
在 ROS (Robot Operating System) 中,ns
是命名空间 (namespace) 的缩写。它用于对 ROS系统中的节点、话题、参数等进行分组和命名。通过使用命名空间,可以避免在多机器人系统中出现命名冲突,使得每个机器人的资源可以独立管理。
xml <group ns = "$(arg first_tb3)">
上面这行代码表示将该
group
中的所有节点、参数等,都放入first_tb3
命名空间内。作用如下:(1) 避免命名冲突 在多机器人系统中,每个机器人可能有相同的资源(例如:
cmd_vel
、odom
、base_footprint
等),这些资源的名字会冲突。使用命名空间可以确保每个机器人的话题、服务等在名称上是唯一的。例如:
- 对于机器人
tb3_0
,cmd_vel
话题可能是/tb3_0/cmd_vel
- 对于机器人
tb3_1
,cmd_vel
话题可能是/tb3_1/cmd_vel
这样,即使它们的名字相同,命名空间的使用使得它们在 ROS 系统中是独立的。(2) 自动为节点和话题加前缀 在
group
标签中使用ns
后,ROS 会自动将该命名空间加到所有节点、话题、参数等的名称前缀。例如对第一个机器人而言:
robot_state_publisher
的节点名称将是/first_tb3/robot_state_publisher
spawn_model
的模型名称将是/first_tb3/spawn_model
cmd_vel
话题的名称将是/first_tb3/cmd_vel
slam_gmapping
的参数base_frame
会变成/first_tb3/base_footprint
这确保了不同机器人的节点和话题在系统中是独立的。(3)参数和话题的作用域控制 命名空间也控制了参数和话题的作用域。比如说,当你发布一个话题或设置一个参数时,它会根据命名空间确定话题的前缀或者参数的路径,从而确保同一系统中的多个机器人不会干扰彼此。
总的来说:
ns
将该组节点、话题和参数放入一个特定的命名空间中,使得它们可以在多机器人系统中区分开来。通过命名空间的使用,可以避免话题、参数或节点名的冲突。
----------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------☆☆☆常改动参数☆☆☆-----------------------------------------------------
这组参数中的robot_description参数用于设定加载机器人模型描述文件(.xacro
文件),如果需要改用其他机器人模型,则需要对该参数进行修改
-----------------------------------------------------------------------------------------------------------------------------------------
5. SLAM(同步定位与建图)配置
对于每个机器人,都有一个gmapping
节点来进行2D SLAM操作,并加载一个配置文件(gmapping_params.yaml
),如果想要修改gmapping建图的相关参数,可以对gmapping_params.yaml
文件进行修改
<node pkg="gmapping" type="slam_gmapping" name="turtlebot3_slam_gmapping" output="screen">
<param name="base_frame" value="$(arg first_tb3)/base_footprint"/>
<param name="odom_frame" value="$(arg first_tb3)/odom"/>
<param name="map_frame" value="$(arg first_tb3)/map"/>
<rosparam command="load" file="$(find ros_multi_tb3)/configuration/gmapping_params.yaml" />
</node>
6. 机器人运动控制(Move Base)
每个机器人都有一个move_base
节点,用于运动规划和控制。它接收来自cmd_vel
话题的指令,并在机器人的命名空间下操作,这里move_base
节点是通过move_base.launch文件进行配置的,该部分内容将在第二部分中进行展开介绍:
<include file="$(find ros_multi_tb3)/launch/includes/move_base.launch">
<arg name="model" value="$(arg model)" />
<arg name="move_forward_only" value="$(arg move_forward_only)"/>
<arg name="cmd_vel_topic" value="/$(arg first_tb3)/cmd_vel"/>
<arg name="namespace" value="$(arg first_tb3)"/>
</include>
7. 地图合并
通过一个单独的启动文件(multi_tb3_mapmerge.launch
)来合并所有机器人生成的地图,该部分内容将在本文第三部分中进行介绍,这里主要是将三个机器人的名字和初始位姿参数传入了multi_tb3_mapmerge.launch
文件中。
<include file="$(find ros_multi_tb3)/launch/includes/multi_tb3_mapmerge.launch">
<arg name="model" value="$(arg model)" />
<arg name="move_forward_only" value="$(arg move_forward_only)"/>
<arg name="first_tb3" value="$(arg first_tb3)"/>
<arg name="second_tb3" value="$(arg second_tb3)"/>
<arg name="third_tb3" value="$(arg third_tb3)"/>
<arg name="first_tb3_x_pos" default="$(arg first_tb3_x_pos)"/>
<arg name="first_tb3_y_pos" default="$(arg first_tb3_y_pos)"/>
<arg name="first_tb3_z_pos" default="$(arg first_tb3_z_pos)"/>
<arg name="first_tb3_yaw" default="$(arg first_tb3_yaw)"/>
<arg name="second_tb3_x_pos" default="$(arg second_tb3_x_pos)"/>
<arg name="second_tb3_y_pos" default="$(arg second_tb3_y_pos)"/>
<arg name="second_tb3_z_pos" default="$(arg second_tb3_z_pos)"/>
<arg name="second_tb3_yaw" default="$(arg second_tb3_yaw)"/>
<arg name="third_tb3_x_pos" default="$(arg third_tb3_x_pos)"/>
<arg name="third_tb3_y_pos" default="$(arg third_tb3_y_pos)"/>
<arg name="third_tb3_z_pos" default="$(arg third_tb3_z_pos)"/>
<arg name="third_tb3_yaw" default="$(arg third_tb3_yaw)"/>
</include>
8. TF(坐标变换)发布器
这一部分设置了不同坐标框架之间的静态变换(如从map
框架到每个机器人本地map
框架),用于对齐机器人的地图和坐标。
<node pkg="tf" type="static_transform_publisher" name="world_to_mergedmap_tf_broadcaster" args="0.385 0.385 0 0 0 0 world map 20"/>
<!-- <node pkg="tf" type="static_transform_publisher" name="world_to_mergedmap_tf_broadcaster" args="0 0 0 0 0 0 world map 100"/> -->
<node pkg="tf" type="static_transform_publisher" name="world_to_$(arg first_tb3)_tf_broadcaster" args="0 0 0 0 0 0 /map /$(arg first_tb3)/map 20"/>
<node pkg="tf" type="static_transform_publisher" name="world_to_$(arg second_tb3)_tf_broadcaster" args="0 0 0 0 0 0 /map /$(arg second_tb3)/map 20"/>
<node pkg="tf" type="static_transform_publisher" name="world_to_$(arg third_tb3)_tf_broadcaster" args="0 0 0 0 0 0 /map /$(arg third_tb3)/map 20"/>
-----------------------------------------------☆☆☆关于静态tf变换☆☆☆-----------------------------------------------
这部分代码涉及到 ROS 中 static_transform_publisher
节点的使用,主要目的是发布静态变换(static transforms)以描述不同坐标框架之间的关系。具体来说,它们是在不同坐标系之间发布静态的位移和旋转信息,帮助 ROS 系统中的其他节点理解各个坐标系的相对位置。
下面对上面的四个变化逐个进行详细的解释 :
(1) 发布全局坐标系到合并地图坐标系的静态变换xml <node pkg="tf" type="static_transform_publisher" name="world_to_mergedmap_tf_broadcaster" args="0.385 0.385 0 0 0 0 world map 20"/>
pkg="tf"
: 使用tf
包中的static_transform_publisher
类型节点。type="static_transform_publisher"
: 该节点负责发布静态坐标变换。name="world_to_mergedmap_tf_broadcaster"
: 节点的名称,用于标识该节点。args="0.385 0.385 0 0 0 0 world map 20"
: 这里的args
参数表示发布的静态变换的具体参数:
0.385 0.385 0
: 变换的平移部分(x, y, z),即坐标系从world
到map
的平移位移。0 0 0
: 变换的旋转部分(roll, pitch, yaw)。这里是零,表示没有旋转。world
: 源坐标系,即原始坐标系是world
。map
: 目标坐标系,变换之后的坐标系是map
。20
: 发布变换的频率,表示每秒发布20次。这个节点的作用是将
world
坐标系变换到map
坐标系,并且发布这个变换。这样,map
坐标系的位置和方向相对于world
坐标系就明确了。
(2) 发布从
world
到first_tb3
的静态变换xml <node pkg="tf" type="static_transform_publisher" name="world_to_$(arg first_tb3)_tf_broadcaster" args="0 0 0 0 0 0 /map /$(arg first_tb3)/map 20"/>
name="world_to_$(arg first_tb3)_tf_broadcaster"
: 这里,$(arg first_tb3)
表示将参数first_tb3
的值插入到节点的名字中,生成一个动态的节点名称。假设first_tb3
的值为tb3_0
,那么节点的名称就是world_to_tb3_0_tf_broadcaster
。args="0 0 0 0 0 0 /map /$(arg first_tb3)/map 20"
: 变换的参数:
0 0 0
: 平移部分,表示没有位移(x, y, z)。0 0 0
: 旋转部分,表示没有旋转(roll, pitch, yaw)。/map
: 源坐标系,即map
坐标系。/$(arg first_tb3)/map
: 目标坐标系,通过$(arg first_tb3)
动态生成目标坐标系的名称。例如,如果first_tb3
是tb3_0
,那么目标坐标系就是/tb3_0/map
。20
: 发布频率,20 次每秒。这个节点的作用是将全局
map
坐标系和first_tb3
机器人(例如tb3_0
)的map
坐标系之间的变换信息进行广播。
(3) 发布从
world
到second_tb3
的静态变换xml <node pkg="tf" type="static_transform_publisher" name="world_to_$(arg second_tb3)_tf_broadcaster" args="0 0 0 0 0 0 /map /$(arg second_tb3)/map 20"/>
这一行与上面相似,只是目标坐标系变成了second_tb3
(例如tb3_1
)。具体来说,它的作用是发布world
坐标系到tb3_1
的map
坐标系之间的变换信息。(4) 发布从
world
到third_tb3
的静态变换xml <node pkg="tf" type="static_transform_publisher" name="world_to_$(arg third_tb3)_tf_broadcaster" args="0 0 0 0 0 0 /map /$(arg third_tb3)/map 20"/>
这行代码与上面两行类似,只不过是用于发布从world
到third_tb3
(例如tb3_2
)的map
坐标系之间的变换信息。
总的来说:这部分代码通过
static_transform_publisher
节点定义了三个静态变换,将全局world
坐标系与多个机器人(tb3_0
、tb3_1
、tb3_2
)的map
坐标系之间的关系进行发布。每个变换节点都会发布其坐标系之间的平移和旋转关系(在本例中都是零旋转,零平移),帮助其他节点理解不同坐标系之间的相对位置。这些静态变换对于多机器人系统尤为重要,可以帮助系统中的各个部分正确地理解彼此的位置,尤其是在使用如slam_gmapping
、move_base
等节点时,坐标系转换是很关键的一部分。
9. RViz可视化
最后,启动RViz来进行机器人环境、地图和传感器数据的可视化:
<node pkg="rviz" type="rviz" name="rviz" required="true"
args="-d $(find ros_multi_tb3)/rviz/multi_tb3_gmapping.rviz"/>
-----------------------------------------------☆☆☆常改动参数☆☆☆-----------------------------------------------------
这里的multi_tb3_gmapping.rviz设定了打开的rviz界面的相关配置,如果想要更改配置,可以在rviz界面修该后,保存更新该文件,或者生成新的配置文件,并在这里修改文件名和路径。
-----------------------------------------------------------------------------------------------------------------------------------------