近期进行多机器人编队控制仿真(gps、camera、laser),遇到些许问题,总结如下。
- 基于一个机器人URDF如何在gazebo中仿真显示多机器人——launch文件中使用group标签
<launch>
<!-- 运行gazebo仿真环境 -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
</include>
<!-- begin robot1 -->
<group ns="ares1">
<param name="robot_description" command="$(find xacro)/xacro $(find urdf_gazebo)/xacro/my_car.urdf.xacro bodyframe:=ares1 ns:=ares1" />
<!-- 运行joint_state_publisher节点,发布机器人的关节状态 -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" >
</node>
<!-- 运行robot_state_publisher节点,发布tf -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen" >
<param name="publish_frequency" type="double" value="50.0" />
<param name="tf_prefix" value="ares1" />
</node>
<!-- node name="ares_teleop" pkg="ares_teleop" type="ares_teleop.py" output="screen" /-->
<!-- 在gazebo中加载机器人模型-->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model ares1 -param robot_description -x 0 -y 0"/>
</group>
<!-- begin robot2 -->
<group ns="ares2">
<param name="robot_description" command="$(find xacro)/xacro $(find urdf_gazebo)/xacro/my_car.urdf.xacro bodyframe:=ares2 ns:=ares2" />
<!-- 运行joint_state_publisher节点,发布机器人的关节状态 -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" >
</node>
<!-- 运行robot_state_publisher节点,发布tf -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen" >
<param name="publish_frequency" type="double" value="50.0" />
<param name="tf_prefix" value="ares2" />
</node>
<!-- 在gazebo中加载机器人模型-->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model ares2 -param robot_description -x 0 -y 1"/>
</group>
<!-- begin robot3 -->
<group ns="ares3">
<param name="robot_description" command="$(find xacro)/xacro $(find urdf_gazebo)/xacro/my_car.urdf.xacro bodyframe:=ares3 ns:=ares3" />
<!-- 运行joint_state_publisher节点,发布机器人的关节状态 -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" >
</node>
<!-- 运行robot_state_publisher节点,发布tf -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen" >
<param name="publish_frequency" type="double" value="50.0" />
<param name="tf_prefix" value="ares3" />
</node>
<!-- 在gazebo中加载机器人模型-->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model ares3 -param robot_description -x 0 -y -1"/>
</group>
</launch>
2、机器人如何单独控制、或共同控制运动——namespace、cmd_vel
差速机器人-左右轮xacro驱动配置
<robot name="my_car_move" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:macro name="joint_trans" params="joint_name">
<transmission name="${joint_name}_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="${joint_name}">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
</joint>
<actuator name="${joint_name}_motor">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
</xacro:macro>
<xacro:joint_trans joint_name="left_wheel2base_link" />
<xacro:joint_trans joint_name="right_wheel2base_link" />
<gazebo>
<plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
<rosDebugLevel>Debug</rosDebugLevel>
<publishWheelTF>true</publishWheelTF>
<publishTf>1</publishTf>
<publishWheelJointState>true</publishWheelJointState>
<alwaysOn>true</alwaysOn>
<updateRate>100.0</updateRate>
<legacyMode>true</legacyMode>
<leftJoint>left_wheel2base_link</leftJoint>
<rightJoint>right_wheel2base_link</rightJoint>
<wheelSeparation>${base_link_radius * 2}</wheelSeparation>
<wheelDiameter>${wheel_radius * 2}</wheelDiameter>
<broadcastTF>1</broadcastTF>
<wheelTorque>30</wheelTorque>
<wheelAcceleration>1.8</wheelAcceleration>
<commandTopic>cmd_vel</commandTopic>
<odometryFrame>odom</odometryFrame>
<odometryTopic>odom</odometryTopic>
<robotBaseFrame>$(arg bodyframe)/base_footprint</robotBaseFrame>
<!-- <robotBaseFrame>base_footprint</robotBaseFrame> -->
</plugin>
<plugin name="p3d_base_controller" filename="libgazebo_ros_p3d.so">
<alwaysOn>true</alwaysOn>
<updateRate>50.0</updateRate>
<bodyName>base_link</bodyName>
<topicName>base_pose_ground_truth</topicName>
<gaussianNoise>0.01</gaussianNoise>
<frameName>world</frameName>
<xyzOffsets>0 0 0</xyzOffsets>
<rpyOffsets>0 0 0</rpyOffsets>
</plugin>
</gazebo>
</robot>
如何单独控制各个机器人:
即通过launch文件的group标签,给cmd_vel话题前加上命名空间。命名空间添加失败原因:
1> gazebo标签下的plugin标签里面,有<robotNamespace>/<robotNamespace>,该语句设置此配置中命名空间无法奏效,只需删除该语句;
2> <commandTopic>cmd_vel</commandTopic>设置中,话题cmd_vel前面有 '/',导致该话题为全局话题,命名空间不起作用,若需单独控制机器人则需要删除该斜杠;若需同时控制多机器人,则保留话题为 /cmd_vel 。
xacro配置文件plugin标签中,若所有话题前面有”/“,则该话题为全局话题,命名空间不起作用,若需命名空间,则需删除”/“。
3、ROS-gazebo如何进行GPS仿真
首先,需下载一个功能包hector_gazebo_plugins。Hector _ gazebo _ plugins 提供了来自 Hector 团队的 gazebo 插件。目前,它包含一个6瓦差分驱动插件,一个 IMU 传感器插件,一个地球磁场传感器插件,一个 GPS 传感器插件和一个声纳测距插件。
介绍:http://wiki.ros.org/hector_gazebo_plugins
sudo apt-get install ros-melodic-hector-gazebo-plugins
首先通过xacro文件描述出GPS的物理形状—my_gps.urdf.xacro文件
<robot name="sensor" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:property name="height1" value="0.05" />
<xacro:property name="width" value="0.05" />
<!-- Used for fixing robot to Gazebo 'base_link' -->
<joint name="fixed" type="fixed">
<parent link="laser"/>
<child link="sensor"/>
<origin xyz="0 0 ${height1 / 2}" />
</joint>
<!-- Base Link -->
<link name="sensor">
<collision>
<origin xyz="0 0 ${height1/2}" rpy="0 0 0"/>
<geometry>
<box size="${width} ${width} ${height1}"/>
</geometry>
</collision>
<visual>
<origin xyz="0 0 ${height1/2}" rpy="0 0 0"/>
<geometry>
<box size="${width} ${width} ${height1}"/>
</geometry>
<material name="orange"/>
</visual>
<inertial>
<origin xyz="0 0 1" rpy="0 0 0"/>
<mass value="1"/>
<inertia
ixx="1.0" ixy="0.0" ixz="0.0"
iyy="1.0" iyz="0.0"
izz="1.0"/>
</inertial>
</link>
<material name="orange">
<color rgba="${255/255} ${108/255} ${10/255} 1.0"/>
</material>
<gazebo reference="sensor">
<material>Gazebo/Orange</material>
</gazebo>
</robot>
然后进行gps功能配置:
<robot name="sensor" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:include filename="$(find urdf_gazebo)/xacro/my_gps.urdf.xacro"/>
<gazebo>
<plugin name="gazebo_ros_gps" filename="libhector_gazebo_ros_gps.so">
<updateRate>4.0</updateRate>
<bodyName>sensor</bodyName>
<frameId>sensor</frameId>
<topicName>gps/fix</topicName>
<velocityTopicName>gps/fix_velocity</velocityTopicName>
<referenceLatitude>-30.06022459407145675</referenceLatitude>
<referenceLongitude>-51.173913575780311191</referenceLongitude>
<referenceHeading>90</referenceHeading>
<referenceAltitude>10</referenceAltitude>
<offset>0 0 0</offset>
<drift>0.001 0.001 0.001</drift>
<gaussianNoise>0.05 0.05 0.05</gaussianNoise>
<velocityDrift>0.001 0.001 0.001</velocityDrift>
<velocityGaussianNoise>0.5 0.5 0.5</velocityGaussianNoise>
</plugin>
</gazebo>
其中,在该gps功能配置的xacro文件中,必须通过 <xacro:include filename="$(find urdf_gazebo)/xacro/my_gps.urdf.xacro"/> ,导入gps的物体描述xacro文件;即gps的物体描述代码与功能配置代码,需连接在一起。原因:如果是传感器的功能配置plugin标签,则必须在gazebo标签内的sensor标签下,否则不起作用。而该gps的配置gazebo标签内没有sensor标签,若想plugin标签起作用,就得紧接在物体描述代码后,而不能分成两个单独得文件。
同时,若想命名空间起作用,就需主要 话题 前面的”/“。
<frameId>sensor</frameId>中,frameId为GPS基于哪个ID发布的坐标,其中sensor为描述的GPS名称。
(个人见解,不是很深刻)
4、Laser仿真
雷达仿真注意事项也如上:
雷达(单线)物体描述的xacro文件:
<robot name="my_laser" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:property name="support_length" value="0.15" />
<xacro:property name="support_radius" value="0.01" />
<xacro:property name="support_x" value="0.0" />
<xacro:property name="support_y" value="0.0" />
<xacro:property name="support_z" value="${base_link_length / 2 + support_length / 2}" />
<xacro:property name="support_m" value="0.02" />
<link name="support">
<visual>
<geometry>
<cylinder radius="${support_radius}" length="${support_length}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="red">
<color rgba="0.8 0.2 0.0 0.8" />
</material>
</visual>
<collision>
<geometry>
<cylinder radius="${support_radius}" length="${support_length}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
</collision>
<xacro:cylinder_inertial_matrix m="${support_m}" r="${support_radius}" h="${support_length}" />
</link>
<joint name="support2base_link" type="fixed">
<parent link="base_link" />
<child link="support" />
<origin xyz="${support_x} ${support_y} ${support_z}" />
</joint>
<gazebo reference="support">
<material>Gazebo/White</material>
</gazebo>
<xacro:property name="laser_length" value="0.05" />
<xacro:property name="laser_radius" value="0.03" />
<xacro:property name="laser_x" value="0.0" />
<xacro:property name="laser_y" value="0.0" />
<xacro:property name="laser_z" value="${support_length / 2 + laser_length / 2}" />
<xacro:property name="laser_m" value="0.1" />
<link name="laser">
<visual>
<geometry>
<cylinder radius="${laser_radius}" length="${laser_length}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="black" />
</visual>
<collision>
<geometry>
<cylinder radius="${laser_radius}" length="${laser_length}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
</collision>
<xacro:cylinder_inertial_matrix m="${laser_m}" r="${laser_radius}" h="${laser_length}" />
</link>
<joint name="laser2support" type="fixed">
<parent link="support" />
<child link="laser" />
<origin xyz="${laser_x} ${laser_y} ${laser_z}" />
</joint>
<gazebo reference="laser">
<material>Gazebo/Black</material>
</gazebo>
</robot>
功能配置xacro文件(满足命名空间)
<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro">
<gazebo reference="laser">
<sensor type="ray" name="rplidar">
<pose>0 0 0 0 0 0</pose>
<visualize>false</visualize>
<update_rate>5.5</update_rate>
<ray>
<scan>
<horizontal>
<samples>360</samples>
<resolution>1</resolution>
<min_angle>-3</min_angle>
<max_angle>3</max_angle>
</horizontal>
</scan>
<range>
<min>0.10</min>
<max>30.0</max>
<resolution>0.01</resolution>
</range>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.01</stddev>
</noise>
</ray>
<plugin name="gazebo_rplidar" filename="libgazebo_ros_laser.so">
<topicName>scan</topicName>
<frameName>laser</frameName>
</plugin>
</sensor>
</gazebo>
</robot>
小车集成xaro文件:
<robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:include filename="my_head.xacro" />
<xacro:include filename="my_base.urdf.xacro" />
<xacro:include filename="my_camera.urdf.xacro" />
<xacro:include filename="my_laser.urdf.xacro" />
<!-- show gps -->
<!-- <xacro:include filename="my_gps.urdf.xacro" /> -->
<xacro:include filename="ros_control/gps.xacro" />
<xacro:include filename="ros_control/move.xacro" />
<xacro:include filename="ros_control/laser.xacro" />
<xacro:include filename="ros_control/camera.xacro" />
<xacro:include filename="ros_control/kinect.xacro" />
</robot>
最后小车集成图片:
![](https://i-blog.csdnimg.cn/blog_migrate/b6eac6f2626981be8911145f4661beef.png)
多机器人显示,基于人工势场并可实现多机领航-跟随。
各位同学若需要全套仿真代码,可评论或私信博主。