前言
本系列博文是本人的学习笔记,自用为主,不是教程,学习请移步其他大佬的相关教程。前几篇学习资源来自鱼香ROS大佬的详细教程,适合深入学习,但对本人这样的初学者不算友好,后续笔记将以@古月居的ROS2入门21讲为主,侵权即删。
一、学习目标
- 理解 Gazebo 的核心价值 ------ 没有实物机器人时,也能做物理仿真(模拟运动、环境交互)
- 掌握 Gazebo 的安装与基础启动(解决离线模型加载问题)
- 学会用 XACRO 优化 URDF(解决 URDF 重复代码多、维护难的痛点)
- 掌握 Gazebo 仿真模型的必备配置(惯性、碰撞、传动、控制器插件)
- 能独立完成 "移动机器人 Gazebo 仿真 + 键盘控制" 的完整流程
- 了解下一代仿真器 Ignition 的基本使用
二、Gazebo 是什么?
2.1 一句话定义:机器人的 "虚拟试验场"
Gazebo 是 ROS 生态中最常用的三维物理仿真平台,能模拟真实世界的物理规则(重力、摩擦力、碰撞),让虚拟机器人在虚拟环境中运动,就像在真实世界一样。
2.2 为什么需要 Gazebo?(解决初学者的痛点)
痛点场景 | Gazebo 的解决方案 | 例子 |
---|---|---|
没有实物机器人 | 用虚拟机器人做开发、测试 | 没买移动机器人,也能调试导航算法 |
实物测试危险 / 成本高 | 模拟高危场景(如碰撞、悬崖) | 测试无人机避障,不用担心摔机 |
需要重复测试相同场景 | 保存 / 加载仿真环境,精确复现测试条件 | 每次测试都用同一个 "客厅" 环境 |
需要模拟复杂环境 | 加载地图、障碍物、光照等环境元素 | 模拟火星表面环境,测试火星车运动 |
三、Gazebo 基础:安装与启动
3.1 安装步骤(以 ROS2 Humble 为例)
1. 安装 Gazebo 核心包
打开终端,执行命令:
# 安装ROS2 Humble对应的Gazebo包(包含核心功能和ROS接口)
sudo apt install ros-humble-gazebo-*
2. 解决 "离线模型加载慢" 问题(关键!)
Gazebo 第一次启动时会在线下载模型(如桌子、椅子),速度很慢,建议提前下载离线模型:
-
下载离线模型包(GitHub 链接):
git clone https://github.com/osrf/gazebo_models.git ~/.gazebo/models
-
等待下载完成(约 1GB,耐心等待),之后启动 Gazebo 会直接加载本地模型。
3. 验证安装
启动 Gazebo 空环境,测试是否正常:
# 启动Gazebo(带ROS2接口)
ros2 launch gazebo_ros gazebo.launch.py
- 预期效果:弹出 Gazebo 窗口,显示空旷的仿真环境(地面是网格),无报错。
3.2 Gazebo 窗口基础操作
操作需求 | 鼠标 / 键盘操作 |
---|---|
旋转视角 | 按住鼠标左键拖动 |
平移视角 | 按住鼠标中键拖动 |
缩放视角 | 滚动鼠标滚轮 |
选中物体(如机器人) | 单击鼠标左键 |
移动选中物体 | 按住鼠标右键拖动 |
关闭 Gazebo | 关闭窗口,或终端按Ctrl+C |
四、XACRO:优化 URDF 的 "编程化工具"
URDF 虽然能描述机器人,但存在重复代码多、参数难维护的问题(比如 4 个轮子要写 4 遍相同代码)。XACRO(XML Macro)是 URDF 的升级版本,支持 "编程化" 特性,让模型编写更高效。
4.1 XACRO 的核心优势(对比 URDF)
特性 | URDF 的问题 | XACRO 的解决方案 | 小白类比 |
---|---|---|---|
重复代码多 | 4 个轮子要写 4 遍<link> 和<joint> |
宏定义(xacro:macro ),写 1 次复用 4 次 |
像函数定义,调用时传参数就行 |
参数难修改 | 改轮子半径要找遍所有相关代码 | 常量定义(xacro:property ),改 1 处全生效 |
像编程中的全局变量,改变量值即可 |
无计算能力 | 轮距 = 2× 轮中心 y 坐标,需手动算 | 支持数学计算(${a+b} ),自动算结果 |
像 Excel 公式,输入表达式自动计算 |
大文件难维护 | 整个机器人写在 1 个 URDF 里,找代码麻烦 | 文件包含(xacro:include ),分模块管理 |
像 C 语言的#include ,分文件写代码 |
4.2 XACRO 核心语法
1. 常量定义(xacro:property
)
作用 :定义不变的参数(如轮子半径、底盘质量),方便后续修改。语法:
<!-- 定义常量:名字="参数名",值="参数值" -->
<xacro:property name="M_PI" value="3.1415926"/> <!-- 圆周率 -->
<xacro:property name="wheel_radius" value="0.06"/> <!-- 轮子半径0.06米 -->
<xacro:property name="base_mass" value="1.0"/> <!-- 底盘质量1千克 -->
<!-- 调用常量:用${参数名} -->
<geometry>
<!-- 圆柱体半径=wheel_radius(调用常量) -->
<cylinder radius="${wheel_radius}" length="0.025"/>
</geometry>
2. 数学计算(${表达式}
)
作用 :自动计算参数(如轮距 = 2× 轮子 y 坐标),避免手动计算错误。支持运算 :+
-
*
/
()
(优先级),自动转浮点数。例子:
<!-- 定义轮子中心到底盘中心的y距离 -->
<xacro:property name="wheel_joint_y" value="0.19"/>
<!-- 轮距=2×wheel_joint_y(左右轮之间的距离) -->
<xacro:property name="wheel_separation" value="${2 * wheel_joint_y}"/>
<!-- 调用计算结果(Gazebo差速控制器用) -->
<wheel_separation>${wheel_separation}</wheel_separation>
3. 宏定义(xacro:macro
)
作用 :将重复的代码(如轮子的<link>
和<joint>
)封装成 "模块",调用时传参数即可。语法:
<!-- 1. 定义宏:name=宏名,params=参数(多个参数用空格分隔) -->
<xacro:macro name="wheel" params="prefix reflect">
<!-- prefix:轮子前缀(如left/right),reflect:左右对称(1/-1) -->
<!-- 关节:名字=prefix_wheel_joint(如left_wheel_joint) -->
<joint name="${prefix}_wheel_joint" type="continuous">
<!-- 位置:y=reflect×wheel_joint_y(左右轮对称,reflect=1是左轮,-1是右轮) -->
<origin xyz="0 ${reflect*wheel_joint_y} -0.05" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="${prefix}_wheel_link"/> <!-- 连杆名=prefix_wheel_link -->
<axis xyz="0 1 0"/> <!-- 绕y轴旋转 -->
</joint>
<!-- 连杆:名字=prefix_wheel_link -->
<link name="${prefix}_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0"/> <!-- 旋转90度,让圆柱体立起来 -->
<geometry>
<cylinder radius="${wheel_radius}" length="0.025"/> <!-- 调用常量 -->
</geometry>
</visual>
</link>
</xacro:macro>
<!-- 2. 调用宏:传参数prefix和reflect -->
<xacro:wheel prefix="left" reflect="1"/> <!-- 左轮:reflect=1(y正方向) -->
<xacro:wheel prefix="right" reflect="-1"/> <!-- 右轮:reflect=-1(y负方向) -->
4. 文件包含(xacro:include
)
作用 :将大模型拆分成多个小文件(如底盘、相机、雷达),方便维护。语法:
<!-- 主文件:mbot_gazebo.xacro -->
<?xml version="1.0"?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- 包含底盘模块文件(路径:learning_gazebo/urdf/mbot_base_gazebo.xacro) -->
<xacro:include filename="$(find learning_gazebo)/urdf/mbot_base_gazebo.xacro" />
<!-- 调用底盘宏(在mbot_base_gazebo.xacro中定义) -->
<xacro:mbot_base_gazebo/>
</robot>
4.3 XACRO 安装与验证
1. 安装 XACRO 工具
sudo apt install ros-humble-xacro
2. 验证 XACRO 文件(转 URDF)
XACRO 文件不能直接用,需要转成 URDF 格式,命令:
# 格式:xacro 输入XACRO文件 > 输出URDF文件
xacro learning_gazebo/urdf/mbot_gazebo.xacro > mbot_gazebo.urdf
- 若没有报错,生成
mbot_gazebo.urdf
,说明 XACRO 语法正确。
五、Gazebo 仿真模型配置(关键!URDF→Gazebo 可用)
XACRO 模型还需要添加物理参数 和Gazebo 专属配置,否则加载到 Gazebo 会飘起来、不能动。核心配置有 4 步:
5.1 1. 完善物理参数(惯性 + 碰撞)
Gazebo 是物理仿真,必须给每个<link>
加惯性(inertial) 和碰撞(collision):
- 惯性(inertial):描述物体的质量和惯性(如底盘重 1kg,转动时的阻力),没有会飘起来;
- 碰撞(collision):描述物体的碰撞形状(简化版,比如用长方体代替复杂外壳),没有会穿模。
例子(用 XACRO 宏定义惯性):
<!-- 定义圆柱体惯性宏:m=质量,r=半径,h=长度 -->
<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>
<!-- 调用宏:底盘惯性(质量1kg,半径0.2m,长度0.16m) -->
<link name="base_link">
<collision>
<geometry>
<cylinder radius="${base_radius}" length="${base_length}"/> <!-- 碰撞形状=底盘形状 -->
</geometry>
</collision>
<!-- 调用惯性宏 -->
<xacro:cylinder_inertial_matrix m="${base_mass}" r="${base_radius}" h="${base_length}" />
</link>
5.2 2. 添加 Gazebo 颜色标签(gazebo
)
URDF 的颜色(material
)在 Gazebo 中不生效,需要用<gazebo>
标签重新设置:
<!-- 格式:<gazebo reference="link名"> 配置Gazebo属性 -->
<gazebo reference="base_link">
<material>Gazebo/Blue</material> <!-- Gazebo预设颜色:蓝色 -->
</gazebo>
<gazebo reference="left_wheel_link">
<material>Gazebo/Gray</material> <!-- 轮子颜色:灰色 -->
</gazebo>
- Gazebo 预设颜色:
Gazebo/Red
、Gazebo/Green
、Gazebo/Blue
、Gazebo/Gray
等。
5.3 3. 配置传动装置(transmission
)
传动装置是 "电机" 和 "关节" 的桥梁,告诉 Gazebo "哪个关节由哪个电机驱动":
<transmission name="left_wheel_joint_trans">
<type>transmission_interface/SimpleTransmission</type> <!-- 简单传动类型 -->
<joint name="left_wheel_joint" > <!-- 关联的关节:左轮关节 -->
<!-- 硬件接口:速度控制(控制关节的角速度) -->
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
</joint>
<actuator name="left_wheel_joint_motor"> <!-- 电机名字 -->
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction> <!-- 减速比:1=无减速 -->
</actuator>
</transmission>
5.4 4. 添加 Gazebo 控制器插件(gazebo plugin
)
控制器插件负责 "计算电机速度",比如移动机器人的差速控制器 (根据cmd_vel
指令,计算左右轮的角速度):
<gazebo>
<!-- 差速控制器插件:文件名固定,不用改 -->
<plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
<update_rate>30</update_rate> <!-- 控制频率:30Hz -->
<left_joint>left_wheel_joint</left_joint> <!-- 左轮关节名 -->
<right_joint>right_wheel_joint</right_joint> <!-- 右轮关节名 -->
<wheel_separation>${2*wheel_joint_y}</wheel_separation> <!-- 轮距(左右轮距离) -->
<wheel_diameter>${2*wheel_radius}</wheel_diameter> <!-- 轮子直径 -->
<max_wheel_torque>20</max_wheel_torque> <!-- 最大扭矩(防止电机过载) -->
<command_topic>cmd_vel</command_topic> <!-- 接收速度指令的话题:/cmd_vel -->
<publish_odom>true</publish_odom> <!-- 发布里程计信息 -->
<odometry_topic>odom</odometry_topic> <!-- 里程计话题名:/odom -->
<robot_base_frame>base_footprint</robot_base_frame> <!-- 机器人基础坐标系 -->
</plugin>
</gazebo>
- 关键:
command_topic="cmd_vel"
表示插件会订阅/cmd_vel
话题,接收速度指令(线速度 x、角速度 z)。
六、实战:移动机器人 Gazebo 仿真(完整流程)
6.1 步骤 1:创建功能包与文件结构
learning_gazebo/ # 功能包名
├── urdf/ # XACRO文件
│ ├── mbot_gazebo.xacro # 主XACRO文件(包含底盘)
│ └── mbot_base_gazebo.xacro # 底盘XACRO文件(含物理参数、插件)
├── launch/ # Launch文件
│ └── load_urdf_into_gazebo.launch.py # 启动仿真的Launch
└── worlds/ # Gazebo世界文件(可选,默认是空环境)
└── neighborhood.world # 小区环境(示例)
6.2 步骤 2:解析 Launch 文件(load_urdf_into_gazebo.launch.py
)
Launch 文件一键启动所有节点(Gazebo、加载模型、发布 TF),代码带详细注释:
python
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
def generate_launch_description():
# 1. 获取功能包路径(自动找到learning_gazebo的位置)
package_name = 'learning_gazebo'
pkg_path = get_package_share_directory(package_name)
# 2. 世界文件路径(可选:用自定义环境,如小区;默认是空环境,可注释)
world_file_path = 'worlds/neighborhood.world'
world_path = os.path.join(pkg_path, world_file_path)
# 3. 机器人初始位置(x=0, y=0, z=0,朝向yaw=0)
spawn_x = '0.0'
spawn_y = '0.0'
spawn_z = '0.0'
spawn_yaw = '0.0'
# 4. 包含底盘XACRO的Launch(若有单独的底盘Launch,可包含)
mbot_launch = IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
pkg_path, 'launch', 'mbot.launch.py' # 底盘Launch(可选,无则注释)
)]),
launch_arguments={'use_sim_time': 'true', 'world': world_path}.items() # 启用仿真时间
)
# 5. 启动Gazebo(加载世界环境)
gazebo_launch = IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
get_package_share_directory('gazebo_ros'), 'launch', 'gazebo.launch.py'
)])
)
# 6. 加载机器人模型到Gazebo(关键节点:spawn_entity)
spawn_robot = Node(
package='gazebo_ros',
executable='spawn_entity.py',
arguments=[
'-topic', 'robot_description', # 从/robot_description话题获取模型
'-entity', 'mbot', # 机器人在Gazebo中的名字
'-x', spawn_x, '-y', spawn_y, '-z', spawn_z, '-Y', spawn_yaw # 初始位置
],
output='screen' # 打印日志到终端
)
# 7. 启动关节状态发布节点(带GUI,可拖动关节)
joint_state_pub = Node(
package='joint_state_publisher_gui',
executable='joint_state_publisher_gui'
)
# 8. 启动机器人状态发布节点(发布TF树,Gazebo需要)
robot_state_pub = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
arguments=[os.path.join(pkg_path, 'urdf', 'mbot_gazebo.xacro')] # 传入XACRO文件
)
# 返回所有节点(顺序:先启动Gazebo,再加载模型)
return LaunchDescription([
joint_state_pub,
robot_state_pub,
gazebo_launch,
spawn_robot,
# mbot_launch # 若有底盘Launch,取消注释
])
6.3 步骤 3:启动仿真与控制
1. 编译功能包
cd dev_ws # 进入ROS工作空间
colcon build --packages-select learning_gazebo # 编译功能包
source install/setup.bash # 加载环境变量
2. 启动 Gazebo 仿真
ros2 launch learning_gazebo load_urdf_into_gazebo.launch.py
- 预期效果:Gazebo 窗口加载机器人模型(蓝色底盘 + 灰色轮子),无报错。
3. 启动键盘控制(新终端)
Gazebo 的差速控制器订阅/cmd_vel
话题,需要用键盘发布速度指令:
# 安装键盘控制包(若未安装)
sudo apt install ros-humble-teleop-twist-keyboard
# 启动键盘控制
ros2 run teleop_twist_keyboard teleop_twist_keyboard
4. 控制机器人运动
根据终端提示,用键盘按键控制:
i
:前进(线速度 x=0.5m/s),
(逗号):后退(线速度 x=-0.5m/s)j
:左转(角速度 z=1rad/s)l
:右转(角速度 z=-1rad/s)k
:停止
5. 虚拟机用户注意!(避坑)
若在虚拟机中运行 Gazebo 卡顿或黑屏,需关闭硬件加速:
# 临时关闭(当前终端生效)
export SVGA_VGPU10=0
# 永久关闭(写入.bashrc)
echo "export SVGA_VGPU10=0" >> ~/.bashrc
source ~/.bashrc
七、下一代仿真器:Ignition Gazebo
Gazebo 的下一代版本叫Ignition,渲染效果更好、仿真更流畅,安装和启动更简单:
7.1 安装 Ignition
sudo apt install ros-humble-ros-ign # ROS2 Humble对应版本
7.2 启动示例(RGBD 相机仿真)
ros2 launch ros_ign_gazebo_demos rgbd_camera_bridge.launch.py
- 预期效果:弹出 Ignition 窗口(带相机和立方体),同时启动 RViz 显示相机图像。
7.3 官方文档
更多 Ignition 使用方法:https://www.ignitionrobotics.org/
八、附录:完整 XACRO 模型解析(mbot_base_gazebo.xacro
)
关键代码逐段注释,帮助小白理解:
<?xml version="1.0"?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- 1. 常量定义:机器人所有固定参数(改这里全生效) -->
<xacro:property name="M_PI" value="3.1415926"/> <!-- 圆周率 -->
<xacro:property name="base_mass" value="1" /> <!-- 底盘质量1kg -->
<xacro:property name="base_radius" value="0.20"/> <!-- 底盘半径0.2m -->
<xacro:property name="base_length" value="0.16"/> <!-- 底盘长度0.16m -->
<xacro:property name="wheel_mass" value="0.2" /> <!-- 轮子质量0.2kg -->
<xacro:property name="wheel_radius" value="0.06"/> <!-- 轮子半径0.06m -->
<xacro:property name="wheel_length" value="0.025"/> <!-- 轮子宽度0.025m -->
<xacro:property name="wheel_joint_y" value="0.19"/> <!-- 轮子关节y坐标(距底盘中心) -->
<xacro:property name="wheel_joint_z" value="0.05"/> <!-- 轮子关节z坐标(距底盘底部) -->
<xacro:property name="caster_mass" value="0.2" /> <!-- 万向轮质量0.2kg -->
<xacro:property name="caster_radius" value="0.015"/> <!-- 万向轮半径0.015m -->
<xacro:property name="caster_joint_x" value="0.18"/> <!-- 万向轮关节x坐标(距底盘中心) -->
<!-- 2. 颜色定义(URDF用) -->
<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>
<!-- 3. 惯性宏定义(复用) -->
<!-- 球体惯性宏(万向轮用) -->
<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>
<!-- 4. 轮子宏定义(左轮、右轮复用) -->
<xacro:macro name="wheel" params="prefix reflect">
<!-- 轮子关节(continuous:无限旋转) -->
<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"/> <!-- 绕y轴旋转 -->
</joint>
<!-- 轮子连杆 -->
<link name="${prefix}_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /> <!-- 旋转90度,圆柱体立起 -->
<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>
<xacro:cylinder_inertial_matrix m="${wheel_mass}" r="${wheel_radius}" h="${wheel_length}" />
</link>
<!-- Gazebo颜色配置 -->
<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>
<!-- 5. 万向轮宏定义(前轮、后轮复用) -->
<xacro:macro name="caster" params="prefix reflect">
<joint name="${prefix}_caster_joint" type="fixed"> <!-- fixed:固定,不旋转 -->
<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"/>
</joint>
<link name="${prefix}_caster_link">
<visual><geometry><sphere radius="${caster_radius}" /></geometry><material name="black" /></visual>
<collision><geometry><sphere radius="${caster_radius}" /></geometry></collision>
<xacro:sphere_inertial_matrix m="${caster_mass}" r="${caster_radius}" />
</link>
<gazebo reference="${prefix}_caster_link"><material>Gazebo/Black</material></gazebo>
</xacro:macro>
<!-- 6. 底盘宏定义(主宏,包含所有部件) -->
<xacro:macro name="mbot_base_gazebo">
<!-- 基础坐标系(base_footprint:机器人与地面的接触点) -->
<link name="base_footprint">
<visual><geometry><box size="0.001 0.001 0.001" /></geometry></visual>
</link>
<gazebo reference="base_footprint"><turnGravityOff>false</turnGravityOff></gazebo>
<!-- 连接base_footprint和base_link -->
<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>
<geometry><cylinder length="${base_length}" radius="${base_radius}"/></geometry>
<material name="yellow" />
</visual>
<collision><geometry><cylinder length="${base_length}" radius="${base_radius}"/></geometry></collision>
<xacro:cylinder_inertial_matrix m="${base_mass}" r="${base_radius}" h="${base_length}" />
</link>
<gazebo reference="base_link"><material>Gazebo/Blue</material></gazebo>
<!-- 调用轮子宏(左轮、右轮) -->
<xacro:wheel prefix="left" reflect="1"/>
<xacro:wheel prefix="right" reflect="-1"/>
<!-- 调用万向轮宏(前轮、后轮) -->
<xacro:caster prefix="front" reflect="-1"/>
<xacro:caster prefix="back" reflect="1"/>
<!-- 7. Gazebo差速控制器插件(核心) -->
<gazebo>
<plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
<update_rate>30</update_rate>
<left_joint>left_wheel_joint</left_joint>
<right_joint>right_wheel_joint</right_joint>
<wheel_separation>${wheel_joint_y*2}</wheel_separation> <!-- 轮距=2×y坐标 -->
<wheel_diameter>${2*wheel_radius}</wheel_diameter> <!-- 直径=2×半径 -->
<max_wheel_torque>20</max_wheel_torque>
<max_wheel_acceleration>1.0</max_wheel_acceleration>
<command_topic>cmd_vel</command_topic> <!-- 接收速度指令 -->
<publish_odom>true</publish_odom> <!-- 发布里程计 -->
<odometry_topic>odom</odometry_topic>
<robot_base_frame>base_footprint</robot_base_frame>
</plugin>
</gazebo>
</xacro:macro>
</robot>
九、复习要点总结(小白必背)
- Gazebo 核心:物理仿真平台,需添加惯性、碰撞、传动、插件才能用;
- XACRO 核心语法 :
- 常量:
xacro:property
(定义参数); - 宏:
xacro:macro
(复用代码,如轮子); - 计算:
${表达式}
(自动算轮距、直径); - 包含:
xacro:include
(分模块管理);
- 常量:
- Gazebo 模型四步配置 :
- 加惯性(
inertial
):防飘; - 加碰撞(
collision
):防穿模; - 加 Gazebo 颜色(
gazebo
标签):显式正确; - 加传动 + 插件:让机器人动起来;
- 加惯性(
- 仿真流程 :编译→启动 Launch→键盘控制(
teleop_twist_keyboard
); - 避坑点:离线模型下载、虚拟机关闭硬件加速、XACRO 转 URDF 验证语法。
掌握这些,就能独立用 Gazebo 做移动机器人的仿真开发,后续可扩展导航、SLAM 等算法!
vi .bashrc 这个怎么用gredit打开
首先纠正一个小拼写:你说的 "gredit" 应该是 Linux 下的图形化文本编辑器 gedit (GNOME 桌面默认编辑器),下面分步骤教你用 gedit 打开 .bashrc
文件,小白也能轻松操作:
一、核心命令:用 gedit 打开 .bashrc
.bashrc
是用户主目录下的隐藏文件 (文件名以.
开头),直接用 gedit 加文件路径即可打开,步骤如下:
1. 打开终端
- 方法 1:桌面环境下,按
Ctrl + Alt + T
快捷键(通用 Linux 快捷键,比如 Ubuntu、Linux Mint 都适用); - 方法 2:从应用菜单找到 "终端"(Terminal)图标,点击打开。
2. 输入 gedit 命令
在终端中直接输入以下命令,按下回车:
gedit ~/.bashrc
- 命令解释:
gedit
:调用图形化文本编辑器;~
:代表你的用户主目录 (比如你的用户名是ubuntu
,~
就对应/home/ubuntu
);/.bashrc
:指定要打开的文件(.
开头表示隐藏文件,必须写全,不能漏了.
)。
3. 编辑与保存
- 按下回车后,会弹出 gedit 编辑器窗口,里面就是
.bashrc
的内容,直接编辑即可(比如添加 ROS 环境变量、自定义别名等); - 编辑完成后,按
Ctrl + S
保存,或点击窗口左上角的 "保存" 按钮; - 关闭 gedit 窗口即可。
二、关键补充:修改 .bashrc
后生效
修改 .bashrc
后(比如添加了 source /opt/ros/humble/setup.bash
),需要让修改立即生效,否则新打开的终端不会加载新配置,执行以下命令:
source ~/.bashrc
三、特殊情况:如果终端不在主目录,怎么办?
如果你的终端当前路径不是主目录(比如在 ~/dev_ws
下),直接输入 gedit .bashrc
会报错 "找不到文件",这时候有两种解决方法:
-
方法 1:用绝对路径 (推荐,不管当前路径在哪都能用):
gedit ~/.bashrc
-
方法 2:先回到主目录,再打开 :
cd ~ # 回到主目录 gedit .bashrc # 再打开文件
四、注意:纯命令行环境无法用 gedit!
如果你的 Linux 是纯命令行界面 (没有图形桌面,比如服务器系统),gedit 无法使用(因为它是图形化工具),这时候才需要用 vi .bashrc
或 vim .bashrc
编辑。但只要你的系统有桌面(比如 Ubuntu 桌面版),用上面的 gedit 方法绝对可行。