在之前介绍的《多无人车协同探索开源包部署教程及常见报错解决方式》中运行多无人车协同探索时,先后运行了两个launch文件 multiple_tb3_house.launch 和three_robots.launch ,本文来进一步看一下这两个启动文件以及其调用的move_base .launch 和multi_tb3_mapmerge.launch 都做哪些操作以及如何根据自己的需要进行相应的修改。
由于内容较多,拆分成(上)、(下)两篇博客,链接如下:
多无人车协同探索开源包启动文件介绍(上)
多无人车协同探索开源包启动文件介绍(下)
二、move_base .launch 详细介绍
move_base.launch
文件的作用是启动 ROS 中的 move_base
节点,并进行相关的参数配置。move_base
是 ROS Navigation Stack 中的关键节点,用于实现机器人在地图上的导航,包括全局路径规划、局部路径规划、地图与传感器信息的融合、控制指令计算等。以下是对每一部分的详细解释。
1. 定义参数和命名空间:
<arg name="namespace" default="tb3_1"/>
<arg name="robot_base_frame" default="$(arg namespace)/base_footprint"/>
<arg name="move_forward_only" default="false"/>
<arg name="cmd_vel_topic" default="$(arg namespace)/cmd_vel" />
<!-- <arg name="odom_topic" default="odom" /> -->
<arg name="model" default="waffle_pi" doc="model type [burger, waffle, waffle_pi]"/>
<arg name="namespace" default="tb3_1"/>
: 定义了一个参数namespace
,默认为tb3_1
。这个参数在后续的节点和参数配置中用来指定机器人的命名空间(即机器人的唯一标识符)。<arg name="robot_base_frame" default="$(arg namespace)/base_footprint"/>
: 定义了robot_base_frame
参数,表示机器人的基座坐标系(base_footprint
)。这个参数值通过命名空间动态设定,例如,如果namespace
是tb3_1
,则robot_base_frame
的值为tb3_1/base_footprint
。<arg name="move_forward_only" default="false"/>
: 定义了一个布尔类型参数move_forward_only
,默认值为false
,表示机器人是否只允许前进。后续的控制逻辑会依据该参数判断。<arg name="cmd_vel_topic" default="$(arg namespace)/cmd_vel" />
: 定义了一个cmd_vel
的话题名称参数,该话题用于接收机器人运动的控制命令。它使用命名空间,所以如果命名空间是tb3_1
,该话题就是/tb3_1/cmd_vel
。<arg name="model" default="waffle_pi" doc="model type [burger, waffle, waffle_pi]"/>
: 定义了model
参数,用于指定机器人模型类型,默认为waffle_pi
,用户可以在启动时更改为burger
或waffle
。
注:这里仅对这些参数的默认值进行设定,即在调用move_base .launch文件时,若未对上述参数进行设定,则采用default设定的默认值,在本项目中这些参数在multiple_tb3_house.launch中对move_base .launch进行调用时,已经传入了新的设定参数值,真正发挥作用的是multiple_tb3_house.launch中设定的参数值,所以要对上述参数进行修改时,需要在multiple_tb3_house.launch中进行修改,而非此处。
2. 启动 move_base
节点:
<node pkg="move_base" type="move_base" respawn="false" name="move_base_node" output="screen">
pkg="move_base"
: 启动move_base
包中的move_base
节点,这是 ROS Navigation Stack 的核心节点,负责处理机器人的导航任务。type="move_base"
: 节点类型,即执行的程序是move_base
。respawn="false"
: 设置节点是否在退出时自动重启,false
表示该节点不会重启。name="move_base_node"
: 节点的名称为move_base_node
,它将帮助其他节点识别这个导航节点。output="screen"
: 设置节点的输出信息会显示在终端上。
3. 加载成本地图相关参数:
<rosparam file="$(find ros_multi_tb3)/params/costmap_common_params_waffle_pi.yaml" command="load" ns="global_costmap"/>
<rosparam file="$(find ros_multi_tb3)/params/costmap_common_params_waffle_pi.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find ros_multi_tb3)/params/local_costmap_params_$(arg namespace).yaml" command="load"/>
<rosparam file="$(find ros_multi_tb3)/params/global_costmap_params_$(arg namespace).yaml" command="load"/>
-
<rosparam file="..." command="load" ns="global_costmap"/>
: 这些rosparam
行加载了与成本地图(costmap)相关的参数。costmap
是用于存储环境障碍物信息的栅格地图,global_costmap
和local_costmap
分别代表全局地图和局部地图的配置。- 第一行加载了通用的成本地图配置(
costmap_common_params_waffle_pi.yaml
),适用于waffle_pi
模型。 - 第二行加载了相同的文件,但是应用于局部成本地图(
local_costmap
)。 - 后面两行分别加载了与
namespace
相关的局部和全局成本地图的参数配置。
-----------------------------------------------☆☆☆常改动参数☆☆☆-----------------------------------------------------
- 第一行加载了通用的成本地图配置(
这里设定了要加载的地图配置参数文件,在这三个文件中对地图相关的参数进行了设定,例如 膨胀半径 (inflation_radius) 地图尺寸 (width, height) 分辨率 (resolution) 更新频率 (update_frequency, publish_frequency) 静态地图设置 (static_map) 障碍物层参数 (obstacle_layer) 膨胀层参数 (inflation_layer) 障碍物范围 (obstacle_range, raytrace_range) 转换容忍度 (transform_tolerance) 障碍物清除 (clearing) 坐标变换帧 (global_frame, robot_base_frame) 地图发布话题 (map) 等参数。 可在这三个文件中进行相应的修改,或者使用其他文件在这里更改文件名。
-----------------------------------------------------------------------------------------------------------------------------------------
4. 设置局部路径规划器(local planner):
<param name="base_local_planner" value="teb_local_planner/TebLocalPlannerROS"/>
<rosparam file="$(find ros_multi_tb3)/params/base_local_planner_teb_$(arg namespace).yaml" command="load" />
<param name="base_local_planner" value="teb_local_planner/TebLocalPlannerROS"/>
: 设置move_base
使用的本地路径规划器为TebLocalPlannerROS
,这是一个基于优化的局部路径规划器,能够处理动态障碍物。<rosparam file="..." command="load"/>
: 加载与TebLocalPlannerROS
配置相关的参数文件,这些文件根据命名空间进行调整。
-----------------------------------------------☆☆☆常改动参数☆☆☆-----------------------------------------------------
这里base_local_planner设定了要使用的局部规划器插件,上面的例子中设定的是teb算法的teb_local_planner/ TebLocalPlannerROS插件,如果想要更换为其他局部路径规划器,需要对这个参数进行修改,比如更改为使用dwa算法的dwa_local_planner/DWAPlannerROS插件。
一般来说,规划器插件会预留一些参数供使用者进行调试,所以使用规划器时需要使用rosparam 对它的参数文件也进行加载,比如上面的例子中对base_local_planner_teb_tb3_0.yaml文件进行了加载,可以在该文件中对规划器相关参数进行调节,当然也可以在这里改用其他参数文件,更改规划器插件的时候对应的参数配置文件一般也要进行修改
-----------------------------------------------------------------------------------------------------------------------------------------
5. 加载全局路径规划器(global planner):
<rosparam file="$(find ros_multi_tb3)/params/base_global_planner.yaml" command="load" />
<rosparam file="$(find ros_multi_tb3)/params/move_base_params.yaml" command="load" />
<rosparam file="..." command="load"/>
: 这两行加载了全局路径规划器(base_global_planner.yaml
)的参数配置,并加载了move_base
的通用参数配置(move_base_params.yaml
)。
-----------------------------------------------☆☆☆常改动参数☆☆☆-----------------------------------------------------
注意,在上面的配置中,虽然加载了全局路径规划器的相关参数文件(base_global_planner.yaml
),但是并没有明确指定全局路径规划器插件的名称。此时,ROS将使用默认的全局路径规划器插件 navfn/NavfnROS
,它是基于A算法的路径规划器,广泛用于导航任务。如果想要改用其他全局路径规划器插件,可以使用参数base_global_planner进行设定,如下所示的语句中设定了采用另一个基于A算法的全局路径规划器插件global_planner/GlobalPlanner,并从bringup所在路径的param文件夹下加载了名为move_base_params.yaml的参数配置文件
<param name="base_global_planner" value="global_planner/GlobalPlanner" /><rosparam file="$(find bringup)/param/move_base_params.yaml" command="load" />
-----------------------------------------------------------------------------------------------------------------------------------------
6. 重映射命名空间和话题名称:
<remap from="robot_base_frame" to="$(arg namespace)/base_footprint"/>
<remap from="/map" to="$(arg namespace)/map"/>
<remap from="robot_base_frame" to="$(arg namespace)/base_footprint"/>
: 将robot_base_frame
重映射到命名空间下的base_footprint
,即机器人的基座坐标系。<remap from="/map" to="$(arg namespace)/map"/>
: 将全局地图话题/map
重映射到命名空间下的map
,例如,如果命名空间是tb3_1
,那么它会变成/tb3_1/map
。
7. 结束 move_base
节点配置:
</node>
- 该标签关闭了
move_base
节点的配置,表示该节点的配置结束。
总的来说,该 launch
文件的主要作用是启动一个机器人 (move_base
节点) 的导航系统,配置了全局和局部的成本地图、路径规划器,并通过参数文件设置了与该机器人的导航相关的配置。通过动态命名空间和相关参数,它支持多机器人系统中的每个机器人的个性化配置,确保每个机器人都能根据其特定的配置文件正确运行。
三、multi_tb3_mapmerge.launch 详细介绍
multi_tb3_mapmerge.launch
文件的作用是启动多机器人系统中的 地图合并 (Map Merging) 功能,尤其是在有多个 TurtleBot 机器人参与时,合并它们的地图。以下是详细解释:
注:该launch文件中大部分参数在multiple_tb3_house.launch中进行设定,因此修改的时候也要在multiple_tb3_house中进行修改,这里仅提供一些默认值
1. 定义参数 (Arguments)
<arg name="model" default="waffle_pi" doc="model type [burger, waffle, waffle_pi]"/>
<arg name="move_forward_only" default="false"/>
- model: 定义机器人的模型类型,默认为
waffle_pi
,也可以设置为burger
或waffle
。 - move_forward_only: 控制机器人是否只进行前进动作,默认为
false
,即机器人可以进行全向运动。
2. 定义三个机器人 (TurtleBot3) 的参数
<arg name="first_tb3" default="tb3_1"/>
<arg name="second_tb3" default="tb3_2"/>
<arg name="third_tb3" default="tb3_3"/>
- first_tb3, second_tb3, third_tb3: 分别定义了三个机器人的名称,
tb3_1
、tb3_2
、tb3_3
。这些值将作为参数传递给后续的节点和命名空间。
3. 机器人的初始位姿信息
<arg name="first_tb3_x_pos" default=" 0.5"/>
<arg name="first_tb3_y_pos" default=" 2.2"/>
<arg name="first_tb3_z_pos" default=" 0.0"/>
<arg name="first_tb3_yaw" default=" 0.0"/><arg name="second_tb3_x_pos" default=" 0.5"/>
<arg name="second_tb3_y_pos" default=" 3.8"/>
<arg name="second_tb3_z_pos" default=" 0.0"/>
<arg name="second_tb3_yaw" default=" 0.0"/><arg name="third_tb3_x_pos" default=" 0.5"/>
<arg name="third_tb3_y_pos" default=" 3.0"/>
<arg name="third_tb3_z_pos" default=" 0.0"/>
<arg name="third_tb3_yaw" default=" 0.0"/>
- 为每个机器人定义了初始的位置和朝向(
x_pos
,y_pos
,z_pos
,yaw
)。这些值用于指定机器人在模拟环境中的放置位置。
4. 设置每个机器人地图合并的初始位置
<group ns="/$(arg first_tb3)/map_merge"><param name="init_pose_x" value="$(arg first_tb3_x_pos)"/><param name="init_pose_y" value="$(arg first_tb3_y_pos)"/><param name="init_pose_z" value="$(arg first_tb3_z_pos)"/><param name="init_pose_yaw" value="$(arg first_tb3_yaw)"/>
</group>
<group ns="/$(arg second_tb3)/map_merge"><param name="init_pose_x" value="$(arg second_tb3_x_pos)"/><param name="init_pose_y" value="$(arg second_tb3_y_pos)"/><param name="init_pose_z" value="$(arg second_tb3_z_pos)"/><param name="init_pose_yaw" value="$(arg second_tb3_yaw)"/>
</group>
<group ns="/$(arg third_tb3)/map_merge"><param name="init_pose_x" value="$(arg third_tb3_x_pos)"/><param name="init_pose_y" value="$(arg third_tb3_y_pos)"/><param name="init_pose_z" value="$(arg third_tb3_z_pos)"/><param name="init_pose_yaw" value="$(arg third_tb3_yaw)"/>
</group>
- 为每个机器人分别设置了地图合并的初始位置和朝向。每个机器人的命名空间通过
ns
标签来设置。
5. 启动地图合并节点 (map_merge)
<node pkg="multirobot_map_merge" type="map_merge" respawn="false" name="map_merge"><param name="robot_map_topic" value="/map"/><param name="robot_namespace" value="tb3"/><param name="merged_map_topic" value="/map"/><param name="world_frame" value="world"/><param name="known_init_poses" value="true"/><param name="merging_rate" value="3.0"/><param name="discovery_rate" value="0.02"/><param name="estimation_rate" value="0.6"/><param name="estimation_confidence" value="0.6"/>
</node>
- 启动
map_merge
节点,用于合并不同机器人的地图。具体的参数包括:- robot_map_topic: 定义机器人的地图话题(
/map
)。 - robot_namespace: 机器人命名空间(
tb3
)。 - merged_map_topic: 合并后的地图话题。
- world_frame: 设定地图的参考坐标系(
world
)。 - known_init_poses: 是否使用已知的初始化位置,设为
true
表示使用机器人初始位置。 - merging_rate: 设置地图合并的频率(
3.0
)。 - discovery_rate: 机器人之间发现对方地图的频率(
0.02
)。 - estimation_rate: 地图合并的估算频率(
0.6
)。 - estimation_confidence: 估算的置信度(
0.6
)。
- robot_map_topic: 定义机器人的地图话题(
此 launch
文件主要用于多机器人系统中地图的合并。通过启动 map_merge
节点,并为每个机器人设置其初始位置、命名空间以及相关的地图合并参数,实现了不同机器人之间地图的合并与协调。
四、three_robots.launch 详细介绍
three_robots.launch
文件用于启动与 RRT(Rapidly-exploring Random Tree) 探索算法相关的节点。它主要应用于多机器人环境中的探索任务,包含了前沿检测、前沿分配和地图边界设定等内容。以下是对每一部分的详细介绍:
1. 定义算法相关参数 (Arguments)
<arg name="eta" value="1.0"/>
<arg name="Geta" value="1.0"/>
<arg name="info_radius" value="1.0"/>
<arg name="info_multiplier" value="3.0"/>
<arg name="hysteresis_radius" value="3.0"/>
<arg name="hysteresis_gain" value="3.0"/>
<arg name="costmap_clearing_threshold" value="50"/>
<arg name="delay_after_assignement" value="0.7"/>
<arg name="bandwith_cluster" value="0.3"/>
<arg name="frequency1" value="5.0"/>
<arg name="detected_frontier" value="/detected_points"/>
<arg name="filtered_frontier" value="/filtered_points"/>
- eta 和 Geta: 用于 RRT 算法中的扩展参数,控制算法的探索范围或步长。
- info_radius: 定义在前沿探测中,感知区域的半径。
- info_multiplier: 用于前沿信息的加权。
- hysteresis_radius 和 hysteresis_gain: 与滞后效应(Hysteresis)相关,控制探索过程中的稳定性和响应灵敏度。
- costmap_clearing_threshold: 设定成本地图的清除阈值,用于判断何时清除一个区域。
- delay_after_assignement: 在分配前沿之后的延迟时间,通常是为了同步多个机器人。
- bandwith_cluster: 用于聚类算法中的带宽,影响前沿聚类的结果。
- frequency1: 设置前沿检测和过滤的频率。
- detected_frontier 和 filtered_frontier: 定义前沿点的输入和输出话题。
2. 机器人命名空间 (Robot Namespace)
<arg name="first_tb3" default="tb3_1"/>
<arg name="second_tb3" default="tb3_2"/>
<arg name="third_tb3" default="tb3_0"/>
- 定义了三个机器人(
tb3_1
,tb3_2
,tb3_0
)的命名空间,用于区分不同的机器人。
3. 设置地图相关的参数
<arg name="global_map" value ="/map"/>
<arg name="global_frame" value ="map"/>
<arg name="global_costmap_topic" value="/move_base_node/global_costmap/costmap"/>
- global_map: 定义全局地图话题。
- global_frame: 全局坐标框架,通常是
map
。 - global_costmap_topic: 指定全局成本地图的话题。
4. 启动地图边界检测节点 (Boundary Detection)
<node pkg="rrt_exploration" type="boundary.py" name="exploration_boundary" output="screen"><param name="mapFrame" value="map"/><param name="n_point" value="4"/><param name="topicInput" value="clicked_point"/><param name="topicOutput" value="exploration_boundary"/><param name="frequency" value="0.5"/>
</node>
- boundary.py: 这是一个用于定义探索区域边界的节点,通常用于设定探索的区域范围。
- mapFrame: 设置边界检测的坐标系为
map
。 - n_point: 定义边界的点数目,
4
代表边界为矩形。 - topicInput 和 topicOutput: 用于定义输入和输出的话题,
clicked_point
表示点击输入点,exploration_boundary
表示输出的边界。 - frequency: 设定边界检测的频率。
5. 启动全局 RRT 探测器 (Global RRT Detection)
<node pkg="rrt_exploration" type="global_rrt_detector" name="global_rrt_detector" output="screen"><param name="eta" value="$(arg Geta)"/><param name="map_topic" value="/map"/>
</node>
- global_rrt_detector: 用于全局前沿的 RRT 探测。
- eta: 传入前面定义的
Geta
参数。 - map_topic: 使用全局地图作为输入。
6. 启动本地 RRT 探测器 (Local RRT Detection)
<node pkg="rrt_exploration" type="local_rrt_detector" name="$(arg first_tb3)_rrt_detector" output="screen"><param name="eta" value="$(arg eta)"/><param name="map_topic" value="/$(arg first_tb3)/map"/><param name="robot_frame" value="/$(arg first_tb3)/base_link"/>
</node>
<node pkg="rrt_exploration" type="local_rrt_detector" name="$(arg second_tb3)_rrt_detector" output="screen"><param name="eta" value="$(arg eta)"/><param name="map_topic" value="/$(arg second_tb3)/map"/><param name="robot_frame" value="/$(arg second_tb3)/base_link"/>
</node>
<node pkg="rrt_exploration" type="local_rrt_detector" name="$(arg third_tb3)_rrt_detector" output="screen"><param name="eta" value="$(arg eta)"/><param name="map_topic" value="/$(arg third_tb3)/map"/><param name="robot_frame" value="/$(arg third_tb3)/base_link"/>
</node>
- local_rrt_detector: 用于每个机器人的本地前沿探测。
- 每个机器人都启动一个本地 RRT 探测器,使用相应机器人的地图和坐标框架。
- eta: 传入前面定义的
eta
参数,控制扩展范围。
7. 启动前沿点过滤节点 (Filter Node)
<node pkg="rrt_exploration" type="filter.py" name="filter" output="screen"><param name="map_topic" value="$(arg global_map)"/><param name="info_radius" value="$(arg info_radius)"/> <param name="costmap_clearing_threshold" value="$(arg costmap_clearing_threshold)"/> <param name="global_costmap_topic" value="$(arg global_costmap_topic)"/> <param name="goals_topic" value="$(arg detected_frontier)"/> <param name="robot_namelist" value="$(arg first_tb3),$(arg second_tb3),$(arg third_tb3)"/><param name="rate" value="$(arg frequency1)"/><param name="local_map" value="/map"/><param name="bandwith_cluster" value="$(arg bandwith_cluster)"/>
</node>
- filter.py: 用于对前沿点进行过滤,以便后续处理。
- goals_topic: 输入已检测到的前沿点。
- robot_namelist: 输入机器人列表。
- rate: 设定过滤的频率。
8. 启动前沿分配器 (Assigner Node)
<node pkg="rrt_exploration" type="assigner.py" name="assigner" output="screen"><param name="map_topic" value="$(arg global_map)"/><param name="global_frame" value="$(arg global_frame)"/><param name="info_radius" value="$(arg info_radius)"/> <param name="info_multiplier" value="$(arg info_multiplier)"/> <param name="hysteresis_radius" value="$(arg hysteresis_radius)"/> <param name="hysteresis_gain" value="$(arg hysteresis_gain)"/> <param name="frontiers_topic" value="/filtered_points"/> <param name="robot_namelist" value="$(arg first_tb3),$(arg second_tb3),$(arg third_tb3)"/><param name="delay_after_assignement" value="$(arg delay_after_assignement)"/>
</node>
- assigner.py: 用于分配前沿给不同的机器人,确保每个机器人有明确的任务。
- frontiers_topic: 输入过滤后的前沿点。
- delay_after_assignement: 分配后等待的延迟时间。
此 launch
文件用于在多机器人系统中进行基于 RRT 的协同探索,帮助机器人探索未知区域。它通过启动多个节点来完成地图边界检测、前沿检测、前沿过滤、前沿分配等任务,以支持多机器人协同探索。