结论:OSCC 的价值在于它选了一条最难但最可辩护的路线:不欺骗 CAN 报文、不改原厂安全用例、不破解 ADAS 功能,而是把控制命令注入到转向盘扭矩传感器、油门位置传感器与制动位置传感器这三个物理接口上。代价是必须自己补上原厂本来承担的安全机制——文档里能明确数出来的有三层:enable/disable 门控、每 200 毫秒必须调用一次的看门狗、以及默认开启的操作者超控。任何把这三层当可选项的实现,都偏离了它的设计前提。
接口定位:低层注入而不是报文欺骗
这套系统由软件 API、固件与硬件设计三部分构成,通过车载通信网络与控制系统的模块化接口实现计算机控制。它的能力边界可以拆成三件事:向车辆发送控制命令、从车辆的 OBD-II CAN 网络读取控制报文、转发当前车辆控制状态报告(如转向角与轮速)。控制命令并不直接操纵执行器,而是作用于部件 ECU 的传感器输入端——转向盘扭矩传感器、油门位置传感器、制动位置传感器。汽油版起亚 Soul 不具备线控制动能力,因此额外加装了一套辅助执行器来实现制动。
这种低层接口的意义在于完整保留原厂安全用例:原车的失效检测、冗余与机械链路都还在,注入的只是一个「驾驶员意图」。这与在总线上伪造一帧转向命令有本质区别——后者绕过了原厂所有校验,前者仍然在原厂设计的信号链里。目前官方支持的车型是 2014 年及以后的起亚 Soul(汽油版与纯电版),但 API 与固件在设计时就为新增车型留出结构:按既有车型头文件的格式新增一个头,并补充一个构建选项即可。
版本矩阵:四件事必须同时对齐
需要跟踪的版本有四件:传感器接口板(油门与转向,版本印在板正面)、车辆控制模块(纯电版制动)、执行器控制板(汽油版制动),以及共用同一版本号的 API 与固件。文档对版本更新给的评价很重——每次有新版本都必须更新,以确保没有使用带有已知安全问题的版本。这不是礼貌性提醒,因为板卡版本与固件版本的配对关系会直接影响启动自检能否通过。
| 板卡 | 板卡版本 | 要求的固件版本 | 说明 |
|---|---|---|---|
| 传感器接口板 | 大于等于 1.0.0 | 大于等于 1.0.0 | 承担油门与转向 |
| 车辆控制模块 | 0.1.0 | 大于等于 1.1.0 | 纯电版制动 |
| 执行器控制板 | 大于等于 1.2.0 | 大于等于 1.0.0 | 汽油版制动 |
| 执行器控制板 | 小于 1.2.0 | 大于等于 1.0.1 | 需额外关闭启动自检 |
最后一行是唯一需要额外操作的组合:较新的执行器控制板利用了新的引脚做启动阶段的附加安全检查,旧板没有这些引脚,因此构建时要显式关闭制动启动测试,否则自检会失败。这是硬件演进与安全检查相互耦合的直接例子。
命令契约:归一化取值范围与 200 毫秒保活
API 只暴露三个发布函数,参数全部归一化,与具体车辆的电压标定解耦:制动与油门位置取 0.0 到 1.0,转向扭矩取负 1.0 到正 1.0,其中负为逆时针、正为顺时针。API 负责把归一化值换算成需要注入的欺骗电压,并内置安全检查以确保不会发出超出车辆预期范围的电压。这个换算层是安全边界的一部分——应用层永远碰不到原始电压。
保活要求是这套接口里最容易被忽略的硬约束:三个发布函数每一个都必须至少每 200 毫秒被调用一次,否则模块会判定与上位机失去通信并自行禁用。它把「上位机死机」和「主动松开控制」统一收敛成同一种失效结果,这正是看门狗该有的行为。反过来说,一个只在上位机有输出时才发命令的控制循环,一旦进入长时间稳定状态就会自己把系统关掉。
| 接口 | 方向与取值 | 约束 |
|---|---|---|
oscc_open / oscc_close |
通道编号 | 建立与终止到固件的 CAN 通道连接 |
oscc_enable / oscc_disable |
无参数 | 禁用时仍可接收报告,但无法发送命令 |
publish_brake_position |
0.0 至 1.0 | 每 200 毫秒至少调用一次 |
publish_throttle_position |
0.0 至 1.0 | 每 200 毫秒至少调用一次 |
publish_steering_torque |
负 1.0 至正 1.0 | 负为逆时针、正为顺时针,同样需 200 毫秒保活 |
subscribe_to_brake_reports 等 |
回调函数 | 制动、转向、油门、故障四类报告各自独立订阅 |
subscribe_to_obd_messages |
回调函数 | 转发非本系统的 CAN 帧,可按 ID 自行解析 |
还有一条实现层面的注意事项:API 会捕获 CAN 帧到达时产生的信号并为其安装处理函数,把有效报文转发给应用。因此应用中对中断敏感的代码段,应在该段执行期间临时阻塞该信号、结束后再解除,否则回调可能在临界区中被触发。
三层安全边界
把这些约束放在一起看,OSCC 的安全设计是分层的,任何一层单独失效都不会立刻导致失控。
| 层级 | 机制 | 失效时的行为 |
|---|---|---|
| 应用层 | oscc_enable 与 oscc_disable 门控 |
未使能时命令发不出去,但报告照常接收 |
| 通信层 | 三个发布函数各需 200 毫秒内再次调用 | 超时即判定通信丢失,模块自行禁用 |
| 信号层 | API 内置电压范围安全检查 | 换算后的欺骗电压被限制在车辆预期范围内 |
| 操作层 | 操作者超控检测,默认全部开启 | 驾驶员施加扭矩即退出,转向灵敏度可调 |
| 硬件层 | 启动自检(新板用新引脚做附加检查) | 自检不通过则不上线 |
| 流程层 | 强制跟随版本更新 | 避免停留在带已知安全问题的版本 |
转向超控为什么默认开启且不建议关闭
所有模块的操作者超控检测默认开启,但文档对转向给出了额外警告:系统激活时试图抓住转向盘可能导致严重伤害,因此推荐的转向超控方式是制动踏板或急停按钮,而不是去扳方向盘。若确实需要关闭,可在构建时传入关闭标志,此时灵敏度由对应车型头文件中的扭矩差阈值控制。
这个阈值是一个典型的双向权衡:调低会让模块对超控更敏感,但在转向齿条机械极限或快速反复变向等高扭矩区域产生误判;调高则误判更少,但人工接管转向变得更困难。文档没有给出默认值之外的推荐值,因为最优解取决于具体的转向系统与应用场景,这正是需要在实车上标定的参数。
构建、刷写与测试命令
固件用 CMake 构建而非 Arduino IDE,目的是绕开 IDE 的限制并支持命令行刷写。前置条件是 Arduino Core 1.8.5 及以上与 CMake 2.8 及以上。构建时通过车型标志选择目标:汽油版 Soul、纯电版 Soul 与 Niro 各有对应标志。生成的构建目标可以整体构建,也可以按模块单独构建,四个模块分别是制动、CAN 网关、转向与油门。
| 环节 | 命令或标志 | 说明 |
|---|---|---|
| 选择车型 | 构建时传入车型标志 | 汽油版 Soul、纯电版 Soul、Niro 三选一 |
| 关闭转向超控 | 追加关闭超控标志 | 默认开启,不建议关闭 |
| 关闭制动启动测试 | 追加关闭启动测试标志 | 仅旧版执行器控制板需要 |
| 发行构建 | 指定构建类型为 Release | 关闭调试符号并开启优化 |
| 单模块构建 | 制动 / 网关 / 转向 / 油门四个目标 | 可只构建所需模块 |
| 刷写 | 单模块上传目标与全量上传目标 | 按字母顺序连接模块可获得稳定端口分配 |
| 单元测试 | 打开测试标志后运行单元测试目标 | 依赖 Cucumber 2.0.0 与 Boost |
| 属性测试 | 打开测试标志后运行属性测试目标 | 依赖 Rust、Cargo 与 libclang |
测试分两类且覆盖角度不同。单元测试以行为描述的方式验证报文处理,例如油门模块的「接收命令」用例会给出传感器读数与两路 DAC 输出值的对照表,四个样例点分别是 0 对应 0、256 对应 1024、512 对应 2048、1024 对应 4096。属性测试则验证控制器库的不变式,一组运行包含积分项、微分项、比例项、反转输入、相同输入产生相同控制、以及清零共七项。两类测试都有分模块的独立运行入口,也有一次性运行全部测试的便捷入口。
许可证分工:硬件与软件不是同一种授权
这一点常被忽略但对集成决策影响很大:硬件源材料——原理图、电路板布局、接线图、数据手册、物理安装文档、三维模型等——采用 CC BY-SA 4.0 授权;固件与软件源则采用 MIT 授权,除非第三方依赖另有声明。也就是说,照着板卡设计做改动后的再分发义务,与修改代码后的义务并不相同。此外文档整体声明按现状分发、不提供任何担保。
| 组成部分 | 许可证 | 主要义务 |
|---|---|---|
| 硬件源材料(原理图、布局、接线图、安装文档、三维模型) | CC BY-SA 4.0 | 署名并以相同方式共享衍生作品 |
| 固件与软件源(源码、头文件、文档、构建脚本) | MIT | 保留版权与许可声明 |
| 第三方依赖 | 以各自声明为准 | 需逐项核对 |
项目还提供商用的整车控制接口方案作为交钥匙选项,覆盖纯电版 Soul 与 Niro 混动,包含集成控制模块、车规级线束与急停开关。对研究者而言,开源版本与商业版本的区别在于支持范围与工程化程度,接口契约本身是一致的。
常见问题
OSCC 是在 CAN 总线上伪造报文吗?
不是。它把控制命令作用于部件 ECU 的传感器输入端——转向盘扭矩传感器、油门位置传感器与制动位置传感器,属于低层接口,因此能在不改动原厂安全用例、不欺骗 CAN 报文、不破解 ADAS 功能的前提下实现全量程控制。纯电版以外的汽油车因不具备线控制动能力,需额外加装辅助执行器。
为什么控制命令必须每 200 毫秒发一次?
这是模块侧判定上位机是否存活的看门狗:三个发布函数中任意一个超过 200 毫秒未被调用,模块就认定与上位机失去通信并自行禁用。它把上位机死机与停止控制统一成同一结果。因此控制循环不能只在数值变化时才发命令,长时间稳态下也必须持续调用。
可以关闭转向超控吗?
可以在构建时传入相应标志关闭,但不建议。文档明确警告系统激活时抓握转向盘可能造成严重伤害,推荐的转向超控方式是制动踏板或急停按钮。若保留开启,灵敏度由车型头文件中的扭矩差阈值控制:调低会增加高扭矩区域的误判,调高会让人工接管更困难。
板卡版本与固件版本不匹配会怎样?
会直接影响启动自检。较新的执行器控制板用新引脚做附加的启动安全检查,旧板没有这些引脚,必须用关闭制动启动测试的构建标志处理。其余组合按官方配对表选择固件版本即可,文档同时强调每次发布新版本都应及时更新,以避开已知安全问题。
硬件设计和软件代码的授权一样吗?
不一样。原理图、电路板布局、接线图、数据手册、物理安装文档与三维模型等硬件源材料采用 CC BY-SA 4.0,衍生作品需署名并以相同方式共享;固件与软件源采用 MIT,只需保留版权与许可声明;第三方依赖以各自声明为准。集成前应按组成部分分别核对义务。
延伸阅读
- PACMod 线控 v3 平台档案:4.0.0 到 14.1.0 演进 —— 商用线控平台的版本与接口对照
- StreetDrone 自动驾驶平台的 CAN 接口:36 报文与 184 信号 —— 另一套自动驾驶改装的接口组织方式
- ADS-DV 2021 的 CAN 架构:7 个 API、8 ms 节流与两套 DBC —— 学生方程式车队的控制接口设计
- UDS 诊断工具为什么不能随手调:只读、会话与写 ECU 的分权设计 —— 写权限的分层思路
- 车型数据库 —— 按车型查 CAN 档案
参考资料
- 项目 01 ——
public-can-dbc-datasets/additional/polysync-oscc/README.md(接口定位、版本矩阵、API 契约与 200 ms 保活、构建与测试命令、许可证分工) - 项目 01 ——
public-can-dbc-datasets/additional/polysync-oscc/LICENSE.md(硬件源材料的 CC BY-SA 4.0 条款与固件软件的 MIT 条款全文,含免责与责任限制)
免责声明
本文所述内容来自公开开源项目的说明文件,不代表车辆制造商的官方数据,文中数字均摘自上述文件,未经独立实车验证。该项目按现状分发、不提供任何担保:硬件源材料(原理图、电路板布局、接线图、数据手册、物理安装文档与三维模型)采用 CC BY-SA 4.0,衍生作品须署名并以相同方式共享;固件与软件源采用 MIT,须保留版权与许可声明;第三方依赖以各自声明为准,集成前应逐项核对。对车辆进行任何控制改装都涉及人身与财产安全,本文仅作技术资料梳理,不得作为上路或载人测试的依据;实际操作须在封闭场地、由具备资质的人员在急停开关与完善的失效处理机制下进行,并以官方资料与实际测量为准。
更新记录
- 2026-10-15 初稿