소스 정보
- 저장소
- MIUAV/vibe-coding-ros2
- 최근 소스 활동
- 2026년 4월 3일 16:37
- 감지된 SKILL.md 언어
- 중국어
- 스타
- 26
- 포크
- 2
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/MIUAV/vibe-coding-ros2 --skill gazebo-simulation-env명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | gazebo-simulation-env |
| description | Gazebo 仿真环境创建技能 - 世界文件、地形、障碍物、气象条件、多机器人场景配置 |
| argument-hint | Gazebo仿真环境 OR 创建仿真世界 OR 地形建模 OR gazebo环境配置 |
| user-invocable | true |
用于在 Gazebo Harmonic 中创建高质量仿真环境,包括地形、障碍物、多机器人场景和气象条件
当需要以下帮助时使用此技能:
<?xml version="1.0"?>
<sdf version="1.9">
<world name="empty_world">
<!-- 物理插件 -->
<physics name="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>
</physics>
<!-- 场景 -->
<scene>
<ambient>0.5 0.5 0.5 1</ambient>
<shadows>true</shadows>
<grid>false</grid>
</scene>
<!-- 光照 -->
<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.1 0.1 0.1 1</specular>
<attenuation><range>1000</range><constant>0.9</constant><linear>0.01</linear><quadratic>0.001</quadratic></attenuation>
<direction>-0.5 0.1 -0.9</direction>
</light>
<!-- 地面 -->
<平面>
<geometry>
<plane>
<size>100 100</size>
<normal>0 0 1</normal>
</plane>
</geometry>
<material>
<ambient>0.5 0.5 0.5 1</ambient>
<diffuse>0.7 0.7 0.7 1</diffuse>
<specular>0.01 0.01 0.01 1</specular>
</material>
</平面>
<!-- 包含机器人 -->
<include>
<uri>model://my_robot</uri>
<name>robot1</name>
<pose>0 0 0 0 0 0</pose>
</include>
</world>
</sdf>
<!-- 高度图地形 -->
<model name="heightmap_terrain">
<static>true</static>
<link name="terrain_link">
<collision name="collision">
<geometry>
<heightmap>
<use_terrain_paging>false</use_terrain_paging>
<sdf_filename>terrain.dem</sdf_filename>
<texture>
<size>10</size>
<diffuse>file://media/materials/textures/terrain/dirt_diffuse.png</diffuse>
<normal>file://media/materials/textures/terrain/dirt_normal.png</normal>
</texture>
<blur>1.5</blur>
<primitives>3</primitives>
<view_primitives>false</view_primitives>
<>0.5
terrain.dem
file://media/materials/textures/terrain/dirt_diffuse.png
file://media/materials/textures/terrain/dirt_normal.png
import numpy as np
def generate_rough_terrain(size=20, amplitude=0.1):
"""生成粗糙地面高度数据"""
x = np.linspace(-size/2, size/2, 100)
y = np.linspace(-size/2, size/2, 100)
X, Y = np.meshgrid(x, y)
# 基础地形 + 噪声
Z = amplitude * np.sin(X * 0.5) * np.cos(Y * 0.5)
Z += 0.05 * np.random.randn(100, 100)
return Z
<!-- 墙壁 -->
<model name="wall_1">
<static>true</static>
<link name="wall_link">
<pose>5 0 1.25 0 0 0</pose>
<collision name="wall_collision">
<geometry>
<box><size>0.2 5 2.5</size></box>
</geometry>
</collision>
<visual name="wall_visual">
<geometry>
<box><size>0.2 5 2.5</size></box>
</geometry>
<material>
<diffuse>0.6 0.6 0.6 1</diffuse>
</material>
</visual>
</link>
true
3 3 0.5 0 0 0
0.3
1.0
0.3
1.0
0.8 0.2 0.2 1
<!-- 移动的人 -->
<model name="walking_person">
<static>false</static>
<link name="body">
<pose>0 0 0.9 0 0 0</pose>
<collision name="collision">
<geometry>
<cylinder><radius>0.3</radius><length>1.8</length></cylinder>
</geometry>
</collision>
<!-- 使用.actor 实现动画移动 -->
<plugin name="actor_plugin" filename="libActorPlugin.so">
<model>
<walking>
<pose>-5 0 0 0 0 0</pose>
<keyframe>
<time>0</time>
<pose>-5 0 0 0 0 0
2
5 0 0 0 0 0
4
-5 0 0 0 0 0
<plugin name="gazebo::ros::Rayscan" name="gazebo_ros_laser">
<ros>
<namespace>/robot1</namespace>
<remapping>~/out:=scan</remapping>
</ros>
<frame_name>laser_link</frame_name>
<publish_intensities>false</publish_intensities>
<publish_channels>true</publish_channels>
<update_rate>10</update_rate>
<ray>
<scan>
<horizontal>
<samples>720</samples>
<resolution>1</resolution>
<min_angle>-3.14159</min_angle>
<max_angle>3.14159</max_angle>
</horizontal>
</scan>
<>
0.08
30.0
0.01
gaussian
0.0
0.01
<sensor name="depth_camera" type="depth">
<camera name="depth">
<horizontal_fov>1.047</horizontal_fov>
<image>
<width>640</width>
<height>480</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.1</near>
<far>10</far>
</clip>
</camera>
<plugin name="gazebo_ros_camera" filename="libgazebo_ros_camera.so">
<ros>
<namespace>/robot1</namespace>
<remapping>image_raw:=camera/image_raw</remapping>
<remapping>camera_info:=camera/camera_info
depth
camera_link
<!-- 天气效果 -->
<scene>
<fog>
<type>exponential</type>
<color>0.9 0.9 0.9 1</color>
<density>0.01</density>
</fog>
<sky>
<clouds>
<speed>10</speed>
<direction>1 0 -1</direction>
<humidity>30</humidity>
</clouds>
</sky>
</scene>
<!-- 雨效果(通过粒子系统) -->
<model name="rain">
<static>true</static>
<link name="rain_link">
<plugin name="ParticleEffect" name="rain">
<filename>particle/rain.dae</>
0
-1
30
-1
# launch/multi_robot_gazebo.launch.py
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
import math
def generate_robot_pose(i, total):
angle = 2 * math.pi * i / total
r = 2.0
x = r * math.cos(angle)
y = r * math.sin(angle)
return f"{x} {y} 0 0 0 {angle}"
def generate_multi_robot_launch(num_robots=3):
robots = []
for i in range(num_robots):
ns = f"robot{i+1}"
robots.append(
DeclareLaunchArgument(f'{ns}_pose', default_value=generate_robot_pose(i, num_robots)),
Node(
package='gazebo_ros',
executable='spawn_entity.py',
arguments=[
'-entity', f'robot_{i+1}',
'-topic', f'robot_description_{i+1}',
'-namespace', ns,
'-x', str(2 * math.cos(2 * math.pi * i / num_robots)),
'-y', str( * math.sin( * math.pi * i / num_robots)),
],
output=,
),
)
LaunchDescription(robots)
# launch/robot_gazebo.launch.py
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
def generate_launch_description():
pkg_share = get_package_share_directory('my_robot_description')
world_file = os.path.join(pkg_share, 'worlds', 'warehouse.world')
return LaunchDescription([
# Gazebo
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(get_package_share_directory('gazebo_ros'), 'launch', 'gazebo.launch.py')
),
launch_arguments={'world': world_file}.items(),
),
# 机器人描述
Node(
package='robot_state_publisher',
executable='robot_state_publisher',
name='robot_state_publisher',
parameters=[{'robot_description': open(os.path.join(pkg_share, 'urdf', 'robot.urdf')).read()}],
),
])
| 问题 | 原因 | 解决方案 |
|---|---|---|
| Gazebo 启动黑屏 | GPU 驱动问题 | export LIBGL_ALWAYS_SOFTWARE=1 |
| 模型加载失败 | URI 路径错误 | 确认 GAZEBO_MODEL_PATH 包含模型目录 |
| 激光雷达无数据 | 插件未加载 | 检查 gz topic -l 确认插件已启动 |
| 物理不稳定 | dt 太大 | 减小 max_step_size |
| 纹理缺失 | 材质路径错误 | 设置 GAZEBO_RESOURCE_PATH |
# 查看可用话题
gz topic -l
# 查看模型列表
gz model -l
# 移动模型
gz model -m robot1 -x 1 -y 2 -z 0
# 查看传感器数据
gz topic -e /robot1/lidar/scan
# 重置世界
gz world -w empty_world -r
simulator/gazebo-harmonic/robot-modeling — Gazebo 机器人建模simulator/gazebo-harmonic/sensor-integration — Gazebo 传感器集成simulator/gazebo-harmonic/plugin-development — Gazebo 插件开发navigation/nav2-integration — Nav2 导航集成