用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/MIUAV/vibe-coding-ros2 --skill ros2-integration命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | ros2-integration |
| description | Gazebo ROS2 集成技能 - ros_gz 桥接、控制器启动、launch 文件配置 |
| argument-hint | gazebo ros2集成 OR ros_gz桥接 OR 控制器配置 |
| user-invocable | true |
用于 Gazebo Harmonic 与 ROS2 的集成
当需要以下帮助时使用此技能:
# For ROS2 Humble
sudo apt install ros-humble-ros-gz-bridge ros-humble-ros-gz-sim ros-humble-ros-gz-image
# For ROS2 Iron
sudo apt install ros-iron-ros-gz-bridge ros-iron-ros-gz-sim ros-iron-ros-gz-image
# launch/bridge.launch.py
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
# cmd_vel 桥接
Node(
package='ros_gz_bridge',
executable='parameter_bridge',
arguments=[
'/cmd_vel@geometry_msgs/msg/Twist@gz.msgs.Twist'
],
output='screen'
),
# 激光扫描桥接
Node(
package='ros_gz_bridge',
executable='parameter_bridge',
arguments=[
'/scan@sensor_msgs/msg/LaserScan@gz.msgs.LaserScan'
],
output='screen'
),
# 图像桥接
Node(
package='ros_gz_image',
executable='image_bridge',
arguments=['/camera/image_raw@sensor_msgs/msg/Image@gz.msgs.Image'],
output='screen'
),
])
from launch import LaunchDescription
from launch_ros.actions import Node
import os
from ament_index_python.packages import get_package_share_directory
def generate_launch_description():
pkg_name = 'robot_bringup'
pkg_dir = get_package_share_directory(pkg_name)
# 获取 robot_description
robot_desc_path = os.path.join(pkg_dir, 'urdf', 'robot.urdf')
with open(robot_desc_path, 'r') as f:
robot_description = f.read()
return LaunchDescription([
# 里程计桥接
Node(
package='ros_gz_bridge',
executable='parameter_bridge',
arguments=[
'/odom@nav_msgs/msg/Odometry@gz.msgs.Odometry'
],
output='screen'
),
# IMU 桥接
Node(
package='ros_gz_bridge',
executable='parameter_bridge',
arguments=[
'/imu@sensor_msgs/msg/Imu@gz.msgs.IMU'
],
output='screen'
),
# .pointcloud2 桥接
Node(
package='ros_gz_bridge',
executable='parameter_bridge',
arguments=[
'/points@sensor_msgs/msg/PointCloud2@gz.msgs.PointCloudPacked'
],
output='screen'
),
# TF 静态变换
Node(
package='robot_state_publisher',
executable='robot_state_publisher',
parameters=[{: robot_description}],
output=
),
])
# launch/robot.launch.py
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, ExecuteProcess
from launch_ros.actions import Node
from launch.substitutions import LaunchConfiguration
import os
from ament_index_python.packages import get_package_share_directory
def generate_launch_description():
pkg_name = 'robot_bringup'
pkg_dir = get_package_share_directory(pkg_name)
# 参数
use_sim_time = LaunchConfiguration('use_sim_time', default='true')
# 路径
world_path = os.path.join(pkg_dir, 'worlds', 'robot.world')
robot_desc_path = os.path.join(pkg_dir, 'urdf', 'robot.urdf')
return LaunchDescription([
DeclareLaunchArgument(
'use_sim_time',
default_value='true',
description='Use sim time'
),
# Gazebo 进程
ExecuteProcess(
cmd=['gz', 'sim', '-v4', world_path],
output='screen'
),
# 加载机器人到 Gazebo
Node(
package='ros_gz_sim',
executable='create',
arguments=[
'-name', 'robot',
'-file', robot_desc_path,
'-x', '0',
'-y', ,
,
],
output=
),
Node(
package=,
executable=,
name=,
parameters=[{
: (robot_desc_path).read(),
: use_sim_time
}],
output=
),
Node(
package=,
executable=,
arguments=[],
output=
),
Node(
package=,
executable=,
arguments=[],
output=
),
Node(
package=,
executable=,
arguments=[
,
,
,
],
output=
),
Node(
package=,
executable=,
arguments=[],
output=
),
])
# config/diff_drive_controller.yaml
controller_manager:
ros__parameters:
update_rate: 50
diff_drive_controller:
type: diff_drive_controller/DiffDriveController
diff_drive_controller:
ros__parameters:
left_wheel_names: ['left_wheel_joint']
right_wheel_names: ['right_wheel_joint']
wheel_separation: 0.4
wheel_radius: 0.1
max_wheel_odom_velocity: 10.0
max_wheel_acceleration: 10.0
publish_rate: 50.0
command_timeout: 0.1
base_frame_id: base_link
odom_frame_id: odom
enable_odom_tf: true
enable_odom_computation: true
velocity_aggregation: "mean"
# PID 控制器参数
vel_timeout: 0.5
# 发布话题
publish_cmd: true
publish_odom: true
publish_wheel_states: true
# config/joint_trajectory_controller.yaml
controller_manager:
ros__parameters:
update_rate: 100
joint_trajectory_controller:
type: joint_trajectory_controller/JointTrajectoryController
joint_trajectory_controller:
ros__parameters:
joints:
- arm_joint_1
- arm_joint_2
- arm_joint_3
- arm_joint_4
- arm_joint_5
- arm_joint_6
command_interfaces:
- position
state_interfaces:
- position
- velocity
gains:
arm_joint_1: {p: 100.0, d: 10.0, i: 0.0, i_clamp: 1.0}
arm_joint_2: {p: 100.0, d: 10.0, i: 0.0, i_clamp: 1.0}
arm_joint_3: {p: 100.0, d: , , }
{ , , , }
{ , , , }
{ , , , }
<!-- urdf/robot.urdf.xacro -->
<?xml version="1.0" ?>
<robot name="robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- 参数 -->
<xacro:property name="robot_name" value="my_robot" />
<xacro:property name="mesh_dir" value="package://robot_description/meshes" />
<!-- 包含其他文件 -->
<xacro:include filename="$(find robot_description)/urdf/robot.gazebo" />
<!-- 链接 -->
<link name="base_link">
...
</link>
<!-- 关节 -->
<joint name="wheel_joint" type="revolute">
...
</joint>
</robot>
# 生成 URDF
xacro robot.urdf.xacro > robot.urdf
# 空世界
gz sim -v4
# 指定世界文件
gz sim -v4 /path/to/world.sdf
# GUI 模式
gz sim -g
# 服务器模式 (无 GUI)
gz sim -s
# 查看话题列表
ros2 topic list
# 查看话题数据
ros2 topic echo /scan
# 手动加载模型
ros2 run ros_gz_sim create -name my_robot -file /path/to/robot.sdf
解决方案:确认 ROS2 和 Gazebo 的话题名称匹配,检查日志输出
解决方案:确认 joint 名称与 URDF 中一致,检查 controller_manager 配置
解决方案:检查模型路径是否正确,确认 SDF/URDF 语法正确