项目概述
聆行 VoxDrive 是一套跑在真实硬件上的双 SoC 分布式车载智能座舱:
- RK3588(LubanCat-4)= 媒体 + 端侧语音节点:摄像头采集 → MPP 硬件编码 → MP4 循环存储 / RTMP 推流,NPU 跑行人/车辆检测做事件锁录;流式 ASR(fp16 三模型 NPU 分载)与 TTS 合成(SummerTTS)也都落在这块板;
- Jetson Orin Nano = 中心 AI 节点:LLM / RAG / 意图路由 / 画面问答 / Qt 数字座舱,全离线、不上云;
- 两板以太网互联:视频走 RTMP,控制与事件走 ZeroMQ。语音可以控制录像、查状态、抓拍,还能直接问"画面里有什么"(VLM 看行车画面作答);
- 麦克风与音箱是接在 RK 上的同一 USB 设备:说话本板识别、跨板查询、应答本板播报,播报期自动静音防"自己听到自己"(回灌)。
设计原则:数据密集走专用加速器(RK 的 VPU/RGA/NPU),模型密集走中心算力(Jetson 的 GPU);实时敏感、算力可承担的小模型(ASR/TTS)下沉边缘,大模型(LLM/VLM)留中心。
双板实物
左上 Jetson Orin Nano(带散热扇),右侧 RK3588 LubanCat-4,两板经路由器以太网互联;左下 7 寸 DSI 触摸屏接 RK,正在运行座舱 UI 的桌面会话;麦克风/音箱 USB 组合设备接 RK 侧:

系统架构
两个平面刻意分开:视频大流量不进控制面,控制面单条消息只有几百字节——跨板工具往返实测 0.73-2ms。语音链同理:音频采集、识别、合成、播报都在 RK 本板,跨板只传识别文本与应答文本两条轻量通道。
真机实拍(RK3588 7 寸触摸屏,真屏拍摄)
行车记录页:左侧 mediamtx 拉流的实时预览(断流自动重连),右侧状态卡轮询 RK(帧率/段数/磁盘水位环)+ 实时事件日志,底部按钮经 tool_bus 直控真设备;语音气泡「你:打开行车记录」是刚说完一句语音导航后 UI 的回显:

主页磁贴:录像状态横条(30.0fps / 138 段 / 5.8GB 可用)与四张磁贴的数据全部来自跨板实时链路,无一张静态图:

行车记录仪原始画质参考(IMX415 直出 1080p 快照,RK 端 NV12→JPEG、跨板抓拍约 0.15s):

车控页 + 语音上屏(Jetson 侧实例同款界面):问"现在录着吗"走真实链路(识别 → 路由 → 跨板查询 → LLM 组织 → TTS),底栏字幕是用户原话、气泡是基于真实工具应答生成的播报:

行车记录视频链路(RK3588)
几个值得说的实现细节:
- NV12 同制式直入 MPP:ISP 出的 NV12 不做格式转换直接编码(全链路 CPU ~2.8%),RGA 只用于检测前处理的缩放;
- MP4 分段的坑:movenc 不代转 Annex-B,需逐 NAL 转 AVCC 并手工组装 avcC;NAL 边界 off-by-one 的症状是"时长正常但解码全错"——验收判据用逐段全量解码而非 duration;
- 事件锁录:检测线程经"最新帧槽"旁路挂接(忙时覆盖、不反压主管线),命中即给当前段加
LOCK_前缀,循环覆盖天然豁免,另有配额防锁段吃满磁盘; - rkisp 残留态:boot 残留下 S_FMT 原样传回会得到行距矛盾的布局(SEGV/无帧),修复=清零强制重算 + 读回几何校验。
端侧语音闭环(推理与音频 I/O 都在 RK,LLM 留 Jetson)
语音链的形态一句话:音频不出板,跨板只传文本。麦克风/音箱(同一 USB 设备)接 RK——voice_service 进程内采集 16k PCM → kaldi-native-fbank 特征(与 sherpa C++ 前端逐位一致)→ zipformer 三模型 fp16 NPU 三核分载流式解码 → 识别文本 REQ 回 Jetson 意图路由 → 应答文本回到 RK 的 tts_node(SummerTTS 多核合成)→ 本板播报。
- 防回灌:麦克风和音箱是同一块硬件,播报期做事件驱动静音,解除须等 play_end 后麦克风连续 1s 真实静音(+超时兜底);
- ASR 选 fp16 而非 int8:INT8 全套量化精度分析实测不满足流式精度(状态累积崩溃),fp16 零量化损失且 RTF 0.3 以内;TTS 评估 matcha RKNN 路线后放弃(声码器输出 STFT 谱需宿主 ISTFT,NPU 图不适用),改用 SummerTTS 引擎源码上板编译——真麦声学自环实测识别逐字正确、无循环。
Jetson 侧保留三个关键架构决策:
- 真设备域确定性直通。1.5B 小模型在 7 个工具间选择实测不可靠(“关闭预览"被选成关车窗、“还剩多少存储"选成编数),改为关键词命中即直达跨板工具、LLM 只把真实结果组织成播报——控制类链路降到 0.43s。
- 语义双路路由。规则通路兜底 + 语义通路(离线意图中心余弦,阈值留出探针校准):关键词全 miss 的改述问句直接走 RAG 快路径,9.4s → 1.2s;语义通路故障自动退化为规则单路。
- 推理位置按实时性分层。ASR/TTS 下沉边缘 NPU/CPU,LLM/RAG 留中心——判据是"实时敏感 × 算力可承担”,不是无脑把模型搬到一块板。
RAG 语料是真实车主手册(官网 PDF → 三级过滤 → 577 块向量库,板上构建),召回阈值 0.48 由"手册内改述句 vs 手册外噪声"的相似度实测分界定出。
座舱 UI 双端部署(RK 触摸屏)
同一套 dashboard 代码不改一行,配置切换跑在两种形态:
- Jetson 桌面与 RK 7 寸 DSI 触摸屏(1024×600,Goodix 触摸)各跑一个实例,双端同时在线、订阅同一套 ZMQ 数据源——UI 是纯客户端,换屏只是多一个实例,服务端拓扑零变化;
- 小屏自适应:可用几何过小时自动最大化 + X 级缩放 1.5625× 到 1600×938 逻辑设计尺寸(Qt 自带
QT_SCALE_FACTOR在本板组合上首帧后冻结,实测弃用); - 真机闭环已验证:说"打开行车记录”→ RK 触摸屏切页并自动拉起 RTSP 预览,画面色彩正确、跨屏数据实时。
实测数据
所有数字可复述测量方法,无估算值:
| 指标 | 实测值 |
|---|---|
| 采集(IMX415 → NV12 1080p) | 30.0fps,max 帧间距 33ms(驱动时间戳,120 帧) |
| MPP H.264 硬编 | 延迟 avg 4.8 / max 8.5ms,全链路 CPU ~2.8%(单核) |
| 跨板拉流(RK→Jetson mediamtx) | 1080p30 全量解码零错误(30.2s),静态场景 VBR 下探 0.71Mbps |
| 跨板控制面(ZMQ REQ) | RTT 2ms(路由器组网);直连组网复测 avg 0.73ms(0.64-0.83,n=20);抓拍 143ms(含 JPEG 编码 + 183KB base64 跨板) |
| RKNN 事件锁录检测 | 推理 25.3ms ewma(NPU core0),检测线程挂接下录像 30fps 无损;连续 1.5h+ 录像 ewma 26.2ms / 5154 次 |
| 语音闭环全程(文本入口→播报结束) | 3.55-5.47s(LLM 组织 0.86-1.07s 为大头,跨板工具仅 2-10ms);修复回灌级联后干净口径:router 应答 1.49-4.14s,→播报结束 7.0-17.9s(=答复文本+合成+实时音频时长,随答复长度自洽) |
| ASR 推理(RK NPU fp16 三模型分核) | RTF 0.26-0.30(10.1s 中英混复测 0.296),线上流式转写与 Jetson ORT fp32 贪心逐字一致;前端特征与 sherpa C++ 逐位一致(对拍 maxabs=0) |
| TTS 合成(RK SummerTTS 多核 CPU) | RTF 0.22-0.27(7 字句 0.63s、28 字句 1.47s),合成 PCM 回传播放时长精确吻合 |
| VLM 画面问答(Qwen2-VL-2B,按需换出 llm) | 应答与画面实测一致;周期=快照 0.35s+推理 4.7s+恢复 14.9s(冷启动 ~25-30s);GPU 铁律=共存 OOM/须 evict 页缓存/ctx 2048+图降采样 960×540 |
| 真麦声学闭环(USB 组合设备) | 播命令→空气→麦克风→NPU 识别逐字正确→真数据应答→本板播报+防回灌静音→无循环 |
| LLM | Qwen2.5-1.5B Q4_K_M,22.8 token/s(首测);第三轮复测 20.5-21.0 token/s(llama.cpp 纯生成口径 ×3,全栈在线) |
| 长稳 | 16min 双板联跑 fps 稳定 30.00、29417 帧零异常;故障注入 5s 精确超时自愈;第三轮复测时已连续录像 1.5h+(154k 帧) 30.001fps、RTMP 零写错误 |
| 回归验证 | 2026-09-06 第二轮全量验证全绿:RK 5/5 + Jetson selftest 8/8 + 回归 4/4×2 + E2E 抽查(RTSP 90 帧零错误/色度中性、HLS、跨板语音查询含真实值 rtt 1.6-2.2s、跨板抓拍 123ms);同日傍晚第三轮性能复测(跨板 RTT/LLM/RAG 208-280ms/ASR/TTS/E2E 全栈在线全项重测) |
五个实战排障叙事
比数字更有意思的是踩坑(每条都有一手证据链):
- RKNN「流式状态发散」— 症状像量化精度,根因是内存布局。zipformer 转 RKNN 后流式解码首块全对、之后结构性错乱(值集不变、位置全乱),INT8/fp16 同症状——直觉会怪量化或图编译。真因是 RKNN 对 4D 图输入的布局约定:缓存张量必须按
transpose(0,2,3,1)预转置喂入。定位:探针模型 chunk 级逐张量对账 → 周期标记指纹排除数值精度 → 4D 直通 tiny 图暴力解出唯一转置;修复后转写与 fp32 逐字一致。教训:多输入非图像模型上 NPU,先做直通等价自测。 - ZMQ linger 默认无限:对端进程死亡时,客户端析构带着未投递消息永久阻塞,工具总线整体楔死。没有 gdb 条件,靠
/proc/<pid>/wchan+ 残留 context 线程定位;修复 linger=0 + EINTR 重试后,故障注入 5s 精确超时、恢复即自愈。 - 1.5B 选错工具:LLM 自由选工具实测不可靠(关预览→关车窗),改成"关键词直通执行 + LLM 仅组织结果"——把确定性还给代码,把语言能力留给模型。
- rkisp 残留态:S_FMT 原样传回残留行距,驱动照收但布局自相矛盾,症状是段错误 + 无帧。教训:不信任驱动的"照单全收",写入前清零重算、读回后几何校验。
- 防回灌静音窗口被"事件语义差"击穿:E2E 对账发现播报结束时间异常,排查见扬声器播的回答被自家麦克风识别、级联出新查询。根因是跨板事件语义差:Jetson 的
play_end是"合成+写入完成"(12s 音频 2.9s 就发出),而播报在 RK 实时进行——静音在"写完"后 0.6s 就解除,长答复播到一半麦克风听到自己的声音。修复=静音期顺带能量观测,解除改为 play_end 后麦克风连续 1s 真实静音;同场景对比级联 3 次 → 0 次。教训:跨板系统的"同名词事件"未必同语义,端到端对账日志是最好的透视镜。
与站内其他项目的关系
- 车载 AI 语音助手(Jetson):本项目的 Jetson 侧前身,七服务架构与音频链路由它收编重构而来;
- X 射线焊缝检测下位机:另一条嵌入式线(STM32 + FreeRTOS)。