一、为什么机器人模型必须做Gazebo物理仿真配置?

前期搭建的ROS机器人URDF/Xacro模型,仅能还原机器人本体、各类传感器的外观结构与坐标系关联关系,不具备真实物理运动特性和传感器数据输出能力。若要让机器人在仿真环境中复刻真机运行效果,实现运动控制、环境感知、SLAM建图、自主导航等功能调试,必须为机器人模型补充物理属性、碰撞检测规则、运动控制器及传感器仿真插件配置。

本文基于ROS+Gazebo仿真平台,结合ros_control核心控制中间件,手把手完成两轮差速移动机器人本体仿真配置、激光雷达+摄像头传感器仿真适配,最终实现仿真环境机器人运动控制、里程计可视化查看,全程适配通用ROS开发规范,可直接落地实操复用。

二、核心基础:ros_control控制中间件核心原理

2.1 ros_control核心作用

ROS生态中SLAM、导航、MoveIt等上层应用功能包,无法直接对接真实机器人硬件或Gazebo仿真器,二者之间缺少标准化的衔接适配层。而ros_control是ROS官方提供的标准化控制中间件,作为上层ROS应用与底层机器人硬件/仿真环境的核心桥梁,配套完善的控制器接口、传动装置接口、硬件抽象接口及控制器工具箱。

该中间件采用可插拔架构设计,制定统一的机器人控制开发规范。任意机器人平台只要遵循该规范完成适配开发,即可无缝兼容ROS所有上层应用,大幅提升机器人开发的代码复用率、开发效率与系统灵活性。

2.2 ros_control分层架构与数据流

ros_control采用分层解耦设计,核心分为五大层级,层级之间各司其职、互不干扰,核心数据流自上而下闭环流转:

  1. Controller Manager(控制器管理器):核心管理调度单元,单台机器人可搭载底盘、传感器、机械臂等多个控制器,该管理器提供统一通用接口,集中管理所有控制器的启动、停止、切换与调度,直接接收ROS上层应用下发的控制指令。

  2. Controller(控制器):具体控制执行单元,支持底盘差速控制、关节位置控制、速度控制等多类型控制模式,内置PID控制算法。主要负责向下层硬件资源请求控制权限,读取硬件实时状态数据,运算后下发精准控制执行指令。

  3. Hardware Resource(硬件资源接口):上下层衔接中间接口,标准化封装机器人所有硬件及仿真资源,为控制器与硬件抽象层提供统一数据交互通道。

  4. RobotHW(硬件抽象层):直接对接真实硬件或Gazebo仿真硬件的核心层级,通过read、write标准方法完成硬件数据读取与控制指令下发,同时内置关节限位、力矩转换、状态数据转换等基础防护与数据处理功能。

  5. Real Robot(真实机器人硬件):底层执行载体,搭载嵌入式下位机控制器,接收上层转发的控制指令后,驱动电机、传感器等执行器完成对应动作,反馈实时运行状态数据。

2.3 ros_control核心功能包组成

ros_control由多个专用功能包模块化组成,各司其职支撑控制全流程运行,核心包含:combined_robot_hw硬件集成包、controller_interface控制器基础接口、controller_manager控制器管理核心包、controller_manager_msg控制器消息定义包、hardware_interface底层硬件接口、joint_limits_interface关节限位防护接口、transmission_interface传动装置适配接口、realtime_tools实时控制工具包。整体通过通用控制循环回调机制,依托PID控制器完成关节数据闭环控制,适配上位机、下位机双模式控制部署。

三、Gazebo仿真前期准备:功能包创建与依赖配置

Gazebo是ROS生态适配度最高的通用仿真环境,支持室内外复杂场景机器人物理仿真、传感器数据仿真,可完美复刻真机运行物理规律。首先需准备专用仿真开发功能包,导入必备依赖环境。

可复用原有机器人描述功能包,或新建专属功能包,功能包必须导入核心依赖:urdf、xacro、gazebo_ros、gazebo_ros_control、gazebo_plugins,分别用于机器人模型描述、模块化模型编译、Gazebo与ROS联动、ros_control仿真适配、传感器仿真插件支持。

四、机器人本体Gazebo仿真Xacro文件配置

Rviz可视化模型与Gazebo仿真模型配置要求差异极大,Gazebo仿真必须为机器人每个link刚体补充惯性属性、碰撞属性、Gazebo专属外观属性,同时配置传动装置与两轮差速运动控制器,否则机器人会出现仿真抖动、悬空、无法运动、无物理碰撞等问题。

4.1 Gazebo仿真三大必备核心配置说明

  1. collision碰撞标签:仿真碰撞检测核心依据,Gazebo物理仿真必须依赖该标签完成机器人与环境、机器人各部件之间的碰撞交互检测,不可省略;简单规则模型可与visual可视化标签参数一致,复杂真机模型需简化碰撞模型降低仿真算力消耗。

  2. inertial惯性标签:物理力学仿真核心参数,包含刚体质量与惯性矩阵,用于Gazebo计算机器人重力、运动惯性、力矩等力学数据。除base_footprint虚拟基座外,所有刚体link必须配置,且惯性矩阵需按规则物体公式计算生成,随意填写会导致机器人仿真抖动、自主漂移。

  3. gazebo外观标签:Gazebo专属模型颜色配置,Rviz中visual标签的material颜色参数无法在Gazebo生效,必须单独通过该标签设置模型材质,否则仿真模型默认显示灰白色。

4.2 标准惯性矩阵Xacro宏定义封装

针对机器人常用球体、圆柱体、立方体刚体,提前封装惯性矩阵计算宏,直接调用即可自动生成合规惯性参数,无需手动计算,适配仿真力学要求。

<!-- 球体惯性矩阵宏定义 -->
<xacro:macro name="sphere_inertial_matrix" params="m r">
    <inertial>
        <mass value="${m}" />
        <inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"
            iyy="${2*m*r*r/5}" iyz="0" 
            izz="${2*m*r*r/5}" />
    </inertial>
</xacro:macro>

<!-- 圆柱体惯性矩阵宏定义 -->
<xacro:macro name="cylinder_inertial_matrix" params="m r h">
    <inertial>
        <mass value="${m}" />
        <inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0"
            iyy="${m*(3*r*r+h*h)/12}" iyz = "0"
            izz="${m*r*r/2}" /> 
    </inertial>
</xacro:macro>

<!-- 立方体惯性矩阵宏定义 -->
<xacro:macro name="Box_inertial_matrix" params="m l w h">
    <inertial>
        <mass value="${m}" />
        <inertia ixx="${m*(h*h + l*l)/12}" ixy = "0" ixz = "0"
            iyy="${m*(w*w + l*l)/12}" iyz= "0"
            izz="${m*(w*w + h*h)/12}" />
    </inertial>
</xacro:macro>

4.3 机器人本体仿真核心xqrobot_base_gazebo.xacro完整配置

在xqrobot_description/urdf/xacro路径下新建gazebo文件夹,创建机器人本体仿真专属Xacro文件,定义机器人基座、驱动轮、支撑轮参数,配置传动装置与两轮差速驱动控制器,绑定速度控制接口。

xqrobot_base_gazebo.xacro

<?xml version="1.0"?>
<robot name="xqbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <!-- 基础参数常量定义 -->
    <xacro:property name="M_PI" value="3.1415926"/>
    <xacro:property name="base_mass"   value="20" /> 
    <xacro:property name="base_radius" value="0.20"/>
    <xacro:property name="base_length" value="0.16"/>
    <xacro:property name="wheel_mass"   value="2" />
    <xacro:property name="wheel_radius" value="0.06"/>
    <xacro:property name="wheel_length" value="0.025"/>
    <xacro:property name="wheel_joint_y" value="0.19"/>
    <xacro:property name="wheel_joint_z" value="0.05"/>
    <xacro:property name="caster_mass"    value="0.5" /> 
    <xacro:property name="caster_radius"  value="0.015"/>
    <xacro:property name="caster_joint_x" value="0.18"/>

    <!-- 机器人材质定义 -->
    <material name="yellow"><color rgba="1 0.4 0 1"/></material>
    <material name="black"><color rgba="0 0 0 0.95"/></material>
    <material name="gray"><color rgba="0.75 0.75 0.75 1"/></material>
    
    <!-- 惯性矩阵宏定义(上文已封装,此处直接调用) -->
    <xacro:macro name="sphere_inertial_matrix" params="m r">
        <inertial>
            <mass value="${m}" />
            <inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0" iyy="${2*m*r*r/5}" iyz="0" izz="${2*m*r*r/5}" />
        </inertial>
    </xacro:macro>
    <xacro:macro name="cylinder_inertial_matrix" params="m r h">
        <inertial>
            <mass value="${m}" />
            <inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0" iyy="${m*(3*r*r+h*h)/12}" iyz = "0" izz="${m*r*r/2}" /> 
        </inertial>
    </xacro:macro>

    <!-- 驱动轮宏定义(含关节、碰撞、惯性、传动配置) -->
    <xacro:macro name="wheel" params="prefix reflect">
        <joint name="${prefix}_wheel_joint" type="continuous">
            <origin xyz="0 ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0"/>
            <parent link="base_link"/>
            <child link="${prefix}_wheel_link"/>
            <axis xyz="0 1 0"/>
        </joint>
        <link name="${prefix}_wheel_link">
            <visual><origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${wheel_radius}" length = "${wheel_length}"/></geometry><material name="gray" /></visual>
            <collision><origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${wheel_radius}" length = "${wheel_length}"/></geometry></collision>
            <cylinder_inertial_matrix  m="${wheel_mass}" r="${wheel_radius}" h="${wheel_length}" />
        </link>
        <gazebo reference="${prefix}_wheel_link"><material>Gazebo/Gray</material></gazebo>
        <!-- 传动装置:关联关节与控制器核心配置 -->
        <transmission name="${prefix}_wheel_joint_trans">
            <type>transmission_interface/SimpleTransmission</type>
            <joint name="${prefix}_wheel_joint" ><hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface></joint>
            <actuator name="${prefix}_wheel_joint_motor"><hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface><mechanicalReduction>1</mechanicalReduction></actuator>
        </transmission>
    </xacro:macro>

    <!-- 支撑脚轮宏定义 -->
    <xacro:macro name="caster" params="prefix reflect">
        <joint name="${prefix}_caster_joint" type="continuous">
            <origin xyz="${(reflect*caster_joint_x)} 0 ${-(base_length/2 + caster_radius)}" rpy="0 0 0"/>
            <parent link="base_link"/>
            <child link="${prefix}_caster_link"/>
            <axis xyz="0 1 0"/>
        </joint>
        <link name="${prefix}_caster_link">
            <visual><origin xyz="0 0 0" rpy="0 0 0"/><geometry><sphere radius="${caster_radius}" /></geometry><material name="black" /></visual>
            <collision><origin xyz="0 0 0" rpy="0 0 0"/><geometry><sphere radius="${caster_radius}" /></geometry></collision>      
            <sphere_inertial_matrix  m="${caster_mass}" r="${caster_radius}" />
        </link>
        <gazebo reference="${prefix}_caster_link"><material>Gazebo/Black</material></gazebo>
    </xacro:macro>

    <!-- 机器人本体核心宏定义 -->
    <xacro:macro name="xqrobot_base_gazebo">
        <link name="base_footprint"><visual><origin xyz="0 0 0" rpy="0 0 0" /><geometry><box size="0.001 0.001 0.001" /></geometry></visual></link>
        <gazebo reference="base_footprint"><turnGravityOff>false</turnGravityOff></gazebo>
        <joint name="base_footprint_joint" type="fixed"><origin xyz="0 0 ${base_length/2 + caster_radius*2}" rpy="0 0 0" /><parent link="base_footprint"/><child link="base_link" /></joint>
        <link name="base_link">
            <visual><origin xyz=" 0 0 0" rpy="0 0 0" /><geometry><cylinder length="${base_length}" radius="${base_radius}"/></geometry><material name="yellow" /></visual>
            <collision><origin xyz=" 0 0 0" rpy="0 0 0" /><geometry><cylinder length="${base_length}" radius="${base_radius}"/></geometry></collision>   
            <cylinder_inertial_matrix  m="${base_mass}" r="${base_radius}" h="${base_length}" />
        </link>
        <gazebo reference="base_link"><material>Gazebo/Blue</material></gazebo>
        <wheel prefix="left"  reflect="-1"/>
        <wheel prefix="right" reflect="1"/>
        <caster prefix="front" reflect="-1"/>
        <caster prefix="back" reflect="1"/>
        <!-- 两轮差速运动控制器核心插件配置 -->
        <gazebo>
            <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
                <rosDebugLevel>Debug</rosDebugLevel>
                <publishWheelTF>true</publishWheelTF>
                <robotNamespace>/</robotNamespace>
                <publishTf>1</publishTf>
                <publishWheelJointState>true</publishWheelJointState>
                <alwaysOn>true</alwaysOn>
                <updateRate>100.0</updateRate>
                <legacyMode>true</legacyMode>
                <leftJoint>left_wheel_joint</leftJoint>
                <rightJoint>right_wheel_joint</rightJoint>
                <wheelSeparation>${wheel_joint_y*2}</wheelSeparation>
                <wheelDiameter>${2*wheel_radius}</wheelDiameter>
                <broadcastTF>1</broadcastTF>
                <wheelTorque>30</wheelTorque>
                <wheelAcceleration>1.8</wheelAcceleration>
                <commandTopic>cmd_vel</commandTopic>
                <odometryFrame>odom</odometryFrame> 
                <odometryTopic>odom</odometryTopic> 
                <robotBaseFrame>base_footprint</robotBaseFrame>
            </plugin>
        </gazebo> 
    </xacro:macro>
</robot>

针对机器人模型,需要对每一个 link 添加标签,包含的属性仅有material。material 属性的作用与 link 里中 material 属性的作用相同,Gazebo 无法通过中的 material 参数设置外观颜色,所以需要单独设置,否则默认情况下 Gazebo 中显示的模型全是灰白色。

为 joint 添加传动装置以及控制器-两轮差速配置

<!-- 控制器 -->
    <gazebo>
        <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
            <rosDebugLevel>Debug</rosDebugLevel>
            <publishWheelTF>true</publishWheelTF>
            <robotNamespace>/</robotNamespace>
            <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>base_footprint</robotBaseFrame> <!-- 根坐标系 -->
        </plugin>
    </gazebo>

</robot>

五、传感器Gazebo仿真插件配置

机器人本体配置完成后,需单独配置激光雷达、摄像头传感器仿真文件,通过Gazebo传感器插件实现仿真环境下真实传感器数据输出,自动发布ROS标准传感器话题。

5.1 激光雷达仿真配置(lidar_gazebo.xacro)

提前在xqrobot_description/meshes目录放入hokuyo.dae雷达模型文件,在urdf/xacro/sensors目录创建雷达仿真配置文件,配置雷达探测范围、采样频率、噪声参数及ROS话题发布插件。

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="lidar">
    <xacro:macro name="hokuyo_lidar" params="prefix:=lidar">
            <link name="hokuyo_link">
                <collision>
                    <origin xyz="0 0 0" rpy="0 0 0"/>
                    <geometry>
                        <box size="0.1 0.1 0.1"/>
                    </geometry>
                </collision>
                <visual>
                    <origin xyz="0 0 0" rpy="0 0 0"/>
                    <geometry>
                        <mesh filename="package://xqrobot_description/meshes/hokuyo.dae"/>
                    </geometry>
                </visual>
                <inertial>
                    <mass value="1e-5" />
                    <origin xyz="0 0 0" rpy="0 0 0"/>
                    <inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6" />
                </inertial>
            </link>
            <gazebo reference="hokuyo_link">
            <material>Gazebo/Black</material>
        </gazebo>


            <gazebo reference="hokuyo_link">
                <sensor type="ray" name="head_hokuyo_sensor">
                  <pose>0 0 0 0 0 0</pose>
                  <visualize>false</visualize>
                  <update_rate>40</update_rate>
                  <ray>
                    <scan>
                      <horizontal>
                        <samples>720</samples>
                        <resolution>1</resolution>
                        <min_angle>-1.570796</min_angle>
                        <max_angle>1.570796</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_ros_head_hokuyo_controller" filename="libgazebo_ros_laser.so">
                    <topicName>/scan</topicName>
                    <frameName>hokuyo_link</frameName>
                  </plugin>
                </sensor>
              </gazebo>
    </xacro:macro>
</robot>

5.2 摄像头仿真配置(camera_gazebo.xacro)

同目录下创建摄像头仿真配置文件,配置摄像头分辨率、视场角、成像参数及图像数据发布插件,仿真输出彩色图像与相机内参话题。

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="camera">
    <xacro:macro name="usb_camera" params="prefix:=camera">
        <!-- Create laser reference frame -->
        <link name="${prefix}_link">
            <inertial>
                <mass value="0.1" />
                <origin xyz="0 0 0" />
                <inertia ixx="0.01" ixy="0.0" ixz="0.0"
                         iyy="0.01" iyz="0.0"
                         izz="0.01" />
            </inertial>
            <visual>
                <origin xyz=" 0 0 0 " rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.04 0.04" />
                </geometry>
                <material name="black"/>
            </visual>
            <collision>
                <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.04 0.04" />
                </geometry>
            </collision>
        </link>
        <gazebo reference="${prefix}_link">
            <material>Gazebo/Black</material>
        </gazebo>
        <gazebo reference="${prefix}_link">
            <sensor type="camera" name="camera_node">
                <update_rate>30.0</update_rate>
                <camera name="head">
                    <horizontal_fov>1.3962634</horizontal_fov>
                    <image>
                        <width>1280</width>
                        <height>720</height>
                        <format>R8G8B8</format>
                    </image>
                    <clip>
                        <near>0.02</near>
                        <far>300</far>
                    </clip>
                    <noise>
                        <type>gaussian</type>
                        <mean>0.0</mean>
                        <stddev>0.007</stddev>
                    </noise>
                </camera>
                <plugin name="gazebo_camera" filename="libgazebo_ros_camera.so">
                    <alwaysOn>true</alwaysOn>
                    <updateRate>0.0</updateRate>
                    <cameraName>/camera</cameraName>
                    <imageTopicName>image_raw</imageTopicName>
                    <cameraInfoTopicName>camera_info</cameraInfoTopicName>
                    <frameName>camera_link</frameName>
                    <hackBaseline>0.07</hackBaseline>
                    <distortionK1>0.0</distortionK1>
                    <distortionK2>0.0</distortionK2>
                    <distortionK3>0.0</distortionK3>
                    <distortionT1>0.0</distortionT1>
                    <distortionT2>0.0</distortionT2>
                </plugin>
            </sensor>
        </gazebo>

    </xacro:macro>
</robot>

5.3 机器人与传感器整机组合配置(xqrobot_gazebo.xacro)

汇总机器人本体、激光雷达、摄像头仿真配置,设置传感器安装偏移坐标,通过固定关节绑定传感器与机器人基座,形成完整仿真机器人模型。

<?xml version="1.0"?>
<robot name="xqbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
 <xacro:include filename="$(find xqrobot_description)/urdf/xacro/gazebo/xqrobot_base_gazebo.xacro" />
 <xacro:include filename="$(find xqrobot_description)/urdf/xacro/sensors/lidar_gazebo.xacro" />
  <xacro:include filename="$(find xqrobot_description)/urdf/xacro/sensors/camera_gazebo.xacro" />
<xacro:property name="camera_offset_x" value="0.18" />
<xacro:property name="camera_offset_y" value="0" />
<xacro:property name="camera_offset_z" value="0.09" />
 <xacro:property name="lidar_offset_x" value="0.1" />
 <xacro:property name="lidar_offset_y" value="0" />
 <xacro:property name="lidar_offset_z" value="0.10" />
<xqrobot_base_gazebo/>
 <joint name="camera_joint" type="fixed"><origin xyz="${camera_offset_x} ${camera_offset_y} ${camera_offset_z}" rpy="0 0 0" /><parent link="base_link"/><child link="camera_link"/></joint>
  <xacro:usb_camera prefix="camera"/>
 <joint name="lidar_joint" type="fixed"><origin xyz="${lidar_offset_x} ${lidar_offset_y} ${lidar_offset_z}" rpy="0 0 0" /><parent link="base_link"/><child link="hokuyo_link"/></joint>
    <xacro:hokuyo_lidar prefix="lidar"/>
</robot>

六、仿真启动Launch文件配置与运行实操

6.1 前期文件准备

  1. 在xqrobot_description目录新建worlds文件夹,放入仿真场景room.world/racecar_ar.world场景文件;

  2. 在launch目录新建gazebo文件夹,创建仿真启动launch文件,关联Gazebo环境、机器人模型、TF发布、Rviz可视化配置。

6.2 仿真启动display_xqrobot_gazebo.launch配置

<launch>
    <arg name="paused" default="false"/>
    <arg name="use_sim_time" default="true"/>
    <arg name="gui" default="true"/>
    <arg name="headless" default="false"/>
    <arg name="debug" default="false"/>
    <!-- 启动Gazebo仿真环境 -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch">
         <arg name="debug" value="$(arg debug)" />
        <arg name="gui" value="$(arg gui)" />
        <arg name="paused" value="$(arg paused)"/>
        <arg name="use_sim_time" value="$(arg use_sim_time)"/>
        <arg name="headless" value="$(arg headless)"/>
        <arg name="world_name" value="$(find xqrobot_description)/worlds/racecar_ar.world"/>
    </include>
    <!-- 加载机器人仿真模型 -->
    <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find xqrobot_description)/urdf/xacro/gazebo/xqrobot_gazebo.xacro'" /> 
    <!-- 发布关节状态、TF坐标变换 -->
    <node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" ></node> 
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen" ><param name="publish_frequency" type="double" value="50.0" /></node>
    <!-- 在Gazebo中生成机器人模型 -->
    <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen" args="-urdf -model mrobot -param robot_description"/> 
    <!-- 启动Rviz可视化 -->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find xqrobot_description)/config/xqrobot_urdf.rviz" required="true" />
</launch>

6.3 仿真启动与机器人运动控制指令

  1. 启动整体仿真环境:

    roslaunch xqrobot_description display_xqrobot_gazebo.launch

  2. 查看仿真话题列表,确认/cmd_vel控制话题、/scan雷达话题、/odom里程计话题正常发布;

  3. 命令行发布速度指令控制机器人运动:

    rostopic pub -r 10 /cmd_vel geometry_msgs/Twist '{linear: {x: 0.2, y: 0, z: 0}, angular: {x: 0, y: 0, z: 0.5}}'

  1. 可视化TF坐标树:

    rosrun rqt_tf_tree rqt_tf_tree

  2. 查看节点与话题关联关系:

    rosrun rqt_graph rqt_graph

  3. 安装遥控功能包并键盘控制:源码安装https://gitee.com/hanzq03/xqrobot.git,执行roslaunch xqrobot_teleop xqrobot_teleop.launch 键盘遥控机器人运动。

七、Rviz里程计信息可视化查看

Gazebo仿真环境仅负责机器人物理运动与数据仿真输出,无法直接可视化机器人位姿状态。启动仿真后,在自动弹出的Rviz界面中,添加里程计、机器人模型、TF坐标等可视化组件,选择对应话题数据源,即可实时查看机器人相对原点的X/Y坐标、运动朝向等里程计信息,直观校验机器人运动控制精度与仿真运行状态。

https://gitee.com/hanzq03/xqrobot.git

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐