Ranger EV 改装的 CarState 规格:五个真信号与一个 vEgo 陷阱

作者:

在

结论:把一辆 1986 年 Ranger 的 EV 改装车接进 openpilot,真正能被真实信号填满的 carState 字段只有五个:vEgo、gas、brakePressed、gearShifter、standstill。四轮转速是从 vEgo 复制的假值,全部转向字段为零且必须保持为零,巡航状态留到第三阶段。而在进入纵向控制之前,还有一个前置阻塞项:vEgo 目前只在 3 挡正确。

两条总线与 openpilot 侧的编号映射

改装车上有两条独立的 250 kbit/s 总线:can0 挂 Thunderstruck MCU/BMS 与 TSM2500 充电机(ZEVCCS 相关 0x351/0x355/0x356),can1 是 X1 / Hyper9 电机的 CANopen TPDO 总线(0x181/0x182/0x183/0x184)。在移植中它们被重新编号为 Hyper9 = bus 0、MCU = bus 1。

总线 速率 设备 openpilot bus
can0 250 kbit/s Thunderstruck MCU/BMS + TSM2500 充电机 1
can1 250 kbit/s X1 / Hyper9 电机控制器 0

安装时有一处容易踩的坑:Panda 默认是 500 kbit/s,而这辆车的总线是 250 kbit/s,必须先把 Panda 的总线速率改到 250 k,再确认设备能看到 0x181 与 0x183。

哪些字段有真实来源,哪些是占位

规格表按「必须有」的驱动信号逐行列出来源与变换。判断标准是:能否在 ranger-dashboard/dbc/*.dbc 里找到对应的报文与信号。

carState 字段 来源报文 信号与变换 状态
vEgo / vEgoRaw HYPER9_STATUS 0x181 VEHICLE_SPEED(km/h,有符号 ×0.1),abs(kmh)/3.6 转 m/s 有,但挡位相关
gas HYPER9_MOTOR 0x183 THROTTLE_REQUEST(-100..100 %),clip(req,0,100)/100 有
brakePressed HYPER9_STATUS 0x181 SYSTEM_FLAGS bit5(FLAG_PEDAL_BRAKE) 有
gearShifter HYPER9_MOTOR 0x183 有符号 MOTOR_RPM:大于 20 为 D,小于 -20 为 R,否则 N;FLAG_PARK_BRAKE 置 P 有
standstill 派生 vEgoRaw 小于 0.1 有
wheelSpeeds.fl/fr/rl/rr 无 四轮全部等于 vEgoRaw 伪造,无轮速传感器
steeringAngleDeg / RateDeg / Torque / Pressed 无 全部为 0.0 或 False 缺传感器与 EPS
cruiseState.available / enabled 无 暂为 False 第三阶段
doorOpen / seatbeltUnlatched 无 固定 False 无传感器

转向全为零在只读阶段是可以接受的:openpilot 会照常构建完整的 carState 并完成指纹匹配,只是无法转向。规格里把转向角传感器列为第 1.5 阶段要补的第一件东西——没有它,后续的横向控制就没有反馈闭环。

vEgo 的挡位依赖问题

这是进入纵向控制前必须先修掉的问题。X1 报出的 VEHICLE_SPEED 本身是「电机转速 × 一个固定内部速比」,而这辆车用的是 M5OD-R1 五速手动变速箱,速比每换一挡就变一次,因此单一常数的车速只在一个挡位上正确。2026 年 8 月的实测结果是:3 挡基本正确,4 挡读数约为实际值的一半。只读阶段可以容忍,纵向控制绝对不能——错误的 vEgo 会直接破坏速度控制。

规格给出的修法不是去反推挡位,而是在变速箱下游测速,两个候选来源是 comma 设备自带的 GPS(无需新增布线,巡航准确但低速迟滞)与 M5OD 输出端的尾轴 VSS(真实车速,低速表现好)。拿到挡位无关的真实车速后,显示与日志用的前进挡位反而可以由「电机转速 / 真实车速」对照已知速比四舍五入得到——openpilot 本身只需要 vEgo 与 D/R/N。

EV 专属信号为什么不进 carState

openpilot 的 carState 结构里没有电池包电压、SoC、电机温度这类字段。规格明确把这些信号留在仪表盘与 MQTT 上做带外暴露,移植层不处理。

信号 来源 展示位置
BATTERY_SOC 0x181 或 MCU 0x355 仪表盘 SoC 表
DC_BUS_VOLTAGE / CURRENT、power_kw HYPER9_POWER 0x182 仪表盘功率表
MOTOR_TEMP、INVERTER_TEMP HYPER9_MOTOR 0x183 仪表盘温度
电池包 V/I/温度、单体极值 MCU 0x356 等 仪表盘与 Home Assistant
故障等级与系统标志 0x181 或 MCU 0x35a 仪表盘诊断

如果后续要让这些信号进入 openpilot 内部(比如在 comma 界面显示 SoC,或用电池包故障来门禁接管),规格建议的做法是在 fork 的 carState 上加几个自定义字段,或者走一条旁路的 cereal 消息,而不是硬塞进标准结构。

分阶段现实阶梯与安全前提

这份规格把整件事拆成了三级阶梯,并标出了明确的硬件阻塞点。第一阶段只读是这套脚手架当前所处的状态。

阶段 目标 状态 阻塞项
1 只读 openpilot 通过 CAN 看到车辆 本脚手架 无
2 纵向 通过 Hyper9 扭矩/动能回收控速 未开始 safety_ranger.h、vEgo 挡位无关化
3 横向 转向 被阻塞 车辆无 EPS,需加装转向执行器

第二阶段的执行路径已经写明:纵向加速度映射到发给 X1 的 MOTOR_TORQUE 命令 RPDO;制动权先由负扭矩/动能回收承担,且需要先实测动能回收的减速度上限。但在这些生效前,必须有 panda 固件里的 safety_ranger.h 钩子逐报文施加限制。第一阶段跑的是 SILENT 安全模式——记录一切,不发送任何东西。

常见问题

为什么四个轮速信号要伪造?

因为这辆车没有独立轮速传感器,规格只能把四个 wheelSpeeds 全部赋成 vEgoRaw。对只读阶段和纵向控制够用,但横向调校最终需要真实的逐轮转速,属于后续要补的硬件。

vEgo 在 4 挡读数约为实际值的一半,怎么处理?

不要在总线里反推挡位,改在变速箱下游测速。两个方案:直接用 comma 设备自带的 GPS(无需新增布线,巡航速度准确,低速迟滞),或在 M5OD 输出端装尾轴 VSS(真实车速,低速表现好)。把 carstate.py 的 vEgo 来源从 VEHICLE_SPEED 换成其中之一。

没有 EPS 是不是就完全做不了 openpilot?

不是。openpilot 的两件事是转向和控速,这辆车缺的是转向执行器,因此横向被阻塞,但纵向控制不依赖 EPS,仍可在加装转向执行器之前实现。完全脱手的完整功能才需要 EPS 改装这个独立硬件项目。

EV 的 SoC 和电池温度为什么不在 carState 里?

因为 openpilot 的 carState 结构本身不建模电池包电压、SoC 与电机温度字段。这些信号保留在仪表盘与 MQTT 上带外暴露。若确实需要在 openpilot 内部使用,规格建议加自定义字段或走旁路 cereal 消息。

接上 Panda 后第一件事要改什么?

改总线速率。Panda 默认 500 kbit/s,而这辆改装车的两条总线都是 250 kbit/s,必须先把 Panda 设为 250 k,再确认设备能看到 0x181 与 0x183,之后才进入版本对齐与指纹匹配步骤。

延伸阅读

参考资料

  • 项目 03 —— public-can-dbc-datasets/additional/wstewarttennes-ranger-ev-conversion/openpilot-port/spec/ranger_carstate_spec.md(总线映射、逐字段来源与变换、vEgo 挡位依赖与带外 EV 信号清单)
  • 项目 03 —— public-can-dbc-datasets/additional/wstewarttennes-ranger-ev-conversion/openpilot-port/README.md(三阶段阶梯、文件职责、版本对齐步骤与安装流程)
  • 项目 03 —— public-can-dbc-datasets/additional/wstewarttennes-ranger-ev-conversion/README.md(仓库布局与仪表盘仓库关系)

免责声明

本文内容来自公开仓库中的自定义移植规格,描述的对象是一辆特定年份的改装车辆,其总线构成、控制器型号与变速箱配置均不具备通用性。文中数字(报文 ID、缩放系数、挡位相关性)来自该仓库的实测记录,未经独立复现。任何涉及车辆控制的改动都应以实际测量与合规验证为准,本文不构成改装或上路操作指引。

更新记录

  • 2026-10-14 初稿

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注