mcpField
R
ros2-robotics

ros2-robotics

github.com/mindrally开发30185 次安装4 周前更新
代码仓库

关于 ros2-robotics

面向机器人软件开发者的 ROS 2 开发技能,覆盖软件包、节点、通信接口、时序与坐标系,以及构建和测试流程。内容也涉及 QoS 配置和常见运行问题。

主要功能

  1. 01组织 ROS 2 软件包与节点
  2. 02选择话题、服务和动作接口
  3. 03配置 QoS、时序与坐标变换
  4. 04使用 colcon 构建与测试
  5. 05检查运行状态并排查故障

适用场景

  1. 01搭建可组合的机器人功能节点
  2. 02设计传感器与控制通信接口
  3. 03测试多节点行为和传感器场景

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mindrally/skills --skill ros2-robotics

安装后在 Claude Code 中输入/ros2-robotics确认已加载。

详细介绍

ROS 2 机器人开发

本技能涵盖 ROS 2 包和节点的构建,包括包结构、通信模式(主题、服务、动作)、时序与坐标系、使用 colcon 的构建/测试工作流,以及机器人软件中的常见问题。

构建 ROS 2 包的工作流

  1. 创建包骨架 — 在 colcon 工作区的 src/ 目录中运行 ros2 pkg create --build-type ament_python <name>(Python),或运行 --build-type ament_cmake <name>(C++)。
  2. 定义接口 — 仅当标准接口(std_msgs、geometry_msgs、sensor_msgs、nav_msgs)无法满足需求时,才在 msg/、srv/、action/ 目录下添加自定义 .msg、.srv 或 .action 文件。
  3. 实现节点 — 编写职责明确、可组合的节点;显式声明参数;数据流使用主题,快速请求/响应使用服务,带有反馈和取消功能的长时间运行目标使用动作。
  4. 编写启动文件 — 使用 launch_ros.actions.Node 在 launch/*.launch.py 文件中组合节点、参数和重映射。
  5. 有目的地设置 QoS 配置 — 针对传感器数据与命令/控制路径,匹配发布者/订阅者的 QoS(可靠性、持久性、历史记录深度)。
  6. 构建工作区 — 在工作区根目录运行 colcon build --symlink-install,然后运行 source install/setup.bash。
  7. 测试 — 添加单元测试(Python 使用 pytest,C++/集成测试使用 gtest/launch_testing),并运行 colcon test。
  8. 运行并检查 — 使用 ros2 run、ros2 launch、ros2 topic echo、ros2 node info 和 ros2 doctor 验证运行时行为。

包结构

  • 让每个包专注于一种机器人能力或集成边界(例如 lidar_driver、path_planner、arm_controller),而不是创建一个庞大的单体包。
  • 确保 package.xml 与其中声明的构建类型保持一致,并使用 CMakeLists.txt(ament_cmake,C++)或 setup.py/setup.cfg(ament_python)。
  • 使用 launch/ 存放启动脚本,config/ 存放 YAML 参数文件,msg/ 存放消息定义,srv/ 存放服务,action/ 存放动作,urdf//xacro/ 存放机器人描述文件。
  • 如果某个节点可能多次运行(例如多机器人设置)或会在多个项目中复用,请使用命名空间和主题重映射,而不是硬编码主题名称。
  • 在 package.xml 中显式声明所有依赖(<depend>、<exec_depend>、<build_depend>),以确保工作区能够可复现地构建。

节点与接口

  • 保持节点小巧且可组合——每个逻辑职责对应一个节点,通过主题/服务/动作连接,而不是让一个庞大的节点包办所有工作。
  • 使用 self.declare_parameter('rate_hz', 10.0) 显式声明 ROS 2 参数,并通过 self.get_parameter('rate_hz').value 读取;切勿依赖未声明的参数。
  • 连续状态数据流优先使用消息(主题),快速的阻塞式请求/响应操作使用服务,长时间运行且需要报告反馈并支持取消/抢占的目标使用动作。
  • 在创建自定义接口之前,优先使用标准消息类型(geometry_msgs/Twist、sensor_msgs/LaserScan、nav_msgs/Odometry)——自定义类型会导致生态碎片化,并失去与现有工具的兼容性。
  • 在包 README 或节点文档字符串中,记录主题、服务、动作、坐标系和参数的约定(名称、类型、单位、frame_id、更新频率)。
示例:最小化的 rclpy 发布者节点
import rclpy
from rclpy.node import Node
from rclpy.qos import QoSProfile, ReliabilityPolicy, HistoryPolicy
from geometry_msgs.msg import Twist


class SafeVelocityPublisher(Node):
    """Publishes bounded velocity commands at a fixed rate."""

    def __init__(self) -> None:
        super().__init__("safe_velocity_publisher")

        self.declare_parameter("rate_hz", 10.0)
        self.declare_parameter("max_linear_speed", 0.5)
        rate_hz = self.get_parameter("rate_hz").value
        self._max_linear = self.get_parameter("max_linear_speed").value

        # Reliable QoS for a low-rate command topic; sensor streams would
        # typically use BEST_EFFORT with a shallow history instead.
        qos = QoSProfile(
            reliability=ReliabilityPolicy.RELIABLE,
            history=HistoryPolicy.KEEP_LAST,
            depth=10,
        )
        self._publisher = self.create_publisher(Twist, "cmd_vel", qos)
        self._timer = self.create_timer(1.0 / rate_hz, self._on_timer)
        self._target_linear = 0.0

    def _on_timer(self) -> None:
        msg = Twist()
        msg.linear.x = max(-self._max_linear, min(self._max_linear, self._target_linear))
        self._publisher.publish(msg)


def main(args: list | None = None) -> None:
    rclpy.init(args=args)
    node = SafeVelocityPublisher()
    try:
        rclpy.spin(node)
    except KeyboardInterrupt:
        pass
    finally:
        node.destroy_node()
        rclpy.shutdown()


if __name__ == "__main__":
    main()

时间与坐标系

  • 只要涉及仿真或 rosbag 回放,就使用 ROS 时间(self.get_clock().now();使用仿真时钟时设置 use_sim_time),而非墙上时钟。
  • 所有坐标系变换都使用 tf2(tf2_ros.Buffer + TransformListener);切勿手动编写命名坐标系之间的坐标变换。
  • 记录坐标系名称(base_link、odom、map、传感器坐标系)及其约定(轴方向遵循 REP-103,map→odom→base_link 树遵循 REP-105)。
  • 避免在节点的执行器线程中运行阻塞回调;将耗时工作移至定时器、MultiThreadedExecutor、工作线程或动作中,以便节点继续处理其他回调。
  • 有意设置 QoS 配置:对于允许丢弃采样的高速传感器数据,使用 BEST_EFFORT/volatile;对于类似锁存的配置主题,使用 RELIABLE/TRANSIENT_LOCAL;对于命令链路,使用 RELIABLE/volatile。

构建与测试

  • 使用 colcon build(开发期间通常加上 --symlink-install),并在 package.xml 中明确包间依赖。
  • 通过 colcon test 运行工作区已有的代码检查工具和格式化工具——Python 使用 ament_flake8、ament_pep257;C++ 使用 ament_cpplint、ament_uncrustify。
  • 为多节点行为添加基于 launch_testing 的集成测试(例如,“节点 A 是否会在 N 秒内收到节点 B 发布的内容”)。
  • 使用仿真(Gazebo/Ignition)、录制的 rosbags 或固定测试数据来构建可重复的传感器场景,而不要每次测试都依赖实时硬件。
  • 明确测试故障情况:变换缺失或延迟(tf2.LookupException)、传感器数据过期,以及调用时不可用的服务或动作。

常见错误

  • 将绝对文件系统路径硬编码,而不是通过 ament_index_python.packages.get_package_share_directory 解析路径。
  • 发布速度或执行器命令时未验证 frame_id、单位和时间戳时效性——过期或坐标系错误的命令可能导致机器人危险移动。
  • 在已有标准接口能够表示数据时,仍创建自定义消息/服务/动作类型。
  • 忽略发布者与订阅者之间的 QoS 不兼容警告(例如,BEST_EFFORT 发布者搭配 RELIABLE 订阅者)——连接不会传递数据,而且不会明确报错。
  • 在订阅回调中执行大量工作,却不将其移出回调,导致执行器资源耗尽、其他回调延迟(包括安全关键回调)。
  • 面向模拟器运行时忘记设置 use_sim_time:=true,导致时间戳和 tf2 查询使用的时间与仿真时钟不一致。

评论

支持 Markdown