本文档描述 OpenKidCar 的整体系统架构:上位机(大脑)/ 下位机(小脑) 分层,以及每个模块里到底有什么。
┌──────────────────────────────────────────────────────────────┐
│ ① 应用层 · 浏览器(数字孪生双端) │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 小车端 :8000 │ │ 家长端 :8001 │ │
│ │ 仪表盘+控制区 │ │ GPS/对讲/视频 │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ WebSocket │ WebSocket │
└──────────┼──────────────────────────────────┼────────────────┘
┌──────────▼──────────────────────────────────▼────────────────┐
│ ② 上位机 · 大脑(树莓派 · twin_server.py) │
│ ┌──────────────┐ ┌───────────────┐ ┌──────────────────┐ │
│ │ Brain 决策状态机│ │ VoiceController│ │ 对讲/视频/家长端 │ │
│ │ · 档位/灯光/静音 │ │ · vosk 离线识别 │ │ · WebSocket 服务 │ │
│ │ · 急刹/远程命令 │ │ · 指令规则表 │ │ · 对讲/视频转发 │ │
│ │ · 心跳/离线检测 │ │ · TTS 语音反馈 │ └──────────────────┘ │
│ └──────┬───────┘ └───────────────┘ │
│ ┌──────▼─────────────────────────────────────────────┐ │
│ │ SerialLink · 协议 V0.3 编解码 │ │
│ │ 帧格式:#命令:参数;CK:CRC8\n │ │
│ └──────┬─────────────────────────────────────────────┘ │
└─────────┼─────────────────────────────────────────────────────┘
│ UART 115200 协议帧
┌─────────▼─────────────────────────────────────────────────────┐
│ ③ 下位机 · 小脑(Arduino · 当前用 CerebellumSim 仿真) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ 实时循环 tick │ │ 协议处理 │ │ HAL 硬件抽象层 │ │
│ │ · 周期 50ms │ │ · crc8 校验 │ │ · hal_sim(仿真) │ │
│ │ · 状态上报 STAT│ │ · 帧解析/应答 │ │ · hal_mega(真实) │ │
│ └──────┬───────┘ └──────────────┘ └───────┬──────────┘ │
│ ┌──────▼────────────────────────────────────▼──────────┐ │
│ │ 执行与感知 │ │
│ │ · 油门/刹车/转向(积分式速度物理) │ │
│ │ · 灯光(大灯/灯带/转向灯/刹车灯) │ │
│ │ · 电池电压/温度/GPS 模拟 │ │
│ └─────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
│
┌───────────────────────▼──────────────────────────────────────┐
│ ④ 硬件执行层(未来真实硬件,替换 ③ 中的仿真) │
│ 树莓派 4B │ Arduino Mega 2560 │ 电机/电调 │ LED/灯带 │
│ 踏板/方向盘传感器 │ 电池 │ 4G/GPS 模块 │
└──────────────────────────────────────────────────────────────┘
| 模块 | 职责 | 代码位置 |
|---|---|---|
| Brain 决策状态机 | 维护执行状态(档位/灯光/静音/急刹/在线);处理小脑上行帧(READY/PONG/ACK/BTN/SEAT/EBRK/STAT);心跳保活 + 离线检测 | car_brain/brain.py |
| VoiceController 语音 | vosk 离线中文识别(开启即说指令);COMMAND_RULES 指令规则表(加指令只需加一行);TTS 语音反馈 |
car_brain/voice.py |
| SerialLink 协议层 | 协议 V0.3 帧编解码 + CRC8 校验;负责所有命令的收发 | car_brain/serial_link.py + protocol/ |
| TTS 语音反馈 | edge-tts 高质量语音("晓晓"),可换音色 | car_brain/tts.py |
| 数字孪生服务 | WebSocket 双端服务(小车端/家长端)、对讲音频与视频帧转发、GPS 模拟 | digital_twin/backend/twin_server.py |
大脑只做"决策",不做"实时执行" —— 它算力足但时序不确定,所以把要毫秒级响应的活全交给了小脑。
| 模块 | 职责 | 代码位置 |
|---|---|---|
| 实时循环 loop | 每 50ms 一帧:收命令、执行、上报状态(STAT) | firmware/arduino/src/main.cpp |
| 协议处理 | CRC8 校验、帧解析、统一 ACK 应答 | firmware/arduino/lib/protocol/ |
| HAL 硬件抽象 | 逻辑层只调 hal_* 接口:仿真实现(桌面跑)和真实引脚实现(Mega)互换,代码可移植 |
src/hal/hal_sim.cpp + hal_mega.cpp |
| 执行与感知 | 油门/刹车/转向(积分式速度物理)、灯光(大灯/灯带/转向灯)、电池电压 | simulator.py(仿真版)/ 固件 src/ |
小脑是"实时执行单元" —— 无操作系统、时序确定,直接驱动电机和灯光,是安全(急刹)的最后一道防线。
| 信号 | 路径 | 原因 |
|---|---|---|
| 油门 / 刹车 / 转向 | 前端 → 小脑直连 | 实时高频驾驶输入,低延迟优先 |
| 急刹(车上按钮) | 硬件直连小脑 + 小脑上报大脑 | 安全第一,不依赖大脑也能刹停 |
| 急刹(家长远程) | 家长 → 大脑 → 小脑 | 远程命令需大脑中转 |
| 档位 / 灯光 / 静音 | 大脑下发 | 决策型命令,大脑判断后协议下发 |
这就是真实汽车的分层:踏板/方向盘是传感器直连下位机,安全功能本地优先,智能决策由上位机控制。
| 层 | 现在(仿真) | 将来(真实) |
|---|---|---|
| 大脑 | Python 进程(twin_server.py) | 同一份代码,跑在树莓派 4B |
| 大脑↔小脑通道 | 内存管道(Pipe) | UART 串口(USB/GPIO) |
| 小脑 | CerebellumSim(Python 模拟物理) | 同一套协议逻辑,烧进 Arduino Mega 2560 固件 |
| 执行 | 网页里的状态数字/灯光 | 真实电机、LED、传感器 |
关键:因为逻辑层只依赖协议和 HAL 接口,大脑和小脑的代码原样移植,只换"通道"和"硬件层"。
Raspberry Pi 与 Arduino 通过串口(UART 115200)通信,协议 V0.3:
- 帧格式:
#命令:参数;CK:XX\n(CRC-8/ATM 校验,最大 128 字节) - 统一 ACK 应答、心跳 PING/PONG、离线检测
- 详见 communication_protocol.md