Files
Cognitive_Agent/docs/workflows/can-read-trans.md
T
2026-08-26 20:11:09 +08:00

209 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# can_read_trans 双通道检测与控制
`can_read_trans` 是当前项目的 Linux C++ 命令行诊断程序。一个进程独占一台
ZLG USBCANFD-200U,并同时启动两个通道:
| 通道 | 用途 | 总线格式 | 状态依据 | 控制依据 |
| --- | --- | --- | --- | --- |
| CAN0 | 右前/副驾座椅 | Classic CAN,500 kbit/s,11 位标准 ID | `0x301–0x306/0x4FA` | 副驾固件原生 `0x300/0x29E/0x3CE` |
| CAN1 | 其余车辆设备 | 仲裁 500 kbit/s、数据 2 Mbit/s,Classic CAN + CAN FD/BRS | N7 CAN1 矩阵反馈 | 当前 CAN1 语义白名单 |
CAN0 的运动、通风、加热、木马和摇篮报文来自
`/home/orin/project511/passenger_seat_firmware`。程序不会把旧车机
`0x6A0/0x6A2` 当作控制协议。CAN1 的字节编译和反馈解析复用
`/home/orin/project511/project-code/canfd/can_read_trans.cpp`,避免维护另一份
可能漂移的 CAN1 实现。
## 构建和离线自检
```bash
make can-read-trans
make can-read-trans-test
```
生成的程序位于:
```text
build/can_read_trans/can_read_trans
```
如 CAN 库不在默认目录,可在构建时覆盖:
```bash
make can-read-trans CAN_READ_TRANS_CANFD_ROOT=/path/to/canfd
```
离线自检只核对 ZLG ABI、CAN0 固件字段字节序、动态模式 payload、CAN1 已验证
车窗 payload 和白名单拒绝规则,不打开 USB 设备,也不发送 CAN 帧:
```bash
build/can_read_trans/can_read_trans self-test
```
## 状态检测
持续监听两个通道,按 Ctrl-C 退出:
```bash
build/can_read_trans/can_read_trans monitor
```
监听 5 秒并打印最近状态汇总:
```bash
build/can_read_trans/can_read_trans status --duration-ms 5000
```
只跟踪 CAN0 或 CAN1 的每一条原始接收帧:
```bash
build/can_read_trans/can_read_trans monitor --channel can0 --trace-all
build/can_read_trans/can_read_trans monitor --channel can1 --trace-all
```
`--trace-all` 强制只读,不能与 `send` 组合。程序同时轮询 CAN1 的
`VCI_Receive` 和 `VCI_ReceiveFD`,不会因为只读了其中一个 SDK 队列而漏掉帧。
## 持续交互 Console
只读进入交互终端,可以持续查看状态和校验命令,但不会发送控制帧:
```bash
build/can_read_trans/can_read_trans console
```
确认台架净空、人员远离机构且急停可用后,显式允许本次会话发送白名单命令:
```bash
build/can_read_trans/can_read_trans console --execute
```
程序在同一进程中持续持有 CAN0/CAN1,后台接收线程不会在执行命令时停止,但只
缓存解析结果,不会把周期状态持续打印到交互终端。输入一次 `status` 才会打印一次
当时缓存的 CAN0/CAN1 状态快照。交互命令会根据两份白名单自动路由,不需要手工
添加通道前缀:
```text
can[all]> status
can[all]> seat passenger backrest position 35
[route] CAN0 <- seat passenger backrest position 35
can[all]> ac fan 2
[route] CAN1 <- ac fan 2
can[all]> outlet driver-left close
[route] CAN1 <- outlet driver-left close
can[all]> batch seat passenger basin relative up 10 ; ac fan 2 ; light ambient on
[batch validated] commands=3 execution=sequential stop-on-hard-failure
can[all]> whitelist
can[all]> mark before-shade-test
can[all]> quit
```
内置交互命令:
- `status`:一次性显示最近解析出的 CAN0/CAN1 状态,不发送查询帧;
- `whitelist`:显示全部可发送语义命令;
- `help`:显示 Console 帮助;
- `mark <文本>`:打印带时间戳的调试标记;
- `quit`/`exit`:复位两个通道、关闭设备并退出。
批量命令使用 `batch`,各条语义命令用英文分号分隔:
```text
batch seat passenger basin relative up 10 ; ac fan 2 ; light ambient on
```
程序先完成整批预校验,再发送任何帧。任意一条超出白名单、路由到被
`--channel` 禁止的通道、命令为空,或同批混用 CAN0 动态模式启动与 CAN0 轴移动,
都会拒绝整批且不发送帧。预校验通过后严格按输入顺序串行执行;构造、安全门禁或 SDK
提交失败时立即停止,后续命令不再发送。单风口开关的 3 帧全部提交成功、但在 1500 ms
内未收到 `0x4BB/0x37B` 匹配反馈时,记为 `submitted-unverified`,不误报实体动作成功,
但会继续下一条相互独立的批量命令。最终汇总分别打印 `submitted`、`verified`和
`unverified`。其他依赖闭环或前置状态的命令仍保持原有失败停止策略。单批最多 32 条,
每条最多 160 个字符。
CAN1 的 129 条规范/边界白名单命令已在离线自测中拆成 5 批全部通过;另有一批
30 条的混合用例覆盖门锁、车窗、空调、循环、单风口开关、风口位置、主驾座椅、灯光和遮阳帘。
这证明它们能共同通过批量语义校验并按 CAN1 路由,不等同于无条件完成实体动作:
单窗位置需要新鲜 `0x388`,风口标定坐标需要有效标定,座椅记忆需要 PAD 学习值和
新鲜 `0x494`,遮阳帘位置需要 `0x41A` 闭环;运行时前置条件不满足会停止该批次。
可以用 `--channel can0` 或 `--channel can1` 限制本次会话。路由到未选择通道的
命令会被拒绝。`console --trace-all` 是只读全帧跟踪模式;为防止抓包过程中误发,
它不能与 `--execute` 同时使用。
## 白名单控制
先查看程序接受的完整语义命令:
```bash
build/can_read_trans/can_read_trans whitelist
```
发送必须同时显式给出 `send`、目标通道、白名单语义命令和 `--execute`。例如:
```bash
build/can_read_trans/can_read_trans send \
--channel can0 \
--command "seat passenger backrest position 35" \
--execute
build/can_read_trans/can_read_trans send \
--channel can1 \
--command "ac fan 2" \
--execute
```
以上命令会操作真实硬件,执行前必须确认台架净空、人员远离机构、急停可用,且
车辆满足当前项目的安全条件。程序没有 `--id/--data` 一类任意原始帧发送入口;
不在 CAN0 或 CAN1 语义白名单中的命令会在构造帧前被拒绝。
CAN0 相对移动不会直接信任此前无线链路生成的原始帧:
1. 先读取新鲜、有效的 `0x302` 当前位置;
2. 计算限制在 0–100% 内的绝对目标;
3. 采用固件原生 `0x300` 闭环执行;
4. 只有当前位置不可用且相对量不超过该轴 15% 时,才使用固件限定时长和 Duty
的 Opcode `0x03` 回退;程序不直接暴露 Opcode `0x02`;
5. 未收到终态反馈时发送固件原生 STOP_ALL 安全帧。
当前台架已实测 `seat passenger basin relative up/down` 的物理方向与仓库中旧坐标
说明相反,因此本 C++ 工具把 `up` 映射为 CAN0 归一化位置增加、`down` 映射为减少。
此修正只作用于副驾 CAN0,不会改变 CAN1 主驾坐盆命令或任何 CAN1 帧。
热舒适命令必须先收到新鲜有效的 `0x4FA`,用它保留未被本次命令修改的另一项
功能,防止“调通风”意外关闭加热,或反之。
CAN0 固件要求除 `STOP_ALL` 外的 16 位 sequence 按有符号环形顺序递增。工具重启
后第一次控制若收到 `0x301 RejectReason=8 (SEQUENCE_OLD)`,程序不会猜测或遍历
序号,而是使用固件定义的 `STOP_ALL (0x09)` 序号同步屏障;确认 ACK 且四轴均停止
后,只重试原语义命令一次。若同步或重试仍失败,则保持 Console 可用并停止自动
重试,避免与另一个 CAN0 命令源争抢序号所有权。
## 反馈判定
程序明确区分四个层级:
1. `VCI_Transmit/VCI_TransmitFD=1`:SDK/适配器完成提交;
2. CAN ACK:至少一个正常节点确认该帧;
3. 协议反馈:CAN0 的 `0x301/0x302/0x306/0x4FA` 或 CAN1 对应状态帧出现;
4. 实体动作:机构或车辆设备确实完成动作。
SDK 返回 1 不能单独证明目标 ECU 接收或执行。CAN0 命令会匹配新的 Sequence、
Opcode 和后续状态代次;CAN1 保留既有矩阵反馈等待逻辑。最终仍应结合实体动作、
故障位和总线抓包判断。
## 设备占用和终端电阻
ZLG 设备应只有一个持有进程。运行本工具前,先停止正在占用同一 USB-CAN 盒的
Web 后端、旧版 `can_read_trans` 或 CANPro;否则会出现 `VCI_OpenDevice` 失败。
两个通道的适配器内部 120 Ω 默认都关闭。只有确认适配器位于对应总线物理端点且
拓扑确实缺少该端终端时,才显式增加:
```bash
build/can_read_trans/can_read_trans monitor --can0-termination
build/can_read_trans/can_read_trans monitor --can1-termination
```
不要把“收不到帧”直接解释为“需要打开终端电阻”;应先核对供电、共地、CAN_H、