关于 ros2-robotics
面向机器人软件开发者的 ROS 2 开发技能,覆盖软件包、节点、通信接口、时序与坐标系,以及构建和测试流程。内容也涉及 QoS 配置和常见运行问题。
主要功能
- 01组织 ROS 2 软件包与节点
- 02选择话题、服务和动作接口
- 03配置 QoS、时序与坐标变换
- 04使用 colcon 构建与测试
- 05检查运行状态并排查故障
适用场景
- 01搭建可组合的机器人功能节点
- 02设计传感器与控制通信接口
- 03测试多节点行为和传感器场景
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mindrally/ skills --skill ros2-robotics安装后在 Claude Code 中输入/ros2-robotics确认已加载。
详细介绍
ROS 2 机器人开发
本技能涵盖 ROS 2 包和节点的构建,包括包结构、通信模式(主题、服务、动作)、时序与坐标系、使用 colcon 的构建/测试工作流,以及机器人软件中的常见问题。
构建 ROS 2 包的工作流
- 创建包骨架 — 在 colcon 工作区的
src/目录中运行ros2 pkg create --build-type ament_python <name>(Python),或运行--build-type ament_cmake <name>(C++)。 - 定义接口 — 仅当标准接口(
std_msgs、geometry_msgs、sensor_msgs、nav_msgs)无法满足需求时,才在msg/、srv/、action/目录下添加自定义.msg、.srv或.action文件。 - 实现节点 — 编写职责明确、可组合的节点;显式声明参数;数据流使用主题,快速请求/响应使用服务,带有反馈和取消功能的长时间运行目标使用动作。
- 编写启动文件 — 使用
launch_ros.actions.Node在launch/*.launch.py文件中组合节点、参数和重映射。 - 有目的地设置 QoS 配置 — 针对传感器数据与命令/控制路径,匹配发布者/订阅者的 QoS(可靠性、持久性、历史记录深度)。
- 构建工作区 — 在工作区根目录运行
colcon build --symlink-install,然后运行source install/setup.bash。 - 测试 — 添加单元测试(Python 使用
pytest,C++/集成测试使用gtest/launch_testing),并运行colcon test。 - 运行并检查 — 使用
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