gazebo-仿真Skill gazebo-simulation

gazebo-simulation技能是专门用于Gazebo仿真环境创建、配置和插件开发的专家级技能。它支持创建SDF世界文件、配置物理引擎参数、实现Gazebo插件、生成传感器模型、设置接触传感器和力-扭矩传感器、配置动态演员和动画模型、实施自定义物理材料和摩擦、创建程序化世界生成以及优化仿真性能等功能。

AI应用 0 次安装 0 次浏览 更新于 2/25/2026

以下是gazebo-simulation技能的中文翻译内容:


name: gazebo-simulation description: 专家级技能,用于Gazebo Classic和Ignition/Gazebo仿真世界创建和插件开发。创建包含地形、照明、物理配置、传感器模型和自定义插件的SDF世界。 allowed-tools: Bash(*) 读写编辑Glob Grep WebFetch metadata: author: babysitter-sdk version: “1.0.0” category: simulation backlog-id: SK-002

gazebo-simulation

你是gazebo-simulation - 一个专为Gazebo仿真环境创建、配置和插件开发提供的专家级技能。

概览

这项技能使得AI驱动的Gazebo仿真成为可能,包括:

  • 创建包含地形、照明和物理的SDF世界文件
  • 配置物理引擎参数(ODE、Bullet、DART)
  • 实现Gazebo插件(模型、世界、传感器、视觉)
  • 生成传感器模型(相机、激光雷达、IMU、GPS、深度)
  • 设置接触传感器和力-扭矩传感器
  • 配置动态演员和动画模型
  • 实施自定义物理材料和摩擦
  • 创建程序化世界生成
  • 优化仿真性能(LOD、碰撞简化)
  • 设置多机器人仿真实例

前提条件

  • Gazebo Sim(Harmonic、Ionic)或Gazebo Classic(11)
  • 带有gazebo_ros_pkgs的ROS2
  • SDF规范知识
  • 自定义插件的C++开发工具

能力

1. 世界文件创建

生成SDF世界文件:

<?xml version="1.0" ?>
<sdf version="1.8">
  <world name="robot_world">
    <!-- 物理配置 -->
    <physics name="default_physics" type="ode">
      <max_step_size>0.001</max_step_size>
      <real_time_factor>1.0</real_time_factor>
      <real_time_update_rate>1000</real_time_update_rate>
      <ode>
        <solver>
          <type>quick</type>
          <iters>50</iters>
          <sor>1.3</sor>
        </solver>
        <constraints>
          <cfm>0.0</cfm>
          <erp>0.2</erp>
          <contact_max_correcting_vel>100.0</contact_max_correcting_vel>
          <contact_surface_layer>0.001</contact_surface_layer>
        </constraints>
      </ode>
    </physics>

    <!-- 照明 -->
    <light type="directional" name="sun">
      <cast_shadows>true</cast_shadows>
      <pose>0 0 10 0 0 0</pose>
      <diffuse>0.8 0.8 0.8 1</diffuse>
      <specular>0.2 0.2 0.2 1</specular>
      <direction>-0.5 0.1 -0.9</direction>
    </light>

    <light type="point" name="point_light">
      <pose>5 5 3 0 0 0</pose>
      <diffuse>0.5 0.5 0.5 1</diffuse>
      <specular>0.1 0.1 0.1 1</specular>
      <attenuation>
        <range>20</range>
        <linear>0.05</linear>
        <quadratic>0.001</quadratic>
      </attenuation>
    </light>

    <!-- 地面平面 -->
    <model name="ground_plane">
      <static>true</static>
      <link name="link">
        <collision name="collision">
          <geometry>
            <plane>
              <normal>0 0 1</normal>
              <size>100 100</size>
            </plane>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>100</mu>
                <mu2>50</mu2>
              </ode>
            </friction>
          </surface>
        </collision>
        <visual name="visual">
          <geometry>
            <plane>
              <normal>0 0 1</normal>
              <size>100 100</size>
            </plane>
          </geometry>
          <material>
            <ambient>0.8 0.8 0.8 1</ambient>
            <diffuse>0.8 0.8 0.8 1</diffuse>
          </material>
        </visual>
      </link>
    </model>

    <!-- 包含模型 -->
    <include>
      <uri>model://my_robot</uri>
      <name>robot1</name>
      <pose>0 0 0.1 0 0 0</pose>
    </include>

    <!-- 插件 -->
    <plugin filename="gz-sim-physics-system" name="gz::sim::systems::Physics"/>
    <plugin filename="gz-sim-user-commands-system" name="gz::sim::systems::UserCommands"/>
    <plugin filename="gz-sim-scene-broadcaster-system" name="gz::sim::systems::SceneBroadcaster"/>
    <plugin filename="gz-sim-sensors-system" name="gz::sim::systems::Sensors">
      <render_engine>ogre2</render_engine>
    </plugin>

  </world>
</sdf>

2. 物理引擎配置

配置不同的物理引擎:

<!-- ODE(默认,快速) -->
<physics name="ode_physics" type="ode">
  <max_step_size>0.001</max_step_size>
  <real_time_factor>1.0</real_time_factor>
  <ode>
    <solver>
      <type>quick</type>
      <iters>50</iters>
    </solver>
  </ode>
</physics>

<!-- Bullet(更适合复杂碰撞) -->
<physics name="bullet_physics" type="bullet">
  <max_step_size>0.001</max_step_size>
  <real_time_factor>1.0</real_time_factor>
  <bullet>
    <solver>
      <type>sequential_impulse</type>
      <iters>50</iters>
      <sor>1.3</sor>
    </solver>
  </bullet>
</physics>

<!-- DART(最适合机器人学,铰接体) -->
<physics name="dart_physics" type="dart">
  <max_step_size>0.001</max_step_size>
  <real_time_factor>1.0</real_time_factor>
  <dart>
    <collision_detector>fcl</collision_detector>
    <solver>
      <solver_type>pgs</solver_type>
    </solver>
  </dart>
</physics>

3. 传感器配置

向机器人添加各种传感器:

<!-- 相机传感器 -->
<sensor name="camera" type="camera">
  <always_on>true</always_on>
  <update_rate>30</update_rate>
  <camera>
    <horizontal_fov>1.3962634</horizontal_fov>
    <image>
      <width>640</width>
      <height>480</height>
      <format>R8G8B8</format>
    </image>
    <clip>
      <near>0.1</near>
      <far>100</far>
    </clip>
    <noise>
      <type>gaussian</type>
      <mean>0</mean>
      <stddev>0.007</stddev>
    </noise>
  </camera>
  <plugin filename="gz-sim-camera-system" name="gz::sim::systems::Camera"/>
</sensor>

<!-- 深度相机 -->
<sensor name="depth_camera" type="depth_camera">
  <always_on>true</always_on>
  <update_rate>15</update_rate>
  <camera>
    <horizontal_fov>1.047</horizontal_fov>
    <image>
      <width>640</width>
      <height>480</height>
      <format>R_FLOAT32</format>
    </image>
    <clip>
      <near>0.1</near>
      <far>10</far>
    </clip>
  </camera>
  <plugin filename="gz-sim-depth-camera-system" name="gz::sim::systems::DepthCamera"/>
</sensor>

<!-- 激光雷达传感器 -->
<sensor name="lidar" type="gpu_lidar">
  <always_on>true</always_on>
  <update_rate>10</update_rate>
  <lidar>
    <scan>
      <horizontal>
        <samples>640</samples>
        <resolution>1</resolution>
        <min_angle>-3.14159</min_angle>
        <max_angle>3.14159</max_angle>
      </horizontal>
      <vertical>
        <samples>16</samples>
        <resolution>1</resolution>
        <min_angle>-0.26</min_angle>
        <max_angle>0.26</max_angle>
      </vertical>
    </scan>
    <range>
      <min>0.3</min>
      <max>100</max>
      <resolution>0.01</resolution>
    </range>
    <noise>
      <type>gaussian</type>
      <mean>0</mean>
      <stddev>0.01</stddev>
    </noise>
  </lidar>
  <plugin filename="gz-sim-gpu-lidar-system" name="gz::sim::systems::GpuLidar"/>
</sensor>

<!-- IMU传感器 -->
<sensor name="imu" type="imu">
  <always_on>true</always_on>
  <update_rate>200</update_rate>
  <imu>
    <angular_velocity>
      <x>
        <noise type="gaussian">
          <mean>0.0</mean>
          <stddev>0.0002</stddev>
        </noise>
      </x>
      <y>
        <noise type="gaussian">
          <mean>0.0</mean>
          <stddev>0.0002</stddev>
        </noise>
      </y>
      <z>
        <noise type="gaussian">
          <mean>0.0</mean>
          <stddev>0.0002</stddev>
        </noise>
      </z>
    </angular_velocity>
    <linear_acceleration>
      <x>
        <noise type="gaussian">
          <mean>0.0</mean>
          <stddev>0.017</stddev>
        </noise>
      </x>
    </linear_acceleration>
  </imu>
  <plugin filename="gz-sim-imu-system" name="gz::sim::systems::Imu"/>
</sensor>

<!-- GPS传感器 -->
<sensor name="gps" type="navsat">
  <always_on>true</always_on>
  <update_rate>5</update_rate>
  <navsat>
    <position_sensing>
      <horizontal>
        <noise type="gaussian">
          <mean>0</mean>
          <stddev>0.5</stddev>
        </noise>
      </horizontal>
      <vertical>
        <noise type="gaussian">
          <mean>0</mean>
          <stddev>1.0</stddev>
        </noise>
      </vertical>
    </position_sensing>
  </navsat>
  <plugin filename="gz-sim-navsat-system" name="gz::sim::systems::NavSat"/>
</sensor>

4. ROS2-Gazebo桥接

配置ROS2桥接以发布话题:

<!-- 在世界文件中 -->
<plugin filename="gz-sim-ros-gz-bridge" name="ros_gz_bridge::RosGzBridge">
  <ros>
    <namespace>/robot</namespace>
  </ros>

  <!-- 相机 -->
  <bridge topic="/camera/image_raw" ros_topic="/robot/camera/image_raw" type="sensor_msgs/msg/Image" direction="GZ_TO_ROS"/>
  <bridge topic="/camera/camera_info" ros_topic="/robot/camera/camera_info" type="sensor_msgs/msg/CameraInfo" direction="GZ_TO_ROS"/>

  <!-- 激光雷达 -->
  <bridge topic="/lidar/points" ros_topic="/robot/scan" type="sensor_msgs/msg/PointCloud2" direction="GZ_TO_ROS"/>

  <!-- IMU -->
  <bridge topic="/imu" ros_topic="/robot/imu" type="sensor_msgs/msg/Imu" direction="GZ_TO_ROS"/>

  <!-- 速度命令 -->
  <bridge topic="/cmd_vel" ros_topic="/robot/cmd_vel" type="geometry_msgs/msg/Twist" direction="ROS_TO_GZ"/>

  <!-- 里程计 -->
  <bridge topic="/odom" ros_topic="/robot/odom" type="nav_msgs/msg/Odometry" direction="GZ_TO_ROS"/>

  <!-- 关节状态 -->
  <bridge topic="/joint_states" ros_topic="/robot/joint_states" type="sensor_msgs/msg/JointState" direction="GZ_TO_ROS"/>

  <!-- TF -->
  <bridge topic="/tf" ros_topic="/tf" type="tf2_msgs/msg/TFMessage" direction="GZ_TO_ROS"/>
</plugin>

5. 地形和环境

创建地形和环境模型:

<!-- 高度图地形 -->
<model name="terrain">
  <static>true</static>
  <link name="link">
    <collision name="collision">
      <geometry>
        <heightmap>
          <uri>file://terrain/heightmap.png</uri>
          <size>100 100 10</size>
          <pos>0 0 0</pos>
        </heightmap>
      </geometry>
    </collision>
    <visual name="visual">
      <geometry>
        <heightmap>
          <uri>file://terrain/heightmap.png</uri>
          <size>100 100 10</size>
          <pos>0 0 0</pos>
          <texture>
            <diffuse>file://terrain/grass.png</diffuse>
            <normal>file://terrain/grass_normal.png</normal>
            <size>10</size>
          </texture>
        </heightmap>
      </geometry>
    </visual>
  </link>
</model>

<!-- 障碍物 -->
<model name="obstacle_box">
  <static>true</static>
  <pose>5 3 0.5 0 0 0</pose>
  <link name="link">
    <collision name="collision">
      <geometry>
        <box>
          <size>1 1 1</size>
        </box>
      </geometry>
    </collision>
    <visual name="visual">
      <geometry>
        <box>
          <size>1 1 1</size>
        </box>
      </geometry>
      <material>
        <ambient>0.5 0.5 0.5 1</ambient>
      </material>
    </visual>
  </link>
</model>

6. 自定义插件开发

创建自定义Gazebo插件:

// WorldPlugin示例
#include <gz/sim/System.hh>
#include <gz/plugin/Register.hh>

namespace my_plugins {

class MyWorldPlugin : public gz::sim::System,
                      public gz::sim::ISystemConfigure,
                      public gz::sim::ISystemPreUpdate
{
public:
  void Configure(const gz::sim::Entity &_entity,
                 const std::shared_ptr<const sdf::Element> &_sdf,
                 gz::sim::EntityComponentManager &_ecm,
                 gz::sim::EventManager &_eventMgr) override
  {
    // 加载时配置
    gzmsg << "MyWorldPlugin configured" << std::endl;
  }

  void PreUpdate(const gz::sim::UpdateInfo &_info,
                 gz::sim::EntityComponentManager &_ecm) override
  {
    // 每次仿真步骤前调用
    if (_info.paused)
      return;

    // 自定义逻辑
  }
};

}

GZ_ADD_PLUGIN(my_plugins::MyWorldPlugin,
              gz::sim::System,
              my_plugins::MyWorldPlugin::ISystemConfigure,
              my_plugins::MyWorldPlugin::ISystemPreUpdate)

7. 启动文件集成

启动Gazebo与ROS2:

from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription, DeclareLaunchArgument
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare

def generate_launch_description():
    pkg_share = FindPackageShare('my_robot_gazebo')

    # 世界文件
    world_file = PathJoinSubstitution([pkg_share, 'worlds', 'robot_world.sdf'])

    # Gazebo启动
    gazebo = IncludeLaunchDescription(
        PythonLaunchDescriptionSource([
            FindPackageShare('ros_gz_sim'), '/launch/gz_sim.launch.py'
        ]),
        launch_arguments={
            'gz_args': ['-r ', world_file],
            'on_exit_shutdown': 'true'
        }.items()
    )

    # 机器人生成
    spawn_robot = Node(
        package='ros_gz_sim',
        executable='create',
        arguments=[
            '-name', 'my_robot',
            '-topic', '/robot_description',
            '-x', '0', '-y', '0', '-z', '0.1'
        ],
        output='screen'
    )

    # ROS-GZ桥接
    bridge = Node(
        package='ros_gz_bridge',
        executable='parameter_bridge',
        arguments=[
            '/cmd_vel@geometry_msgs/msg/Twist@gz.msgs.Twist',
            '/odom@nav_msgs/msg/Odometry@gz.msgs.Odometry',
            '/scan@sensor_msgs/msg/LaserScan@gz.msgs.LaserScan'
        ],
        output='screen'
    )

    return LaunchDescription([
        gazebo,
        spawn_robot,
        bridge
    ])

MCP服务器集成

这项技能可以利用以下MCP服务器增强功能:

服务器 描述 安装
Gazebo MCP服务器 ROS2 MCP for Gazebo lobehub.com
ros-mcp-server ROS/ROS2桥接 GitHub

最佳实践

  1. 使用适当的物理引擎 - 根据需求选择物理引擎
  2. 传感器噪声 - 为传感器添加现实噪声模型
  3. 碰撞简化 - 使用简化的碰撞几何体
  4. 实时因子 - 根据仿真与实时需求进行调整
  5. 资源管理 - 禁用未使用的传感器以提高性能
  6. 模块化世界 - 使用包含可重用的世界组件

流程集成

这项技能与以下流程集成:

  • gazebo-simulation-setup.js - 主要仿真设置
  • digital-twin-development.js - 数字孪生创建
  • synthetic-data-pipeline.js - 训练数据生成
  • simulation-performance-optimization.js - 性能调整
  • hil-testing.js - 硬件在环测试

输出格式

执行操作时,提供结构化输出:

{
  "operation": "create-world",
  "worldName": "robot_world",
  "status": "success",
  "configuration": {
    "physicsEngine": "ode",
    "realTimeFactor": 1.0,
    "sensors": ["camera", "lidar", "imu"]
  },
  "artifacts": [
    "worlds/robot_world.sdf",
    "launch/simulation.launch.py"
  ],
  "launchCommand": "ros2 launch my_robot_gazebo simulation.launch.py"
}

约束

  • 验证Gazebo版本兼容性(经典版与Sim)
  • 检查SDF版本以获取功能可用性
  • 测试传感器更新率对性能的影响
  • 验证物理参数以确保稳定性
  • 确保ROS-GZ桥接话题兼容性