关于如何配置多机通讯和同步时间的问题,具体参考【多机手柄控制】这一节课;有网络的情况下直接同步网络系统时间,无需设置。
在使用多机手柄控制时,首先需要确保机器人在同一局域网下,配置同一个【ROS_MASTER_URI】;多个机器人控制运动,只可以有一个主机。本节案例设置虚拟机为主机,其他机器人为从机,有几个从机都可以;当然也可以设置某一机器人为主机其他为从机。
根据针对不同车型,只需在【.bashrc】中设置购买的车型即可,X1(普通四驱) X3(麦轮)X3plus(麦轮机械臂) R2(阿克曼差速) 等等,本节以X3为例
#树莓派5主控需要先进入docker,多执行此步骤
#如果运行脚本进入docker失败,请参考ROS/07、Docker教程
~/run_docker.sh
打开【.bashrc】文件
xxxxxxxxxx
sudo vim .bashrc
查找【ROBOT_TYPE】参数,修改相应的车型
xxxxxxxxxx
export ROBOT_TYPE=X3 # ROBOT_TYPE: X1 X3 X3plus R2 X7
以虚拟机是主机,3台机器人是从机为例;使用前必须有地图。3台从机分别【robot1】、【robot2】、【robot3】,又将【robot1】设定位领航者,【robot2】、【robot3】设定为跟随着。玩该功能时确保场地足够大,以免撞机。且无避障功能。
【该例程不适合树莓派5主板驱动】
虚拟机端
xxxxxxxxxx
roscore
启动命令(robot1端),为方便操作,本节以【mono + laser + yahboomcar】为例。
xxxxxxxxxx
roslaunch yahboomcar_multi laser_bringup_multi.launch ns:=robot1 # laser + yahboomcar
roslaunch yahboomcar_multi laser_usb_bringup_multi.launch ns:=robot1 # mono + laser + yahboomcar
roslaunch yahboomcar_multi laser_astrapro_bringup_multi.launch ns:=robot1 # Astra + laser + yahboomcar
启动命令(robot2端),为方便操作,本节以【mono + laser + yahboomcar】为例。
xxxxxxxxxx
roslaunch yahboomcar_multi laser_bringup_multi.launch ns:=robot2 # laser + yahboomcar
roslaunch yahboomcar_multi laser_usb_bringup_multi.launch ns:=robot2 # mono + laser + yahboomcar
roslaunch yahboomcar_multi laser_astrapro_bringup_multi.launch ns:=robot2 # Astra + laser + yahboomcar
更多机器人以此类推。
手柄控制开启过程参考【多机手柄控制】这一节课。
虚拟机端
xxxxxxxxxx
roslaunch yahboomcar_multi tf_queuebroad.launch use_rviz:=true map:=my_map
启动之后,需要对机器人进行初始化位姿设置,具体设置方法参考【多机导航这一节课】,设置后如下图。
打开动态参数调整工具
xxxxxxxxxx
rosrun 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>
节点查看
xxxxxxxxxx
rqt_graph
【QueueBroad】节点订阅来自每一个机器人的队列指令,该节点只会识别最近一次队形设置。
查看tf树
xxxxxxxxxx
rosrun rqt_tf_tree rqt_tf_tree
由上图可知【robot1】会发出两个坐标系【point1】和【point2】,【robot2】和【robot3】实时监听自身与该坐标系的关系,并使得自身坐标系与该坐标系重合。在【tf_queuebroad.launch】文件中,我们可以看出【robot2】跟随【point1】坐标系;【robot3】跟随【point2】坐标系。