3. 实时操作系统与中间件选型

手术机器人软件栈的实时性需求并不是一条统一的水平线,而是按控制层级分层的。主手力反馈闭环、从手关节伺服、安全监控通常要求微秒到毫秒级确定性;而影像导航、路径规划、状态显示可以容忍几十毫秒甚至更长的抖动。选型的第一步不是比较“谁更快”,而是先把系统拆成若干实时域,再为每个域匹配操作系统与中间件组合。

四类候选技术的定位差异

RTOS(如 VxWorks、FreeRTOS、Zephyr、QNX)的核心价值是确定性调度与可证明的最坏执行时间(WCET)。其调度器通常支持固定优先级抢占,中断延迟可稳定在微秒量级,适合直接驱动电机、编码器、力传感器等硬实时任务。代价是生态相对封闭,网络协议栈、图形界面、AI 推理等非实时功能支持较弱,开发与调试工具链成本高。

Linux PREEMPT_RT 通过将大部分自旋锁替换为可睡眠的互斥锁、把中断处理线程化、引入高精度定时器,把标准 Linux 的内核抢占延迟从毫秒级压缩到几十微秒量级。它保留了 Linux 的完整生态:ROS 2、OpenCV、PyTorch、EtherCAT 主站都能运行。适合作为“软实时 + 富功能”的主控平台,但最坏延迟仍受内存管理、驱动质量、CPU 隔离策略影响,不能替代硬实时 MCU。

ROS 2 本身不是实时操作系统,而是构建在 DDS 之上的机器人软件框架。它提供节点、话题、服务、动作、参数、生命周期管理等抽象,并支持实时执行器(rclcpp Real-Time Executor)与零拷贝传输。ROS 2 的实时性上限由底层 DDS 实现和操作系统共同决定。

DDS 是发布/订阅数据总线标准,提供 QoS 策略(可靠性、持久性、截止时间、延迟预算、所有权、分区)。DDS 的实时能力取决于具体实现:RTI Connext DDS、Fast DDS、Cyclone DDS 在延迟与确定性上差异明显。DDS 的 QoS 是手术机器人中实现“关键数据优先、非关键数据可丢”的核心手段。

手术机器人实时域分层与 OS/中间件映射 实时域(按周期) 硬实时域 关节伺服 / 力反馈 周期 0.25–1 ms,抖动 < 10 µs 安全监控域 看门狗 / 限位 / 急停 周期 1–5 ms,需可证明 WCET 软实时域 运动学 / 轨迹插补 周期 2–10 ms,抖动 < 1 ms 非实时域 影像导航 / 规划 / UI 周期 20–100 ms,可容忍抖动 数据记录 / 日志 异步,不参与控制闭环 OS / 中间件组合 RTOS(QNX / VxWorks / Zephyr) 直接驱动伺服,无 DDS 或轻量 DDS 确定性最强,生态最弱 Linux PREEMPT_RT + EtherCAT CPU 隔离 + 线程优先级 + 高精度定时器 抖动可达 20–50 µs(示例目标) ROS 2 + DDS(Fast DDS / Cyclone DDS) 实时执行器 + QoS 截止时间/延迟预算 适合软实时与模块解耦 标准 Linux + ROS 2 影像、规划、UI、AI 推理 吞吐优先,不承诺硬实时 共享内存 / 零拷贝 / 时间同步 跨域数据交换与 PTP 时钟对齐 部署要点 CPU 隔离与绑核 isolcpus / cgroups / taskset 实时线程独占核心,禁用超线程 DDS QoS 配置 RELIABLE + DEADLINE + LIVELINESS 控制话题用 KEEP_LAST(1) 内存与锁策略 预分配、mlockall、无动态分配 避免优先级反转(PI mutex) 时间同步 PTP(IEEE 1588)对齐多节点 时间戳统一到同一时钟域 验证与观测 cyclictest / ros2 topic delay / 抖动直方图

选型判断:先看周期与抖动预算,再看生态

一个实用的判断顺序是:先确定每个控制回路的周期与允许抖动,再决定该回路是否必须放在硬实时域。例如,从手关节电流环通常运行在 10–20 kHz,必须由伺服驱动器内部的 DSP/MCU 完成,主控只需以 1 kHz 下发位置或力矩指令;主手力反馈闭环若要求 1 kHz 且抖动小于 50 µs,则适合用 PREEMPT_RT 加隔离核,或直接用 RTOS。影像导航与路径规划运行在 10–50 Hz,标准 Linux 加 ROS 2 即可。

ROS 2 与 DDS 的引入会带来额外延迟。以 Fast DDS 默认配置为例,同一主机内两个节点通过 UDP 回环通信,端到端延迟通常在 100–300 µs;若启用共享内存传输并关闭不必要的序列化,可降到几十微秒。对于 1 kHz 控制回路,这个开销可以接受;对于 10 kHz 电流环,则不应经过 DDS,而应使用 EtherCAT 或共享内存直接传递。

部署要点:从内核参数到 QoS 策略

CPU 隔离与绑核。在 PREEMPT_RT 上,建议把控制线程绑定到隔离核,并关闭该核上的调度器负载均衡。示例配置:

# 内核启动参数:隔离 CPU 2-3,保留 CPU 0-1 给系统与非实时任务
isolcpus=2,3 nohz_full=2,3 rcu_nocbs=2,3

# 将控制线程绑定到 CPU 2,并设置实时优先级
taskset -c 2 chrt -f 80 ./joint_controller

# 锁定内存,避免缺页导致抖动
mlockall(MCL_CURRENT | MCL_FUTURE);

DDS QoS 配置。控制话题应使用 RELIABLE 保证不丢包,同时设置 DEADLINE 为周期的一半作为超时告警,LIVELINESS 用于检测节点失效。历史深度用 KEEP_LAST(1),避免旧数据堆积。影像话题可用 BEST_EFFORT 降低开销。示例 QoS 片段:

ReliabilityQosPolicy: RELIABLE
DeadlineQosPolicy: 1 ms
LivelinessQosPolicy: AUTOMATIC, lease_duration 200 ms
HistoryQosPolicy: KEEP_LAST, depth 1
ResourceLimitsQosPolicy: max_samples 4

ROS 2 实时执行器。rclcpp 提供 StaticSingleThreadedExecutor 与实时执行器,可避免运行时动态分配。控制节点应在初始化阶段完成所有内存分配,回调中不调用 new、malloc 或可能阻塞的日志接口。日志改用预分配缓冲或实时安全的日志后端。

验证方法:用数据判断是否达标

部署完成后,必须用可观测指标验证。常用手段包括:

  • cyclictest -p 80 -t 1 -n -i 1000 -l 100000:测量 PREEMPT_RT 下线程唤醒延迟,关注最大值而非平均值。示例目标:最大延迟小于 50 µs。
  • ros2 topic delay /joint_command:观察 ROS 2 话题端到端延迟,判断 DDS 配置是否满足截止时间。
  • EtherCAT 主站分布式时钟偏差:用 ethercat master 查看从站同步误差,目标小于 1 µs。
  • 抖动直方图:把每次控制周期的实际执行时间减去期望周期,统计 P99 与最大值。若 P99 超过周期 20%,说明该回路不适合当前平台。
选型不是“选一个最强的”,而是“为每个实时域选最合适的”。常见组合是:伺服驱动器内跑 RTOS 或专用 DSP,主控跑 PREEMPT_RT + ROS 2 + DDS,影像与规划跑标准 Linux。跨域之间用 EtherCAT、共享内存或 PTP 同步,而不是让所有数据都穿过 DDS。
不要把 ROS 2 默认执行器直接用于硬实时回路。默认执行器使用动态内存与互斥锁,可能引入毫秒级抖动。若必须用 ROS 2 承载控制话题,应启用实时执行器、预分配内存、设置 QoS 截止时间,并在目标硬件上用 cyclictest 与话题延迟测试验证,而不是仅凭配置推断。

最终判断依据应来自目标硬件上的实测数据:控制周期抖动、端到端延迟、丢包率、CPU 隔离效果、DDS 截止时间违约次数。只有这些指标同时满足各实时域的预算,选型与部署才算闭环。