智能硬件机器人嵌入式物联网【免费下载链接】oomwooOpen-source vacuum robot cleaner项目地址https://gitcode.com/gh_mirrors/oo/oomwoo点击查看免费下载导读本文围绕 OOMWOO 开源扫地机器人的 MCU I/O 固件 RFC 展开讲解运行在 STM32G473 I/O 板 MCU 上的固件设计如何在 Arduino 友好层、FreeRTOS 任务层与 HAL/定时器中断实时核心之间分层使电机控制与硬安全防跌落、过流、CPU 看门狗在结构上与上层逻辑隔离。读完本文你将掌握该固件的三层架构规则、分阶段 bring-up 路线图、可量化的验收标准以及一套无硬件即可端到端跑通 CPU↔MCU 链路的宿主侧模拟实现与 ROS 2 桥接方案。一、背景CPU/MCU 分工与安全不依赖 Linux/ROS 2的硬约束OOMWOO 将计算拆分到两个处理器上这与消费级扫地机器人的主流做法一致且关键目的是让安全永远不依赖 Linux/ROS 2参见 ARCHITECTURE.md §5.4CPUCM4/CM5 类计算模块运行 ROS 2、SLAMslam_toolbox、Nav2、LiDAR 处理与高层行为决策。MCUSTM32G473VCT6Cortex-M4FLQFP100独占电机、编码器、全部传感器、电池充电控制与安全职责。CPU 从不直接驱动电机。CPU ↔ MCU 之间通过一条自定义高速串行协议而非 micro-ROS传递命令/遥测外加离散 GPIOCPU 电源开关、MCU 在丢失健康包时断言的 CPU 复位线。本固件模块就是这颗 MCU 上运行的软件。该模块最核心的设计约束可以概括为一句话安全绝不能依赖 Linux/ROS 2且按下面的分层架构也绝不能依赖友好的 Arduino 层。二、一条规则概括的架构三层分层安全结构性隔离Arduino 友好与实时安全在 OOMWOO 看来不是二选一而是通过分层同时获得——贡献者所触碰的层不是负责机器人安全的层层内容归属与职责Layer 3 — ArduinoSTM32duinoAPI新行为、新特性、外设 bring-up 的贡献者友好层社区贡献者在此开发Layer 2 — FreeRTOS 任务静态分配comms、control、telemetry、charging、safety supervisor看门狗喂狗、有界的响应时间任务级调度Layer 1 — HAL/定时器中断实时核心电机控制、硬安全切断、CPU 看门狗维护者专属、需安全评审规则安全与电机控制核心在结构上与 Arduino 层隔离——即使贡献者的 sketch 出现 bug 或死循环也无法击穿防跌落停机、过流切断或 CPU 看门狗因为它们位于上层无法饿死的中断与硬件看门狗之中。代码评审的边界由此划定凡是会写 Layer 3 的贡献者都不触碰 Layer 1 的安全逻辑。这一分工与 ARCHITECTURE.md 的系统总览 中MCU 拥有电机与传感器、硬安全bumper/cliff/wheel-drop 停止、电流限制、CPU 看门狗全部驻留 MCU的描述完全一致也与 I/O 板软件接口 RFC 的既定目标MCU 拥有的安全事件不依赖 ROS 2 存活相呼应。三、Request for Contribution分阶段 bring-up 路线图该 RFC 同时也是贡献征集书与验收门槛。完整的固件设计存于固件仓库这里给出分阶段 bring-up 指南外围设备映射细节见固件仓库 READMEBlink SWD 串口回显在 G473 开发板上跑通最小硬件链路。CPU 串行链路实现 io-board-interface 的帧格式 健康/看门狗握手回环测试全绿。单驱动轮闭环H 桥 PWM 编码器捕获 实时核心中的速度 PID这是其余所有电机的模板模式。全部执行器吸尘风机BLDC FG、主刷/边刷、LiDAR 旋转电机、水泵、拖布电机/舵机——每个都要带电流检测。全部传感器cliff / dock / 侧向接近 IRADC、bumper、wheel-drop、IMUSPI、电流通道。安全层ISR 级 cliff/bumper/wheel-drop 停机、逐电机过流限制、IWDG、CPU 看门狗/复位测量并记录每个切断的最坏情况反应时间附带 hazard note。充电管理功率路径充电器控制、0.5C 限流、输入 DPM、充电器功率不足的优雅处理。集成与 CPU或模拟 MCU 串口工具端到端联调。安全关键代码必须在合并前经过维护者安全评审过流、热、短路、机械夹持——都要附 hazard note。验收标准RFC 给出的验收标准是客观、可度量的确定性实时核心——每个安全切断都有实测并记录的最坏情况反应时间安全与层无关——人为挂起一个 Arduino 层任务必须不能击穿防跌落停机、过流切断或 CPU 看门狗并要求演示证明实现 io-board-interface 串行契约——回环 集成测试通过每个执行器与传感器都在台架上被驱动过有文档、可被他人复现充电行为符合规格——维持 0.5C 上限弱充电器下优雅降级安全关键代码通过维护者安全评审并附带 hazard note。维护者在多个合规候选中按上述标准择优未被选中的实现同样是有价值的学习练习与后备方案。四、支撑性契约CPU ↔ MCU 串行协议协议 v1固件的第二阶段直接依赖 CPU/MCU 串行契约草稿。它的设计目标决定了固件实时核心的形态保持安全关键固件小而确定、独立于 Linux让过期或损坏的命令停止机器人而不是继续运动帧格式简单到 STM32 固件、Python 测试与未来的 C/Rust 桥都能共用。4.1 链路属性与帧格式属性草案值物理链路UART TTL 或 USB CDC相同帧格式波特率首选 1 Mbaud早期台架测试支持 115200字节序小端负载字段帧格式二进制固定头 负载 CRC-16/CCITT-FALSE传输重试快速 setpoint 无重试仅配置类命令 ACK/NACK运动超时心跳或 setpoint 过期时 MCU 停止驱动与清洁电机帧布局magic字节计入 CRC解码器必须拒绝版本错误、长度不可能或 CRC 错误的帧流式解码器可丢弃噪声直到下一个OWmagicoffset size field 0 2 magic: ASCII OW 2 1 protocol version: 1 3 1 flags 4 2 sequence number 6 2 message type 8 2 payload length 10 N payload 10N 2 CRC-16/CCITT-FALSE over header payload4.2 消息 ID 分区与最小消息目录范围方向含义0x0001-0x00ffCPU - MCU控制、心跳、复位、配置0x0100-0x01ffCPU - MCU执行器 setpoint0x7000-0x70ff双向ACK/NACK 与协议诊断0x8000-0x80ffMCU - CPU状态、遥测、安全事件最小消息目录频率与负载来自 cpu_mcu_serial_contract.md常量范围可在 参考编解码器 中核对ID名称方向频率负载0x0001HEARTBEATCPU - MCU20-50 Hzu32 cpu_time_ms,u8 cpu_mode0x0002ESTOP_SETCPU - MCU事件u8 active,u16 reason0x0003CLEAR_LATCHED_FAULTCPU - MCU事件u16 fault_mask0x0004IDENTIFY_REQUESTCPU - MCU连接/重连空MCU 应答MCU_HELLO0x0101DRIVE_SETPOINTCPU - MCU20-50 Hzi16 linear_mm_s,i16 angular_mrad_s,u16 duration_ms0x0102CLEANING_MOTORS_SETCPU - MCU1-10 Hzu8 main_brush_pct,u8 side_brush_pct,u8 fan_pct,u8 pump_pct0x0103LIDAR_MOTOR_SETCPU - MCU1-10 Hzu8 pwm_pct0x0104LED_SETCPU - MCU事件u8 led_id,u8 mode,u8 brightness_pct0x7001ACK双向事件u16 acked_seq,u16 status0x7002NACK双向事件u16 rejected_seq,u16 error_code0x8000MCU_HELLOMCU - CPU启动/事件u16 firmware_major,u16 firmware_minor,u32 build_id0x8001FAST_TELEMETRYMCU - CPU50-100 Hz编码器计数 快速输入标志低 8 位为兼容性安全锁存位0x8002SAFETY_EVENTMCU - CPU事件 锁存u16 event,u8 active,u16 detail0x8003POWER_TELEMETRYMCU - CPU1-5 Hz电池、充电器、电流、热概要0x8004MCU_DIAGNOSTICMCU - CPU1 Hz/事件看门狗、循环时序、丢帧、故障位0x8005SAFETY_STATEMCU - CPU10 Hz 事件u32 timestamp_ms,u16 active_flags,u16 latched_flags几个关键语义IDENTIFY_REQUEST使启动不依赖哪个端点先上电SAFETY_STATE是权威周期安全快照安全事件码N映射到位N-1FAST_TELEMETRY.safety_latched_flags单字节作为兼容字段保留低 8 位新桥必须用SAFETY_STATE重建完整的 active/latched 状态未知高位保留用于诊断并视为抑制运动直到其含义明确。4.3 十条安全事件与失败行为码事件MCU 行为1/2BUMPER_LEFT/BUMPER_RIGHT立即停止驱动仅当 cliff/wheel-drop 清晰时允许有界恢复3/4CLIFF_LEFT/CLIFF_RIGHT停止驱动与清洁电机要求安全撤退或人工介入5/6WHEEL_DROP_LEFT/WHEEL_DROP_RIGHT停止驱动与清洁电机锁存至轮子重新着地7BRUSH_OVERCURRENT停止受影响的刷detail 报告刷 ID8FAN_OVERCURRENT停止风机驱动按 MCU 策略继续9CPU_HEARTBEAT_TIMEOUT停止所有可动输出去抖后可选择性复位 CPU10ESTOP停止所有可动输出锁存至显式清除失败场景的预期 MCU 响应坏 CRC 丢帧并递增诊断计数未知消息 ID 在帧其余部分有效时回 NACKsetpoint 越界则拒绝并停止受影响的执行器CPU 心跳超时停止驱动与清洁电机并发CPU_HEARTBEAT_TIMEOUT串口重连时 CPU 发IDENTIFY_REQUEST、MCU 回MCU_HELLO并在新的心跳与 setpoint 到达前保持执行器关闭MCU 看门狗复位后以全部运动输出禁用状态启动并报告复位原因。4.4 时序规则实时性的量化锚点CPU 在桥激活期间以20-50 Hz发布HEARTBEATCPU 以短duration_ms发布DRIVE_SETPOINTsetpoint 过期即清零驱动输出草案最大DRIVE_SETPOINT.duration_ms250 ms参考编解码器常量MAX_SETPOINT_DURATION_MS 250草案 MCU 心跳丢失硬停150 ms配置命令可 ACK快速 setpoint 应以新 setpoint 覆盖而非重试。这些常量在 oomwoo_mcu_frame.py 中与负载打包函数一起落地MAX_LINEAR_MM_S 500、MAX_ANGULAR_MRAD_S 4000、MAX_SETPOINT_DURATION_MS 250并且duration_ms 0会被直接拒绝。驱动 setpoint 的合法性检查越界抛ValueError在 test_oomwoo_mcu_frame.py 中有对应用例例如pack_drive_setpoint(501, 0, 100)与pack_drive_setpoint(0, 0, 251)都必须抛错。五、ROS 2 桥接映射桥保持薄安全留在 MCU固件链路的 CPU 侧由一个oomwoo_mcu_bridge节点承担草案见 ros2_mapping.mdROS 2 负责高层行为MCU 负责硬安全与电机 IO桥只做翻译。订阅输入节选/cmd_velTwist→ 带钳位的DRIVE_SETPOINT、/oomwoo/safety/e_stop→ESTOP_SET、/oomwoo/cleaning/main_brush_pct等四个清洁电机话题→CLEANING_MOTORS_SET、/oomwoo/lidar/motor_pct→LIDAR_MOTOR_SET、/oomwoo/io/clear_faults服务 →CLEAR_LATCHED_FAULT、/oomwoo/dock/final_cmd_vel入坞低速阶段 → 更紧钳位的DRIVE_SETPOINT。发布输出节选/odom与/joint_states源自FAST_TELEMETRY、/battery_state源自POWER_TELEMETRY、/oomwoo/io/bumper|cliff|wheel_drop|dock位域、四个/oomwoo/dock_ir/*话题、/oomwoo/io/mcu_status与/diagnostics诊断。生命周期桥应实现为 lifecycle 节点unconfigured无串口、无执行器命令→inactive可打开串口并发IDENTIFY_REQUEST等待MCU_HELLO但不发心跳与运动输出→active心跳运行、接受 setpoint、发布遥测→error心跳停止、setpoint 清零、诊断说明原因。取消激活、关停或崩溃都会使心跳停止随后由 MCU 独立停止运动——这是最后一行是设计而非兜底的体现。仲裁桥不解决高层仲裁同一时刻只允许一个 ROS 2 组件写/cmd_vel只强制底层安全钳位最大线/角速度、钳位 setpoint 时长、deactivate 时发零 setpoint、e-stop/cliff/wheel-drop/CPU 超时锁存期间停止转发运动。入坞阶段由/oomwoo/dock/final_cmd_vel提供比常规导航更紧的速度钳位与更短的 setpoint 时长而 MCU 的硬停权威不变。六、当前进展无硬件的宿主侧端到端实现RFC 状态为进行中宿主侧框架、安全策略、模拟器与 ROS 2 桥已经存在但真实 STM32 HAL、电机控制、ISR 集成、IWDG、充电与实测切断时间仍待开发。硬件里程碑应先在Nucleo-G474上构建真实板卡制造完成后再迁移。Creative-Dhanush 的实现 是当前最完整的宿主侧实证CPU↔MCU 链路今天就能在笔记本上端到端运行无需任何硬件——一个 ROS 2 栈以真实的二进制线格式驱动真实的 MCU 安全逻辑当 ROS 2 侧被杀掉时MCU 自己停下电机。6.1 设计要点模拟器就是固件本身模拟器不是固件的模型它运行的就是固件ow_frame/ow_stream_decoder/ow_safety_core这些翻译单元与交叉编译到 STM32G473 的完全相同只有一个实现因此模拟器与目标板永远不会漂移。它是 oomwoo-install 的换行分隔 JSON 桩 的 drop-in 替代品——同样的--link、--period、--battery-mv参数但说的是真实契约。模块划分模块职责ow_frame.{h,cpp}CRC-16/CCITT-FALSE、小端助手、全部 12 种已定义消息类型的编解码——逐字节构建、绝不通过 struct 做memcpy以绕开 C/struct.pack填充不一致ow_stream_decoder.{h,cpp}固定缓冲流式解码器跨读缓冲部分帧、损坏后逐字节重同步ow_safety_core.{h,cpp}安全状态机——心跳超时、setpoint 过期、bumper/cliff/wheel-drop/过流/e-stop、锁存故障ow_link.{h,cpp}把前三者串成可工作的 MCU字节进 → 策略 → 帧字节出带出站排序不拥有任何传输因此同一代码可零 I/O 单测、可在 pty 上运行、可交叉编译到目标板ow_telemetry.{h,cpp}按 ros2_mapping.md 要求的 50-100 Hz 周期FAST_TELEMETRYow_sim_mcu伪终端上的 MCU带 stdin 故障注入oomwoo_mcu_bridgerclpy lifecycle 节点9 订阅 9 发布接口、四个指定 lifecycle 状态、仲裁钳位值得注意桥原样导入xbattlax 的oomwoo_mcu_frame.py而非重新实现链路两端共享同一个线格式定义而不是对契约的两种独立解读。6.2 在笔记本上运行它需要 Linux模拟器使用openpty与 ROS 2 Jazzy两个仓库并排克隆# MCU 侧 —— 安全核心作为宿主二进制跑在伪终端上 git clone https://github.com/Creative-Dhanush/oomwoo-io-firmware pip install -U platformio (cd oomwoo-io-firmware pio run -e native_sim) # CPU 侧 —— ROS 2 桥 git clone https://github.com/Creative-Dhanush/oomwoo-mcu-bridge cd oomwoo-mcu-bridge colcon build source install/setup.bash ros2 launch oomwoo_mcu_bridge demo.launch.py \ sim_binary:$PWD/../oomwoo-io-firmware/.pio/build/native_sim/programlaunch 文件启动模拟器、创建 pty、驱动桥走完configure→activate因此心跳已运行、遥测已流动ros2 lifecycle get /oomwoo_mcu_bridge应显示active。然后驱动它、破坏它、看是谁停下机器人操作现象ros2 run teleop_twist_keyboard teleop_twist_keyboard轮子转动/joint_states与/odom前进向模拟器 stdin 输入cliff left on/oomwoo/io/cliff→ 1轮子停止/cmd_vel无法覆盖它输入cliff left off仍然停止——cliff 锁存不会自清除ros2 service call /oomwoo/io/clear_faults std_srvs/srv/Trigger故障释放运动恢复kill掉桥心跳停止 →MCU 自行停电机没有任何 ROS 2 请求它这么做6.3 证据CI 中约 2 分钟内跑完检查结果帧编解码、流式解码器、安全核心、链路回环pio test -e nativeASanUBSan54 个测试10 / 9 / 15 / 20金帧向量与上游参考逐字节一致通过流式解码器 vs Python 参考的差分模糊测试2000 例0 不一致pty 上的模拟器每字节由上游参考解码并再编码6 例逐字节精确桥帧单测10桥 ↔ 模拟器端到端仅断言 ROS 2 话题5pio run -e nucleo_g474re交叉编译通过其中两项值得特别注意因为它们是本可能被伪造的检查线格式校验以他人实现为 oracle——模拟器发出的每一帧都由 vendored 上游参考解码、再编码、并要求逐字节复现原帧会说真协议是被验证的而非被断言的回环套件全程走线——与直接把手持解码帧交给SafetyCore的安全核心测试不同test/test_link的每个测试都以字节进出因此帧格式、CRC、排序或负载打包的任何缺陷都会使测试失败。桥的 CI 日志原样输出/cmd_vel moved the wheels 0.000 - 6.743 rad, odom x0.236 m cliff latched; /cmd_vel could not override it and the sensor clearing did not release it /oomwoo/io/clear_faults released the latch and motion resumed heartbeat stopped on deactivate and the MCU stopped the wheels by itself 5/5 passed6.4 安全立场MCU 拥有的安全保持 MCU 所有且故意迟钝安全核心在故障时只停止执行器不后退、不扫描、不重规划、不决定机器人去向导航、建图及任何需要完整上下文的事都留在 CPU核心没有任何方式命令运动、只能抑制运动从机制上强制了这一分工。锁存故障不自清除cliff、wheel-drop、e-stop 只在显式CLEAR_LATCHED_FAULT后释放唯一例外是 wheel-drop——按契约字面语义在轮子重新着地时清除。过流只停受影响的电机并在SAFETY_EVENT.detail中报告是哪一个而非一刀切全停。每个入口点都把当前时间作为参数传入、从不读时钟因此 150 ms 超时可确定性地在恰好 149 ms 和 151 ms 处测试无需睡眠。核心中无堆、无异常、无 Arduino 头文件operator new在编译期被删除同一源码既可以构建为普通 hosted C17也可以构建为目标固件。6.5 对照里程碑的进度与明确未实现项#里程碑状态1G473 开发板 Blink SWD 串口回显未开始——需要硬件2CPU 串行链路帧格式 健康/看门狗握手回环测试宿主侧完成3单驱动轮闭环未开始4全部执行器未开始5全部传感器未开始6ISR 级安全、IWDG、实测最坏情况反应时间未开始——策略已存在ISR 与时序工作没有7充电管理未开始8与 CPU 或模拟 MCU 串口工具集成模拟 MCU 侧完成ROS 2 桥端到端驱动它明确未实现如实陈述无 STM32 HAL 或板级 bring-up无电机 PWM、电机电源使能 GPIO、充电或 IWDG安全核心只发出intent——stop、SAFETY_EVENT、NACK——由调用方接到硬件上任何电机负载都不应接到这里无实测最坏情况反应时间模拟器时序是抢占式调度器下的笔记本时序与真实器件无关编码器与轮距常量为占位符SPEC 尚未固定齿轮比与编码器分辨率因此模拟器的距离无意义方向、符号与安全说停就停是有意义的POWER_TELEMETRY与MCU_DIAGNOSTIC在契约中没有负载布局这正阻塞/battery_state充电字段、/oomwoo/io/mcu_status与四个/oomwoo/dock_ir/*话题——它们宁可保持未发布也不填充看似合理的值在标准 ROS 2 话题上伪造battery.percentage比缺失更糟。里程碑 3-7 开放且无人认领。线契约就是接口因此未来换成 Zephyr 写的 MCU、只要会说这套协议就能与现有桥无缝工作。七、建两端发现的三处契约缺口本轮贡献的实际产出同时实现 CPU 侧与 MCU 侧的价值是把契约文档逼到明确。三处发现现已解决同时保留既有 protocol-v1 帧完整安全快照SAFETY_STATE携带 16 位 active 与 latched 掩码旧FAST_TELEMETRY.safety_latched_flags字节作为兼容字段保留事件 9/10 在权威周期快照中表示。CPU 晚接入IDENTIFY_REQUEST允许 CPU 在每次连接/重连后请求一份新鲜MCU_HELLO无需武装输出或刷新心跳。分裂 magic参考StreamDecoder现在保留尾部孤立的O并有回归测试确保下一个读取到达W时补全帧对应 test_oomwoo_mcu_frame.py 的 split-magic 用例。关于CPU 心跳超时维护者在讨论中给出的答案是约 5 分钟用于 CPU 启动时间——这与稳态心跳超时是不同定时器稳态值契约仍标注为草案的100、150 或 250 ms因此稳态值作为Config字段默认 150 ms 而非硬编码常量。启动用结构而非长超时解决执行器在上电或重连后保持禁用直到新的HEARTBEAT和新的DRIVE_SETPOINT都到达——因此慢启动的 CPU 无论数字多少都不会产生运动。八、为贡献者提供的参考路径固件模块 RFC本文主体contributions/mcu-io-firmware/README.md宿主侧实现与端到端演示contributions/mcu-io-firmware/Creative-Dhanush/README.md串行契约草稿规范性cpu_mcu_serial_contract.mdROS 2 映射草案ros2_mapping.md参考编解码器oomwoo_mcu_frame.py 与测试 test_oomwoo_mcu_frame.py机器可读协议清单与金向量protocol_v1.jsonconformance 说明确定性样例帧生成器 sim_mcu.py系统架构与 CPU/MCU 分工ARCHITECTURE.md §5.4ROS 2 接口草案见 SOFTWARE_INTERFACES.md结语OOMWOO 的 MCU I/O 固件以一条规则为核心——用分层让安全在结构上与贡献者层隔离——并以 8 个可度量的里程碑、6 条验收标准与安全关键代码必须通过维护者安全评审的门槛组织社区贡献。当前实现已把最困难的部分先做掉了线格式的正确性、解析器对损坏/碎片输入的鲁棒性、安全策略在每种规定条件下的行为都在笔记本上被证明。剩下的里程碑 3-7 需要一块 Nucleo-G474 把策略接到真实的中断、H 桥与看门狗上——这正是固件从宿主侧证明走向实测反应时间的下一步。赞分享智能硬件机器人嵌入式物联网【免费下载链接】oomwooOpen-source vacuum robot cleaner项目地址https://gitcode.com/gh_mirrors/oo/oomwoo点击查看免费下载相关推荐OOMWOO I/O Board 软件接口实战指南CPU↔MCU 串行契约、安全机制与 ROS2 桥接设计OOMWOO I/O Board 软件接口实战指南CPU↔MCU 串行契约、安全机制与 ROS2 桥接设计 OOMWOO 开源扫地机器人通过一张定制 I/O智能硬件机器人嵌入式物联网OOMWOO I/O 与电机驱动 PCB 设计指南基于 KiCad 从 RK3562 参考原理图裁剪出 STM32G473 载板OOMWOO I/O 与电机驱动 PCB 设计指南基于 KiCad 从 RK3562 参考原理图裁剪出 STM32G473 载板 本篇指南围绕 OOMWOO智能硬件机器人嵌入式物联网OOMWOO I/O PCB设计解析STM32G47360个GPIO如何驱动10个电机和15个传感器OOMWOO I/O PCB设计解析STM32G47360个GPIO如何驱动10个电机和15个传感器 OOMWOO 是一款面向极客与开源社区的 开源扫地机器智能硬件机器人嵌入式物联网创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
