关于如何配置多机通讯和同步时间的问题,具体参考【多机手柄控制】这一节课;有网络的情况下直接同步网络系统时间,无需设置。
在使用多机手柄控制时,首先需要确保机器人在同一局域网下,配置同一个【ROS_MASTER_URI】;多个机器人控制运动,只可以有一个主机。本节案例设置虚拟机为主机,其他机器人为从机,有几个从机都可以;当然也可以设置某一机器人为主机其他为从机。
根据针对不同车型,只需在【.bashrc】中设置购买的车型即可,X1(普通四驱) X3(麦轮)X3plus(麦轮机械臂) R2(阿克曼差速) 等等,本节以X3为例
#树莓派5主控需要先进入docker,多执行此步骤#如果运行脚本进入docker失败,请参考ROS/07、Docker教程~/run_docker.sh打开【.bashrc】文件
xxxxxxxxxxsudo vim .bashrc
查找【ROBOT_TYPE】参数,修改相应的车型
xxxxxxxxxxexport ROBOT_TYPE=X3 # ROBOT_TYPE: X1 X3 X3plus R2 X7以虚拟机是主机,3台机器人是从机为例;使用前必须有地图。3台从机分别【robot1】、【robot2】、【robot3】,又将【robot1】设定位领航者,【robot2】、【robot3】设定为跟随着。玩该功能时确保场地足够大,以免撞机。且无避障功能。
【该例程不适合树莓派5主板驱动】
虚拟机端
xxxxxxxxxxroscore
启动命令(robot1端),为方便操作,本节以【mono + laser + yahboomcar】为例。
xxxxxxxxxxroslaunch yahboomcar_multi laser_bringup_multi.launch ns:=robot1 # laser + yahboomcarroslaunch yahboomcar_multi laser_usb_bringup_multi.launch ns:=robot1 # mono + laser + yahboomcarroslaunch yahboomcar_multi laser_astrapro_bringup_multi.launch ns:=robot1 # Astra + laser + yahboomcar启动命令(robot2端),为方便操作,本节以【mono + laser + yahboomcar】为例。
xxxxxxxxxxroslaunch yahboomcar_multi laser_bringup_multi.launch ns:=robot2 # laser + yahboomcarroslaunch yahboomcar_multi laser_usb_bringup_multi.launch ns:=robot2 # mono + laser + yahboomcarroslaunch yahboomcar_multi laser_astrapro_bringup_multi.launch ns:=robot2 # Astra + laser + yahboomcar更多机器人以此类推。
手柄控制开启过程参考【多机手柄控制】这一节课。
虚拟机端
xxxxxxxxxxroslaunch yahboomcar_multi tf_queuebroad.launch use_rviz:=true map:=my_map
启动之后,需要对机器人进行初始化位姿设置,具体设置方法参考【多机导航这一节课】,设置后如下图。

打开动态参数调整工具
xxxxxxxxxxrosrun rqt_reconfigure rqt_reconfigure

该工具可对每台机器人单独设置。
参数解析
【lin_Kp】、【lin_Ki】、【lin_Kd】:小车线速度PID调试。
【ang_Kp】、【ang_Ki】、【ang_Kd】:小车角速度PID调试。
| 参数 | 范围 | 解析 |
|---|---|---|
| 【teams】 | 默认【vertical】 | 队形:【convoy,vertical, horizontal】 |
| 【robot_model】 | 默认【omni】 | 车型:【omni,diff】 |
| 【navigate】 | 【False,True】 | 是否以导航模式运行 |
| 【Switch】 | 【False,True】 | 功能开关【开始/暂停】 |
| 【dist】 | 【0.5,2.0】 | 队列之间的距离 |
开启【Switch】功能开关后,机器人自动保持【teams】参数设定的队形,【teams】参数只识别最近一次设定的值。如下图所示



队形设定后,当我们控制【robot1】时,其他机器人无需控制自动保持该队形。
tf_queuebroad.launch
xxxxxxxxxx<launch> <arg name="first_robot1" default="robot1"/> <arg name="second_robot2" default="robot2"/> <arg name="third_robot3" default="robot3"/> <!-- 是否打开rviz || Whether to open rviz --> <arg name="use_rviz" default="true"/> <!-- 地图名 || Map name --> <arg name="map" default="my_map"/> <!-- 加载地图 || Load map --> <node name="map_server" pkg="map_server" type="map_server" args="$(find yahboomcar_nav)/maps/$(arg map).yaml"/> <node pkg="rviz" type="rviz" name="rviz" required="true" args="-d $(find yahboomcar_multi)/rviz/tf_multi.rviz" if="$(arg use_rviz)"/> <!-- ############################# first_robot1 ############################# --> <node pkg="yahboomcar_multi" type="broad_queue.py" name="QueueBroad" output="screen" args="$(arg first_robot1)"/> <include file="$(find yahboomcar_multi)/launch/library/move_base_multi.launch"> <arg name="ns" value="$(arg first_robot1)"/> </include> <!-- ############################# second_robot2 ############################# --> <node pkg="yahboomcar_multi" type="listener.py" name="RobotListener" output="screen" args="$(arg second_robot2) point1" ns="$(arg second_robot2)/"> <rosparam param="linPIDparam">[1.0, 0, 1.0]</rosparam> <rosparam param="angPIDparam">[0.8, 0, 1.0]</rosparam> </node> <include file="$(find yahboomcar_multi)/launch/library/move_base_multi.launch"> <arg name="ns" value="$(arg second_robot2)"/> </include> <!-- ############################# third_robot3 ############################# --> <node pkg="yahboomcar_multi" type="listener.py" name="RobotListener" output="screen" args="$(arg third_robot3) point2" ns="$(arg third_robot3)/"> <rosparam param="linPIDparam">[1.0, 0, 1.0]</rosparam> <rosparam param="angPIDparam">[0.8, 0, 1.0]</rosparam> </node> <include file="$(find yahboomcar_multi)/launch/library/move_base_multi.launch"> <arg name="ns" value="$(arg third_robot3)"/> </include></launch>节点查看
xxxxxxxxxxrqt_graph

【QueueBroad】节点订阅来自每一个机器人的队列指令,该节点只会识别最近一次队形设置。
查看tf树
xxxxxxxxxxrosrun rqt_tf_tree rqt_tf_tree

由上图可知【robot1】会发出两个坐标系【point1】和【point2】,【robot2】和【robot3】实时监听自身与该坐标系的关系,并使得自身坐标系与该坐标系重合。在【tf_queuebroad.launch】文件中,我们可以看出【robot2】跟随【point1】坐标系;【robot3】跟随【point2】坐标系。