标签: 赛道驾驶

  • 马自达 RX-8 的 CAN 笔记:6 个 ID、9 个信号与两处未定系数

    结论:这是一份为赛道遥测整理的马自达 RX-8 CAN 笔记,用 6 个报文 ID 承载 9 个信号:0x201 同时给出油门、转速与车速,0x212 给出刹车与手刹两个开关量,0x231、0x420、0x250、0x81 各给出一个信号。它的价值在于把字节偏移、长度、位掩码与换算公式写到了可直接落地的粒度;边界也同样清楚——只在 2006 年款(series 1)手动挡带 DSC 的一台车上用 OBDLink MX+ 与 RaceChrono v7.5.3 验证过,转速除数还有 4.0 与 3.85 两套并存,刹车压力至今只有开关量、没有连续量。

    九个信号的字段边界

    先要澄清一个术语:笔记里的「PID」指的是 CAN 报文 ID,不是 OBD-II 服务 01 下的参数标识符。这决定了取数方式是被动监听总线,而不是主动请求应答。多字节值统一按大端解析,这是后面所有公式的前提。

    信号 报文 ID 字节偏移 长度 位掩码 类型 换算公式
    油门开度 0x201 6 1 无 UINT8 百分比 = 值 / 2(原始值范围 0 到 200)
    引擎转速 0x201 0 2 无 UINT16 rpm = 值 / 4.0
    车速 0x201 4 2 无 UINT16 km/h =(值 – 10000)/ 100.0
    刹车踏板 0x212 5 1 0x08 Bool 踩下 = 值
    手刹 0x212 4 1 0x40 Bool 拉起 = 值
    空挡 0x231 0 1 0x80 Bool 空挡 = 取反后的值
    冷却液温度 0x420 0 1 无 UINT8 摄氏度 = 值 – 40
    进气温度 0x250 3 1 无 UINT8 摄氏度 = 值 – 40
    转向角 0x81 2 2 无 INT16 度 = 值(有符号)

    九个信号里 0x201 一条报文就占了三个,且彼此不重叠:转速在偏移 0 占 2 字节,车速在偏移 4 占 2 字节,油门在偏移 6 占 1 字节。这种紧凑布局意味着解析时一次取 8 字节即可解出三个量,但也意味着任何一个偏移写错都会静默地取到相邻信号。

    位掩码到 RaceChrono 位号的换算

    笔记给字节偏移与位掩码,RaceChrono 公式里用的却是 0 到 63 的位号,两者需要对账。RaceChrono 的约定是从最高位起算:位 0 是最高位,位 57 的权值为 64。据此可以推出换算关系——位号等于字节偏移乘以 8,再加上掩码在该字节内从高位往低数的序号。

    信号 字节偏移 位掩码 掩码在字节内的高位序号 RaceChrono 位号 RaceChrono 公式
    空挡 0 0x80 0 0 (1 – BitsToUInt(raw, 0, 1)) * 100
    手刹 4 0x40 1 33 BitsToUInt(raw, 33, 1) * 100
    刹车踏板 5 0x08 4 44 BitsToUInt(raw, 44, 1) * 100

    三个位号都能对上:0 = 0×8+0,33 = 4×8+1,44 = 5×8+4。三个开关量都乘 100,是为了把布尔量塞进 RaceChrono 的百分比通道。空挡那一项额外做了取反:原始位在空挡或踩离合时为 0,其余情况为 1。

    两处未定系数与一处待办

    笔记里真正需要用户在落地时做判断的,是笔记公式与 RaceChrono 公式不一致的地方。这些差异大多有明确原因(单位制不同),唯独转速那一处被原作者标记为「需要调查」。

    信号 笔记公式 RaceChrono 公式 差异原因 是否待定
    引擎转速 值 / 4.0 值 / 3.85 4.0 是标准公式,3.85 更贴合仪表显示 是,原作者标注需调查
    车速 (值 – 10000)/ 100.0 得 km/h (值 – 10000)/ 360 RaceChrono 需要 m/s,故除以 360 而非 100 否
    冷却液温度 值 – 40 得摄氏度 值 – 40 RaceChrono 自动转换为华氏度 否
    进气温度 值 – 40 得摄氏度 值 – 40 RaceChrono 自动转换为华氏度 否
    转向角 值(有符号) 值 × -1 RaceChrono 需取反才能正确显示转向动画 否
    刹车压力 无 无 笔记 TODO:希望以压力量替代开关量 是,尚未找到

    转速除数为什么不能随手选一个

    4.0 与 3.85 在 7000 rpm 处的差值约 273 rpm,足以让换挡提示与圈速分析出现系统性偏差。笔记明确写到除以 4 是标准公式,但 3.85 看起来更接近车辆仪表显示的值,而作者并未判定哪个正确。落地时的合理做法是用仪表或独立转速计做一次标定,而不是沿用其中任意一个。

    车速公式里的 10000 偏移

    车速要先把原始值减掉 10000 再除以 100,说明这条通道带了一个 10000 的零点偏移,而不是从 0 计起。这样的设计让原始值具备表达负速度(倒车)的余量,但也意味着如果直接把该 uint16 当无符号数解释而忘记减偏移,会得到约 100 km/h 的固定假值。落地时应先确认目标工具是按有符号还是无符号取值,并在静态停车状态下先读一次原始值做零点校验。

    验证环境与适用边界

    这套代码带的免责声明写得很直接:仅供实验用途,使用风险自负。它的验证矩阵也很窄,只有一台车、一个适配器、一个手机型号与一个软件版本。

    项目 取值 对适用性的影响
    车辆 Mazda RX-8 2006(series 1),手动变速箱,带 DSC 自动挡或其他年款未验证
    适配器 OBDLink MX+ 蓝牙扫描仪 换适配器后需重新确认透传是否完整
    手机 Huawei P30 Pro,Android 10 蓝牙协议栈差异可能影响采样连续性
    软件 RaceChrono v7.5.3,需开启实验功能 7.5.3 起必须启用实验特性才能生效
    字节序 多字节值为大端 按小端解析会得到完全错误的速度与转速
    位编号 从最高位起算,范围 0 到 63,位 57 的权值为 64 与常见 LSB 起算工具不通用

    常见问题

    这里的 PID 是 OBD-II 的 PID 吗?

    不是。笔记里的 PID 指 CAN 报文 ID,例如 0x201、0x212、0x231、0x420、0x250、0x81,取数方式是被动监听总线而不是主动请求应答。这与 OBD-II 服务 01 下的参数标识符是两套体系,混用会得到完全不同的字节布局。

    这些报文适用于所有 RX-8 年款吗?

    不能这样假定。笔记声明只在 Mazda RX-8 2006(series 1)、手动变速箱、带 DSC 这一台车上验证成功,并明确为实验用途。自动挡、其他年款或不同市场版本的报文布局可能不同。

    引擎转速为什么会有 4.0 和 3.85 两套除数?

    笔记写到除以 4 是标准公式,但 3.85 看起来更接近车辆仪表显示的值,作者自己也标注「不知道哪个是对的,需要调查」。两者在高转速区的差值可达数百 rpm,落地前应用仪表或独立转速计做一次标定。

    RaceChrono 里的位号 44、33、0 是怎么算出来的?

    由字节偏移与位掩码换算而来。RaceChrono 从最高位起算,位号等于字节偏移乘 8 再加掩码在字节内从高位往低数的序号:刹车 0x08 在偏移 5,得 5×8+4 = 44;手刹 0x40 在偏移 4,得 4×8+1 = 33;空挡 0x80 在偏移 0,得 0×8+0 = 0。

    刹车压力能从这些报文里取到吗?

    暂时不能。笔记只解出了 0x212 里的刹车踏板开关量与手刹开关量,并把「找到刹车压力代替开关信号」列为 TODO。也就是说目前只有布尔状态,没有连续的制动压力通道。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/topolittle-rx8-can-notes/README.md(9 个信号的报文 ID、字节偏移、位掩码、换算公式与验证设备清单)

    免责声明

    本文所述的 CAN 报文解析均来自公开仓库的实验性笔记,原作者明确声明仅供实验用途、使用风险自负,且与文中提到的任何公司无关联或赞助关系。文中数字未经独立实车验证,不同年款、市场与 ECU 版本可能存在差异。涉及安全相关用途时请仅作参考,并以实际测量与官方资料为准。

    更新记录

    • 2026-10-14 初稿

  • RiceTimer:GNSS UTC 统一时钟,DBC 解析仍在计划里

    结论:RiceTimer 是一台把 GNSS、IMU 与 CAN 三路原始数据同步写进 MicroSD 的记录器,但它今天并不解析信号——data/dbc/ 目录下目前只有一份版权声明,说明数据部分派生自 MIT 授权的 OpenDBC;真正的 DBC-based CAN bus parsing 明确写在 Planned Future Work 里,并且作者特别注明它不会影响日志输出,日志永远是原始 CAN 报文。想拿发动机转速和挡位,得自己离线过一遍 DBC。

    它记录什么:三路数据共用一个 GNSS 时钟

    这个项目最扎实的设计决定是把时间基准统一了:所有消息都按 GNSS 的 UTC 时钟打时间戳,而不是按各自 MCU 的上电时间。这决定了后面能不能把 IMU 的姿态和 CAN 的轮速对齐到同一条时间轴上。

    数据源 器件 时间戳方式 注意点
    GNSS uBlox NEO 系列模块 + 外接有源天线 NMEA 语句本身带 UTC 必须接 SMA 天线,板上没有内置 GNSS 天线
    IMU ST LSM6 系列(LGA14)六轴加速度 + 陀螺 硬件在 data available 时刻打时间戳 SPI 总线占用 IOMux 快速引脚,不可随意改引脚
    CAN 一路 3.3 V 非隔离收发器 固件在报文交付时刻打时间戳 兼容 5 V 网络;支持 11/29 位帧,不支持 FD

    三者的时间戳来源不同——IMU 是硬件级的、CAN 是固件级的——这意味着它们相对于 GNSS 时钟都存在各自的偏移。做融合之前,这个偏移必须测出来并补偿,否则 IMU 与 CAN 的数据在时间上会有系统性的错位。

    日志格式也刻意朴素:每行一个数据点,且每一条有效 NMEA 语句都被逐字写入。这样做的代价是文件体积偏大,收益是后期可以用任何外部工具重放,不必依赖设备自身的解析器。示例日志 sample-log.txt 里 GPS 坐标做了部分脱敏处理,因此那份文件的 NMEA 校验和是对不上的——这不是日志坏了。

    硬件接口契约

    接车之前值得把引脚定义核对一遍,因为它是裸板电源与总线共口的设计,接错就是烧片子。

    接口 引脚 电气取值 注意点
    USB Micro-B 供电 + 串口调试烧录 CP210x 桥接 同时也是 ESP32 的编程控制台
    JST SH 5 针(短边) 1 GND、2 VIN、3 Reserved、4 CAN L、5 CAN H VIN 标称 5 至 14 V CAN 与电源共用同一个座,引脚 3 保留未接
    SMA(短边) 外接有源天线 必需 无内置天线,不接则 GNSS 不工作
    JST SH 4 针(长边) 1 GND、2 VCC、3 SDA、4 SCL VCC 标称 3.3 V 兼容 QWIIC 与 Stemma QT,现用于 SH1107 的 128×64 OLED
    Micro SD 4 位 SD 总线 Micro-SDHC 占用 IOMux 快速引脚;重流量下建议低延迟卡

    SD 卡这条容易被忽略。CAN 数据不多时任何 Micro-SDHC 都能用,但报文流量较大时建议换低延迟卡,以避免潜在丢数。市面上通常标注为 Industrial、Endurance 或「行车记录仪专用」的就是这一类。换句话说,丢帧的根因未必在 CAN 侧,可能在文件系统的写入延迟上——而这个问题在 CAN 侧是查不出异常的。

    DBC 目录现在的实际内容

    往下钻一层看 data/dbc/,会发现这个目录目前只有一份 README,全文只有一个信息:这里的数据部分派生自 OpenDBC(MIT 授权),详见 LICENSE。目录里没有可加载的 .dbc 文件。

    这与 README 里的计划清单完全对应——DBC-based CAN bus parsing 被列在 Planned Future Work,描述是「把 DBC 加载到设备上,从而提取并利用实时信号,例如发动机转速、油液温度、车辆自身的 IMU、轮速等」。而紧接着那句话才是关键:这不会影响日志输出,日志始终包含原始 CAN 报文。

    这条约束很值得照抄。它把设备切成两条正交的路径:实时显示在未来可以走 DBC 解析,落盘数据则永远保持原始。收益是后处理链路不会因为解析定义的改动而失效——原始帧始终可以重新解码;代价是每次会话都会多写一份原始报文,占用存储。对一个以复盘为目标的项目来说,这是一笔划算的买卖。

    计划清单里剩下的四件事

    README 明确列出了待办,读它能判断这台设备的成熟度:一是稳定日志格式与后处理流程(当前日志格式尚未正式规定,这对依赖它做自动分析的人是硬约束);二是传感器融合与标定,需要对 IMU、车辆、GNSS 天线之间的刚性变换做标定;三是预测圈速,当前 OLED 只显示少量实时诊断信息;四是启用 Wi-Fi 与 BLE——选 ESP32 就是为了留这一步。

    还有一条对项目形态影响很大:README 明确写「本项目目前不接受贡献」。这解释了为什么它是一个清晰的单人项目而不是一个社区协议库——想要更多的信号定义,只能等作者更新或自己在离线侧补全。

    作为参照,作者已经用早期原型硬件在 Thunderhill East 赛道的实数据跑通过后处理,转换成空格分隔表并交给 CircuitTools 分析。也就是说「赛道实车采集的数据转成空格分隔表,再交给 CircuitTools 分析」这条主链路是通的,缺的只是设备端的 DBC 解析那一环。

    常见问题

    RiceTimer 现在能直接在设备上解出发动机转速吗?

    不能。DBC-based CAN bus parsing 仍列在 Planned Future Work 中,data/dbc/ 目录目前只有一份说明版权与 OpenDBC 派生关系的 README,没有可加载的 dbc 文件。要得到转速、水温、轮速等信号,需要在拿到原始日志后自行用外部工具按 DBC 解码。

    这台设备支持 CAN FD 吗?

    不支持。它只有一路 3.3 V 非隔离 CAN 收发器通道,兼容 5 V 网络,支持 11 位与 29 位帧,文档明确指出 FD 不支持。接 FD 总线不会得到正确报文。

    为什么建议换低延迟的 SD 卡?

    因为写入延迟会在 CAN 流量大时造成丢数。作者说明 CAN 数据不多时任何 Micro-SDHC 都能用,但报文流量较大时应换低延迟卡,通常是标注 Industrial、Endurance 或行车记录仪专用的型号。这类丢帧在 CAN 侧查不到异常。

    示例日志里的 NMEA 校验和为什么对不上?

    因为示例日志的 GPS 坐标做了部分脱敏处理。README 明确说明这一操作会导致校验和不匹配,这是隐私保护的结果,不代表日志损坏或记录链路有问题。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/hpde-rice-timer/README.md(定位与原名 ShiftWatch、三种数据源与器件型号、GNSS UTC 统一时间戳、CAN 收发器电气与 FD 不支持、两个 JST SH 接口的引脚定义、SD 卡低延迟建议、示例日志脱敏说明、Planned Future Work 六项、暂不接受贡献)
    • 项目 01 —— public-can-dbc-datasets/additional/hpde-rice-timer/data/dbc/README.md(该目录数据部分派生自 MIT 授权的 OpenDBC,详见 LICENSE)

    免责声明

    本文所述硬件规格、引脚定义与项目状态均来自公开开源仓库的说明文件,属社区项目产物,未经实车独立验证,也不代表任何制造商的官方数据。日志格式尚未正式规格化,接口定义可能随硬件版本变化。涉及车载供电与总线接入的操作请以实际测量与官方资料为准。

    更新记录

    • 2026-10-14 初稿

  • Mazda MX-5 NC 的 CAN 笔记:10 个 ID 与 RaceChrono 公式

    结论:Mazda MX-5 NC(2005–2015)的公开 CAN 笔记给出 10 个可用 ID 与配套 RaceChrono 公式,但覆盖面有硬边界:0x081 转向角、0x085 制动压力、0x090 疑似加速度三帧只在带 DSC 模块的车型(2007 年起)上出现;10 秒怠速直方图里 20 个 ID 中只有 8 个达到 100 Hz,真正被写清解码的不超过 10 个。

    先分清哪些 ID 依赖 DSC

    这份笔记面向第三代 MX-5(NC / NCFL / NCFLFL,即 MK3 / MK3.5 / MK3.75),按 CAN ID 组织,每个 ID 给出字节含义表与 RaceChrono 通道公式。使用时第一个判断不是「这个 ID 有没有」,而是「这辆车有没有 DSC 模块」——转向角、制动压力、疑似加速度三组信号都只在配备 DSC 的车型上存在,也就是 2007 年之后的车。

    CAN ID 更新频率 关键字节 公式 前提条件
    0x201 100 Hz 0–1 转速、4–5 车速、6 油门、7 恒为 FF 转速 = bytestouint(raw,0,2)/4.00;车速 = ((bytestoint(raw,4,2)/100.00)−100)/3.6;油门 = bytestoint(raw,6,1)*2.00 全系
    0x4B0 100 Hz 0–1 左前、2–3 右前、4–5 左后、6–7 右后 四角统一为 ((bytestoint(raw,N,2)/100.00)−100)/3.6 全系,独立承担轮速
    0x200 100 Hz 6 制动开关、7 节气门位置 制动 = data[6] 与 0x1 按位与;节气门 = bytestouint(raw,7,1)*100/255.00 全系;byte7 与 0x215 byte6 同源
    0x215 100 Hz 6 节气门位置,其余多为故障码 bytestouint(raw,6,1)*100/255.00 全系;byte0 与 byte2 互为镜像,byte1 与 byte3 互为镜像
    0x231 40 Hz 1 的 bit3 空挡、bit1 离合 空挡 = data[1] 与 0x4 按位与;离合 = data[1] 与 0x2 按位与 手动挡其余字节恒为 FF 或 00
    0x240 10 Hz 0 计算负载、1 水温、4 进气温度 水温 = bytestouint(raw,1,1)−40;进气 = bytestouint(raw,4,1)−40 全系;水温与 0x420 byte0 同源
    0x081 100 Hz 2–3 有符号转向角,仅 4 字节 bytesToInt(raw,2,2),正值向右 需 DSC 模块,2007 年起
    0x085 100 Hz 0–1 制动压力、2 的 bit0 制动开关 压力 = (3.4518689053*bytesToInt(raw,0,2)−327.27)/1000.00,单位 kPa 需 DSC;系数源自 miata.net 用户数据,作者标注可能错误

    表里最该被记住的不是公式本身,而是最后一列。0x081 与 0x085 一旦用在 2006 年及以前的车上,会表现为「完全没有该 ID」,而不是数值为零。

    车速公式里那两个魔数的来历

    0x201 与 0x4B0 共用同一套换算:原始值以 km/h 为单位但带 100 km/h 偏移,因此先除以 100 再减 100;末尾的 3.6 是把 km/h 换成 m/s,因为 RaceChrono 内部以 m/s 计算,之后由软件按用户选择的单位再乘回去。自己写解析器时若直接用 m/s 之外的单位,就要把这一级换算还原。

    油门通道的公式是 bytestoint(raw,6,1)*2.00,对应 0.5% 的步进;0x201 的 byte2 与 byte3 虽跟随转速变化,但笔记标注它疑似带 0x7fff 偏移且与发动机扭矩无关,属未完成解析项。

    10 秒直方图:用帧数反推频率

    笔记给了一张停车场怠速状态下 10 秒窗口的报文计数直方图,共 20 个 ID。把帧数除以 10 就得到各 ID 的实际频率,这张表可以直接用来判断采样与总线负载。

    10 秒帧数 换算频率 CAN ID(十六进制) 说明
    1000 100 Hz 081、085、090、200、201、211、215、4B0 含全部已解析的动态信号
    500 50 Hz 204、21A 未解析
    400 40 Hz 231、4EC 231 为变速箱,与笔记标注的 40 Hz 一致
    100 10 Hz 212、240、39A、420、430、4FF 240 为发动机数据,与标注的 10 Hz 一致
    10 1 Hz 4F0、4F1 低频,疑似诊断或状态帧

    这张表的实用价值在于排错:如果某台设备上 0x4B0 的计数明显低于 1000,先查总线负载与过滤规则,再去怀疑解码;如果它和 0x240 一起掉,问题多半在总线本身而非解析。

    恒值与未完成项要单独标记

    笔记里有几类条目不能当信号使用。0x211 全为 0xFF;0x212 恒为 80 00 20 40 00 00 00 00,原文用问号表示这只是观察结果;0x090 整帧标记为 WIP,只推测与加速度有关;0x430 的 byte2–7 恒为 0x00,且笔记提示 0x430 在 ND 上才是油量。把它们写进解析配置只会产生恒零通道。

    0x240 这一帧同样混着可用与不可用项:byte0 的计算负载公式为 100*(bytestouint(raw,0,1)/255.00,笔记说明作者在 RaceChrono 的通道列表里找不到对应的 Engine Load 通道;byte3 的节气门位置被标注为绝对开度(计入怠速开度),但作者实测怠速值偏高(约 11%),提示缩放仍需调整;byte2 疑似点火提前角,未给出公式。

    常见问题

    这份 MX-5 NC 的 CAN 笔记覆盖哪些年款?

    笔记标题写明覆盖 2005–2015 的第三代车型(NC / NCFL / NCFLFL,即 MK3 / MK3.5 / MK3.75)。但转向角 0x081、制动压力 0x085 与疑似加速度 0x090 只在带 DSC 模块的车型上存在,也就是 2007 年起;更早的车上这些 ID 根本不会出现。

    0x085 的制动压力公式能直接用吗?

    需谨慎。笔记给出的公式是 (3.4518689053*bytesToInt(raw,0,2)−327.27)/1000.00,单位为 kPa,但作者明确标注系数来自 miata.net 用户数据、可能有误。作为替代,笔记还给出百分比算法 min(0.2*(bytesToInt(raw,0,2)−102),100),未踩时基准值为 102,松开后短暂降到 99 会出现轻微负值。

    车速公式里为什么既要减 100 又要除以 3.6?

    两级换算是两件事。原始车速以 km/h 为单位但带 100 km/h 偏移,所以先除以 100 再减 100 还原真实 km/h;再除以 3.6 是换成 m/s,因为 RaceChrono 内部以 m/s 计算,最终按用户选择的单位自动乘回。自建解析器时若不需要 m/s,应去掉这一级。

    离合与空挡信号在自动挡车上也能用吗?

    不能直接套用。0x231 的 byte1 中 bit3 表示空挡、bit1 表示离合,笔记说明该字节的解读基于手动挡车:手动挡时 byte0、byte2、byte3 恒为 FF,byte4–byte7 恒为 00。笔记也提到该帧对自动挡车可能有更多有意义的数据,但并未给出自动挡下的解析。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/hatsunearu-mx5-nc-notes/mazda_mx5_nc.md(10 个 CAN ID 的字节表、RaceChrono 公式、更新频率与 10 秒怠速直方图)

    免责声明

    本文内容整理自公开开源笔记,其中公式、系数与频率均为原作者基于自车观察给出的结果,部分条目被作者本人标注为未完成或可能错误,未经独立实车验证。不同年款、市场、ECU 版本与是否带 DSC 模块均会导致差异,请以实际抓包与官方资料为准。

    更新记录

    • 2026-10-14 初稿

  • 干净室插件架构实践:把遥测工作流拆成可替换插件

    结论:要做干净室、插件化的遥测工具重构,落点是把「宿主」压缩到最小、把能力全部下沉到可独立加载与卸载的插件。本文的取舍可以概括为三条:宿主只负责插件生命周期、工作区、命令路由与能力发现;所有数据模型与契约位于中立的 Abstractions 层,不依赖任何 UI 框架;单个插件加载失败只进入失败清单,不阻止无依赖插件运行。清单的 schemaVersion 当前为 1,插件 ID 使用反向域名风格,通道名使用稳定点分命名(如 speed.kmh)。

    七条设计原则

    架构文档给出的七条原则,决定了后续所有工程取舍:

    原则 含义
    宿主最小化 宿主只负责插件生命周期、工作区、命令路由和能力发现
    数据中立 会话、采样、圈、分段、视频引用与弯角定义位于 Abstractions,不依赖 UI 或第三方库
    多实现并存 同一契约可注册多个实现,例如 CSV、GeoJSON 与报告都实现同一个导出契约
    依赖显式 依赖写在 plugin.json,加载器做拓扑排序并检测循环
    故障隔离 单个插件加载失败进入失败清单,不阻止无依赖插件运行
    UI 是适配器 CLI、桌面与 Web 都是宿主外壳,不能持有核心业务算法
    安全默认值 更新源只接受 HTTPS;插件加载目录必须由宿主明确指定

    第四条与第五条合起来,是插件架构能否长期维护的关键:依赖必须显式声明,才能在加载阶段做拓扑排序、定位失败插件并隔离它。

    插件生命周期与加载隔离

    加载流程是固定的一段顺序,可按下面步骤核对:

    1. 发现 plugin.json;
    2. 验证 schemaVersion;
    3. 定位 entryAssembly;
    4. 依赖拓扑排序;
    5. 创建独立 AssemblyLoadContext;
    6. 实例化插件接口;
    7. 注册服务与命令;
    8. 启动(StartAsync);
    9. 正常运行;
    10. 停止(StopAsync);
    11. 卸载 AssemblyLoadContext。

    这里有一条容易踩坑的规则:共享的 Abstractions 程序集始终由默认加载上下文提供,插件加载上下文不会加载自己的契约副本。这么做是为了避免 CLR 类型身份不一致——如果每个插件各自加载一份契约,同一接口在不同上下文里会被当成不同类型,注册与调用都会失败。

    能力契约与功能拆分映射

    宿主通过一组能力契约暴露功能,插件只实现自己关心的契约:

    契约 用途
    数据导入契约 文件到遥测会话
    会话处理契约 导入后的派生通道与标准化处理
    数据导出契约 会话到外部文件
    弯角库服务 赛道弯角库读取
    圈速服务 门线、圈速、分段
    视频引用服务 视频关联和路径解析
    图表序列服务 图表序列和抽样
    地图路线服务 地图轨迹和简化
    洞察分析器 弯角分析
    配置存储 配置持久化
    更新源服务 安全更新元数据
    赛道库服务 赛道、门线和位置查询
    文件传输服务 会话文件分组和复制
    插件命令 可脚本化的用户命令

    原软件里集中的「服务」被拆成独立边界。功能域的映射关系如下:

    原功能域 对应插件
    文件读写与数据服务 数据导入插件
    弯角数据与赛道路径 弯角插件
    起终点数据库 赛道数据库插件
    开放赛道几何 开放赛道数据插件
    数学通道 数学插件
    圈与分段 圈速插件
    视频服务 视频插件(播放后端作为后续适配器)
    图表、地图、导出、报告、洞察 各自独立的图表 / 地图 / 导出 / 报告 / 洞察插件
    设置、自动更新、文件传输 设置 / 更新 / 文件传输插件

    桌面层延续同样原则:外壳只提供停靠区、菜单、状态栏与工作区选择;图表插件贡献图表面板、不直接引用导入插件;地图插件只读标准位置通道;视频插件可接入可替换的播放后端;PDF、打印、HTML 报告分别实现同一个报告渲染契约;在线地图、遥测上传与 AI 建议必须是显式安装、可禁用的网络插件。

    干净室边界:能用什么、不能带进什么

    干净室开发的核心是划一条清晰的输入边界,只允许来自可观察行为与公开资料的证据:

    可以使用 不进入新工程
    用户可观察的输入、输出和交互行为 原程序的反编译源码或轻微改名的等价复制
    公开文档、公开文件格式和独立测试数据 保护区域中恢复出的专有方法体
    为互操作性而确认的字段、单位和二进制布局 厂商图标、图片、文案、赛道数据库等受保护资源
    自行设计的数据模型、算法、插件接口和用户界面 厂商 DLL、许可组件、私有密钥或未授权在线服务
    — 绕过许可、签名验证或访问控制的逻辑

    工程上还有几条落地措施:源码、插件与测试目录不引用反编译目录;测试用的采集文件为人工合成数据;文件格式解析器只实现互操作,测试时从用户本机安装读取、不把数据库复制进仓库;可分发的赛道与弯角数据包只从明确许可的开放数据源生成,并在每个快照中保留来源、查询、署名和文件哈希;更新插件拒绝 HTTP 源且不自动下载或安装包。

    新增一个插件的五步

    1. 新建一个引用 Abstractions 的目标框架类库;
    2. 实现插件接口;
    3. 通过注册器注册服务或命令;
    4. 在项目根目录放置 plugin.json,声明入口程序集、入口类型、依赖和能力;
    5. 把项目加入解决方案并构建,宿主会从输出目录自动定位程序集。

    兼容性规则同时要求:插件不得引用反编译目录或厂商二进制;破坏性契约变化要发布新的 Abstractions 主版本。把这两条与前面的「依赖显式」放在一起看,就能理解为什么插件清单必须声明入口程序集、入口类型、依赖与能力——加载器据此排序、隔离并在失败时给出清单,而不是静默跳过。

    常见问题

    单个插件加载失败会不会拖垮整个工具?

    不会。架构原则要求故障隔离:单个插件加载失败进入失败清单,不阻止无依赖的插件运行。前提是依赖显式写在清单里,加载器才能做拓扑排序并隔离失败项。

    为什么每个插件各自加载一份契约会出问题?

    会造成 CLR 类型身份不一致:同一接口在不同加载上下文里被当成不同类型,注册与调用都会失败。因此共享的契约程序集始终由默认加载上下文提供,插件加载上下文不加载自己的契约副本。

    哪些数据可以来自原软件?

    只有用户可观察的输入、输出与交互行为,以及公开文档、公开文件格式和独立测试数据。反编译源码、保护区域恢复的专有方法体、厂商图标文案、厂商二进制与私有密钥都不进入新工程。

    网络、在线地图和 AI 能力怎么处理?

    它们必须是显式安装、可禁用的独立网络插件。更新源只接受 HTTPS,且不自动下载或安装包;这类能力应保持默认关闭、可审计。

    延伸阅读

    参考资料

    • 项目 03 —— nixiang-tracklab/PLUGIN_ARCHITECTURE.md(取用七条设计原则、插件生命周期、能力契约、功能拆分映射与兼容性规则)。
    • 项目 03 —— nixiang-tracklab/CLEAN_ROOM.md(取用干净室的可使用 / 不进入边界与工程措施)。
    • 项目 03 —— nixiang-tracklab/README.md(取用当前插件状态、构建运行方式与新增插件五步)。

    说明:本文为对整洁室重构文档与固定源码快照的静态结构整理,未运行完整测试套件、未连接任何厂商数据库或车辆、未验证各插件在实际数据上的输出。文中所有原则、契约与步骤均出自源文档,标注为未验证的结论保留其原有边界。

    更新记录

    首次发布 2026-10-11 最近核对:2026-10-11

  • 方程式赛车总线档案:53 条报文与多设备 DBC 合并

    结论:这份档案的对象是一支大学生方程式车队的赛车总线,不是量产车:源文档以 11 位标准帧、8 字节为主的 DBC 文本,逐条给出 ECU、变速箱控制、IMU、电源分配、车轮与制动传感器等设备的报文定义。它的数据特征是「多设备 DBC 合并成一份 master」——config.dbc 是自动生成的整车总览(当前 53 条报文),单独设备定义在 devices/ 下,两者按设计存在重叠,不可当作彼此独立的车辆覆盖。源文档未提供比特率、日志数或采集跨度,也未独立验证各供应商组件定义的年份与适用性,因此下述结论只限这份 DBC 快照本身。

    车辆与适用范围

    源文档是一份随车项目公开的 DBC 配置仓库:根目录一份 config.dbc 作为「master calibration」,各设备定义放在 devices/,通过合并脚本汇总。它描述的是车队赛车的整车总线,而非某一款市售车型。

    项 内容
    车型 大学生方程式赛车队的赛车及车上组件(源文档未给出具体车号或平台名)
    年款 / 市场版本 源文档未确认;仓库中同时保留历史 2019-2021/config.dbc
    ECU / 改装状态 赛车总线,含 ECU、变速箱控制(GCM)、IMU、电源分配模块(PDM)、GPS/圈速记录(SDM550)、制动红外测温与车轮力传感器等
    采集跨度 源文档未提供(无日志数、事务数或时长记录)
    适用范围 仅覆盖该 DBC 快照内定义的设备与报文;各供应商组件定义的年款适用性未独立验证

    总线与寻址

    源文档以 DBC 文本形式给出全部报文,未包含物理层描述,因此比特率与终端电阻等条件无法从本档案确认。

    项 内容
    物理层 / 比特率 源文档未给出
    寻址方式 逐条报文均标注 Extended: No,即 11 位标准帧
    帧长度 以 8 字节为主;个别报文 2 / 4 / 6 字节(如 SDM550_LapTrigger 为 2 字节、GCM_Queue 与 GCM_Error 为 4 字节)
    CAN FD 源文档未提供任何 CAN FD 报文
    组织方式 按设备分文件定义,再由脚本合并为 config.dbc 总览
    字节序 同一设备内混用:既有 big_endian 也有 little_endian,须逐信号核对

    已解码信号

    下表从源文档的信号定义中抽取最有代表性的条目(发动机、底盘、IMU、圈速与耗材传感器)。位置一列保留源文档的报文 ID 与字节位/长度写法,解码一列保留其原始缩放与单位;「证据」一列注明该条目出自合并总览还是组件定义。

    信号 位置(ID / 起始位·长度) 解码 证据
    nmot 0x300 / bit 7·16 大端有符号,缩放 1,0–20000 rpm;同一信号亦出现在 0x20、0x3fb config.dbc 及组件定义
    ath 0x300 / bit 23·16 大端有符号,缩放 0.1,0–110 % config.dbc
    lambda 0x300 / bit 39·16 大端有符号,缩放 0.001,0–5 config.dbc
    ub(电压) 0x300 / bit 55·16 大端有符号,缩放 0.01,0–25.5 V config.dbc
    tmot / toil / tint / tfuel 0x301 / 各 8 位 缩放均为 1 °C;tmot 为小端,其余大端 config.dbc
    texh 0x301 / bit 32·16 小端无符号,1 °C,0–1250 °C config.dbc
    poil / pfuel 0x302 / 16 位 大端有符号,缩放 0.001,0–10 bar config.dbc
    gear / pbrake_f / pbrake_r 0x20 / 字节 5–7 区 挡位 -1–12;前后制动压力 0–150 bar config.dbc
    speed(变速箱控制) 0x3fb / bit 0·16 小端无符号,缩放 0.01,0–400 km/h config.dbc
    四轮速 + 车速 0x3aa / 各 8 位 vwheel_fl/fr/rl/rr 与 speed,0–400 km/h config.dbc
    Laptrigger_laptime_dls 0x69a / bit 32·32 小端无符号,缩放 0.01,0–500 s config.dbc
    lapctr / outctr 0x69c / 各 8 位 小端无符号,0–255 config.dbc
    IMU_Yaw_Rate 0x174 / bit 0·16 小端,缩放 0.005,单位 deg/s config.dbc
    IMU_X_Accel 0x178 / bit 32·16 小端,缩放 0.0001274,「g」量纲 config.dbc
    Kistler_S350_Vel 0x7fa / bit 23·16 大端无符号,缩放 0.036,0–400 km/h config.dbc

    读取方法与注意事项

    源文档给出了一条明确的工程纪律:不要直接修改 config.dbc。它的定位是「master calibration」,主要供某类商业诊断工具在接入车辆时总览整条总线;正确的做法是编辑 devices/ 下各设备的 DBC——这样更容易批量重命名信号、整体调整某设备的所有 ID。

    合并流程是:在 devices/ 目录下运行合并脚本 python merge_can.py,把各设备定义汇总生成根目录的 config.dbc。源文档并提示 devices/ 下的隐藏文件 .dbc 并非空占位,而是一份有效的五报文制动红外传感器定义。

    解析时须注意两点。第一,同一逻辑量会在多条报文里重复出现(例如 nmot 同时出现在 0x300、0x20、0x3fb),是否一致、以哪条为准,源文档未给出仲裁规则。第二,字节序在同一设备内混用,大端与小端并存,任何解析器都必须逐信号读取其 Byte Order 字段,不能假定全局一致。

    证据等级与边界

    本档案属于「源码/配置静态记录」:全部信号定义都能在 DBC 文本里逐字核对,属于源文档直接证据;但源文档没有任何实车观测,也没有比特率、节拍或日志作为间接支持。文件层面,源文档说明该快照归档了 21 个字节互不相同的 DBC:当前 config.dbc(53 条报文)、历史 2019-2021/config.dbc(23 条报文)以及 devices/ 下 19 个组件文件。

    两点不能外推。第一,当前 master 与组件定义按设计重叠,把两者相加并不能得到更大的车辆覆盖,只能得到同一辆车的重复描述。第二,源文档明确这些是车队赛车与组件定义、不是量产车型 DBC,且各供应商组件定义的具体年份与适用性未独立验证;把某条信号外推到其他年份的其他车上,超出了源文档证据。此外,该仓库快照未声明也未发现许可证,部分组件名指向第三方供应商、原始权利未核实,源文档要求保留为私有离线研究副本、再分发前先确认权利。

    关于安全访问,源文档未提供任何绕过方法,且不建议尝试。

    常见问题

    config.dbc 为什么不能直接改?

    因为它是自动生成的整车总览,单独设备定义在 devices/ 下。直接改 master 会与组件定义脱节;源文档要求改组件 DBC,再用合并脚本生成 master,这样便于批量重命名与整体改 ID。

    把 master 和组件 DBC 的信号加起来,覆盖会不会更大?

    不会。源文档明确当前 master 与组件定义按设计重叠,两者不是独立的车辆覆盖;相加只是重复描述同一辆车,不能当作更全的信号集。

    这些信号能直接套到其他年份的赛车上吗?

    不能。源文档未确认车辆年份,也未独立验证各供应商组件定义的适用性;同一逻辑量还会在多条报文里重复出现且未给仲裁规则。外推超出源文档证据范围。

    为什么同一设备的字节序会混用?

    源文档如实记录:部分信号为 big_endian、部分为 little_endian(例如 0x301 的 tmot 为小端、toil 为大端)。这是源定义的实际状态,解析器必须逐信号读取字节序字段,不能假定全局一致。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/illini-motorsports-can-configuration/UPSTREAM_README.md(本项目车型档案主来源:config.dbc 与 devices/ 的组织方式及全部报文信号定义)。
    • 项目 01 —— public-can-dbc-datasets/additional/illini-motorsports-can-configuration/SOURCE.md(仓库修订、21 个字节互不相同 DBC 的归档说明、许可证与适用性边界)。

    说明:本文整理自第三方开源项目的公开文档,仅代表该文档所记录的单个车辆样本,不代表同型号全系车型。CAN 与诊断操作存在风险,任何实车操作前请自行复核并遵守当地法规。

    更新记录

    首次发布 2026-10-11 最近核对:2026-10-11

  • EdgeDeploy:BLE 与 USB 两条通道怎么把签名包送到 ESP32-S3

    很多 MCU 升级方案把「签名校验」当作终点,实际上它只是中间检查点。真正难的是链路:BLE 有 MTU 限制、USB 会掉线、UART 会丢字节。EdgeDeploy 就是把「包可信」与「包能完整到达」拆成两件事分别解决的那一层。

    三条链路,同一套帧语义

    EdgeDeploy v1 的协议语义与承载链路解耦:无论走 UART、原生 USB 还是 BLE,都使用固定帧头、CRC32、传输 ID、分片 ACK、丢包重试、断点续传、接收端重启恢复、提交结果重放和整包 SHA-256。差别只在分片大小与传输载体:BLE 通道把 512 字节的 EdgeDeploy DATA 拆成 128 字节的 GATT 写片,靠通知流重组、超时、取消与重试补齐。

    链路 分片与载体 已完成的软件/实板验证 仍未验证
    原生 USB 序列包分帧,独立流解码器 + 共享加锁接收器 COM6 从 3,504 字节断点续传并成功 COMMIT;序列 4 包七帧 DATA 完整安装;B 槽 Flash 回读 SHA-256 与发送包一致 掉电恢复、目视显示确认
    BLE(GATT) 512 字节 DATA → 128 字节写片;固定 128 位服务/Request/Response UUID ESP32-S3 加密写入/通知服务、NimBLE Host 复用、浏览器闭环 16/16 场景通过 真实射频与配对不在任务验收内
    UART 按传输 ID 分片 ACK 与重传 框架测试覆盖;外接 UART 实传仍待验证 外接 UART 实传、掉电恢复
    Android APK 系统配对 + 签名 EFP 文件选择 + 分片/重试/断点/提交 + 进度界面 ARM64 构建、3 项协议测试、Lint 0 错误;APK 2,987,883 字节 真机配对、安装、重启健康确认、断线恢复与后台行为

    断点续传和提交结果重放解决的是两个不同的失败

    断点续传解决「写到一半断了」:传输 ID 与序号让接收端知道已经收了多少,重连后从偏移继续,而不是从 0 重来。提交结果重放解决「提交后不知道成功没有」:接收端重启后能回答上一次 COMMIT 的结果,避免主机重复提交或误判失败。

    这两条都服务于同一个下游动作——只有当整包 SHA-256 与签名校验通过,C99 接收器才把完整 EFP 交给 A/B 包管理器,随后才是暂存、试运行、原子激活与 5 秒健康窗口确认。也就是说,传输层只保证「完整送到」,是否运行仍由 96 字节事务状态记录与三态机制决定。

    现在已经验证到什么程度

    微雪 ESP32-S3-Touch-AMOLED-1.75 是目前走得最远的实板:EF-106 记录它已从 ota_1 启动并保留 ota_0 原应用与完整 Flash 备份;EF-106D 的串口观察显示 COM6 复位后 7 个信号、2 条管线、4 个组件就绪,65 秒无复位,UI 任务最低剩余栈 7,576 字节。框架侧自动测试当前共 46 项,本机 44 项通过,另 2 项 Linux POSIX 与 SocketCAN vcan0 集成测试在非 Linux 主机按条件跳过。

    需要说清楚的边界是:以上都是串口可见的软件行为,不等于整机通过。屏幕像素、手指触摸、外部传感器、掉电与长期运行尚未验收;Wasm 后端属于 P3 计划,尚未完成。把「编译通过」或「COM 口有输出」说成「产品可用」,是这类端侧项目最常见的自我误导。

    这对赛道数据链路意味着什么

    赛道日的现实是:设备已经在车上、线束已经走好,此时才发现某个信号解析有误,可用的补救窗口只有几十分钟。因此部署通道的价值不在「无线很方便」,而在可断点、可校验、可回退——包传一半断连不必重来,装上去不健康能在 5 秒内自动回到旧槽。

    这与车载采集和复盘环节的诉求是一致的:SR-RaceBox 车载数据采集器 负责把姿态与位置数据完整落盘,SR-Data 圈速分析器 负责事后复盘,任何一次「改完就回不去」的更新都会让整段数据失去连续性。对 Toyota GR86 这类以 OBD 车速作为计时输入的场景尤其明显——计时口径一旦在更新中改变,同一条赛道(例如 宁波国际赛车场)的历史圈速就无法再横向比较。

    FAQ

    EdgeDeploy 和 OTA 是一回事吗?

    不是。OTA 通常指整份固件的无线替换;EdgeDeploy 传的是签名的功能包 EFP,落地后要经 A/B 包管理器暂存、试运行与原子激活,且传输层自带断点续传与提交结果重放。

    BLE 传固件为什么一定要拆成 128 字节?

    因为 GATT 写片受 MTU 限制。EdgeDeploy 把 512 字节 DATA 拆成 128 字节写片,配合通知流重组与重传,才能在受限链路上保证完整性。

    断点续传后还需要重新验签吗?

    需要。整包 SHA-256 与 Ed25519 验签在接收端完成后才交给包管理器,续传只解决字节完整性,不替代来源校验。

    现在能说 EdgeDeploy 已经量产可用吗?

    不能。外接 UART 实传、掉电恢复、Android 真机配对与长期运行仍未验证,Wasm 后端属 P3 未完成项。

    参考资料

    • 项目 05 —— D:/Backup/Documents/开发板侧端模型/EdgeForge自编译软件框架方案.md(V1.4,平台层五类接口、EdgeDeploy v1、MVU 与 P3 路线)
    • 项目 05 —— D:/Backup/Documents/开发板侧端模型/DEVELOPMENT_TASKS.md(EF-105 / EF-105A / EF-105C / EF-106 / EF-106D / EF-114A 状态)

    更新记录

    首次发布 2026-10-11 最近核对:2026-10-11

  • 赛道日数据复盘:用 42 条赛道分段定位每一秒失分

    先说明数据来源:本篇所属的赛道工程实验数据项目(nixiang-tracklab)存放在 NAS,当前因缺少 SMB 凭据而不可达,本次没有任何来自该项目的输入。以下内容基于站点既有的赛道档案与产品能力写成,属于通用复盘方法,不含该项目的实验结论。

    结论先行:复盘的产出不是「我今天快了多少」,而是「我在第几段慢了、为什么慢、下一步先改什么」。这三问必须按顺序回答,跳过前面直接改硬件,是最常见的浪费。

    第一步:先有分段,再谈圈速

    没有分段的圈速只是一个数字。SR-Track 中国赛道数据包当前收录 42 条赛道,提供赛道中心线、自动分段、按车型规格分组的参考圈速、关键超车点与刹车点标注、地形剖面与高差数据;赛道改版后 7 个工作日内更新,历史版本保留 12 个月。

    赛道 全长 弯数 官方单圈(登记值)
    宁波国际赛车场 4.014 km 12 1:38.5(GT3,2024)
    鄂尔多斯国际赛车场 4.005 km 19 1:39.0(GT3,2024)
    天津滨海国际赛车场 3.594 km 18 1:42.3(GT3,2024)
    上海国际赛车场 5.451 km 16 1:31.4(GT3,2024)

    弯数越多,分段对比的价值越大。鄂尔多斯国际赛车场 有 19 个弯,是练习分段拆解的理想场地;宁波国际赛车场 弯型组合紧凑,适合建立连续节奏并做分段对比。

    第二步:定位最大失分路段

    把每一段的最快值与本次值做差,取绝对值最大的那一段。这一步要刻意忽略总圈速——总圈速的改善是结果,不是抓手。SR-Data 圈速分析套件会自动完成逐段对比并标出最大失分路段。

    需要注意的是,参考圈速按车型规格分组。用 GT3 规格的参考值去比一台原厂车,得到的差值没有意义;正确做法是同车型规格、同场地条件下的纵向对比,或者与自己本场的最快圈做横向对比。

    第三步:判断成因,而不是猜成因

    失分通常来自三类:刹车点过早或过晚、出弯油门开度不足、走线偏差。三者在数据上的表现不同,可以区分:

    成因 数据表现 判读方法
    刹车点问题 入弯前速度曲线提前下降 刹车点反推与理论最优值比较
    出弯牵引不足 出弯段油门开度滞后或波动 油门开度图识别隐形损失
    走线偏差 分段速度整体偏低且稳定 走线偏差计算
    轮胎状态 同一段随时间单调变慢 胎温、胎压与磨损趋势追踪

    SR-Data v2.4.0 重写了刹车点反推算法,精度提升约 0.05 秒;v2.4.1 新增胎温趋势热力图。0.05 秒这个量级未必直接改变你的驾驶,但它决定了「这一段到底差多少」这个判断是否可信。

    第四步:按车型特性排优先级

    同样的失分,在不同车型上的改进顺序不同。以 Nissan GT-R (R35) 为例,它的全时四驱会掩盖走线问题——驾驶员不容易察觉出弯牵引与走线的缺陷,因此第一步永远是建立客观数据基线,而不是先改 ECU、排气或避震。四驱让车「感觉很快」,但分段数据通常不这么认为。

    相反,轻量后驱车的失分更多出现在出弯阶段,此时轮胎与避震的收益远高于动力。判断依据是分段差值集中在哪一类路段:集中在低速弯多半是机械抓地问题,集中在长直道末端才是动力问题。

    采集端要保证数据完整。SR-RaceBox 车载数据采集器 以 IMU 50 Hz、GPS 20 Hz 同步记录,宽压 CAN 覆盖 12V–36V,掉电保护保证异常断电不丢已记录段,本地 SD 与实时上传双通道并存。分析在 SR-Data 圈速分析套件 中离线完成,数据不出本地。

    复盘流程

    1. 确认赛道分段与同规格参考圈速(赛道改版后需重新核对版本)
    2. 导入本场全部圈速,剔除无效圈(出站圈、被阻挡圈、黄旗圈)
    3. 逐段对比,定位绝对值最大的失分路段
    4. 用刹车点反推与油门开度图判断该段成因
    5. 按车型特性排改进优先级,一次只改一个变量
    6. 下一场用同样的分段重新采集,验证改动是否生效

    第 5 步最容易被忽略。一次改三个变量,得到的数据无法归因,等于这一场白跑。

    FAQ

    没有参考圈速就不能复盘吗?

    可以复盘,只是基准不同。可以先与自己本场的最快圈做横向对比,同车型同条件下的纵向对比也有价值。

    50 Hz 采样够用吗?

    够做刹车点与走线分析。SR-RaceBox 采用 IMU 50 Hz、GPS 20 Hz 同步记录;采样率需求随分析精度提高而提高。

    为什么四驱车更依赖数据?

    因为四驱会掩盖走线问题。GT-R R35 的改装建议第一条就是「先做数据记录」,否则后续改装容易变成盲目投入。

    一次能改几个变量?

    一个。多变量同时改动会导致数据无法归因,无法判断哪项改动真正生效。

    参考资料

    • 站点赛道档案 —— https://sracing.cn/wp/wp-json/wp/v2/track(2026-10-11 实测,8 条赛道)
    • 站点产品档案 —— SR-Data 圈速分析套件 v2.4.1、SR-RaceBox 车载数据采集器 v3.1.2、SR-Track 中国赛道数据包 2026.10
    • 说明 —— 项目 03 nixiang-tracklab(\192.168.31.115团队文件-星核公司数据库公共中转站nixiang-tracklab)本次不可达,无输入

    更新记录

    首次发布 2026-10-11 最近核对:2026-10-11

  • 一套令牌覆盖 5 种分辨率:车载 HUD 从 456×280 到 1280×720 的适配工程

    结论:一块屏扩成五块屏,成本取决于「一套规则能复用多少」,而不是画了多少张图。我们的赛道 HMI 原型用一套设计令牌加一组布局推导规则驱动 5 种画布,从 456×280 到 1280×720,自动生成 52 张预览。新增一块屏时改的是推导规则,不是重画一套视觉。

    五块画布的尺寸与旋转关系

    画布 UI 分辨率 物理面板 定位
    1.64 寸 456×280 280×456 竖屏,旋转使用 极简零百计时
    3.5 寸 480×320 320×480 竖屏,旋转使用 单表
    4.3 寸 800×480 480×800 IPS 横屏使用 赛道分区
    5.0 寸 1280×720 720×1280 IPS 横屏使用 宽屏全景
    3.97 寸电子纸 800×480 800×480 电子纸 离线路书

    这里有个容易沿用的错误:1.64 寸不是圆屏。它的原生面板是 280×456 的长方形 AMOLED,早期视觉稿里的「400×400 圆表」是过时概念稿。这个数字很重要——它决定了 UI 必须按 456×280 重新排,而不是把圆表缩放过来。

    令牌分两层:结构色与语义色

    以默认的「厂商(pro)」主题为例,令牌按职责分成两层,这个分层是跨尺寸复用的前提:

    层 令牌 色值 用途
    结构层 背景 #05080A 夜间主屏
    面板 #0D1417 卡片与次级底条
    抬升面 #131D21 最佳成绩与告警格底
    主读数 #EDF3F4 车速、转速、时间
    次级文字 #93A7AC 标签与单位
    三级文字 #5B6E75 指标名与弱化信息
    语义层 青色 #4FD1C5 最佳圈、速度弧
    琥珀 #F5B942 DELTA、预警、转速弧
    绿色 #7CD98A 低转换挡灯、正常状态
    红色 #FF5A4E 高转灯、报警

    结构层可以随主题变化,语义层不可以。红 / 琥珀 / 绿在五套主题中始终对应报警、预警与正常——这样驾驶员换主题后仍然能「不读数值就判断状态」。语义色不得用于装饰,只能承载状态。

    布局靠推导,不靠等比放大

    这是跨分辨率适配的核心规则:圆表的半径与圆心由可用区宽与高度共同推导,而不是从一个基准尺寸缩放。宽屏下如果直接放大,两个圆表会重叠;按可用区反推半径之后,4.3 寸与 5.0 寸都能保证不重叠。

    同理,信息密度也不是线性增长。5.0 寸的底栏比 4.3 寸多一格胎压,这是宽屏专属的密度提升,而不是把 4.3 的布局拉长。反过来,1.64 寸承担不了圈速栈——那个尺寸只做超大数字双格与底部进度条。

    两类硬约束:电子纸与浅底主题

    电子纸单独一套版式,白底黑字,不套用任何彩屏主题。这不是风格偏好,而是刷新特性决定的:它只用于静态路书与停车状态信息,不显示实时车速、转速或胎压告警。局刷、翻页残影与休眠电流目前仍是待实测项目,在确认波形与刷新能力之前,不能把部分刷新写成必然支持。

    复古主题是浅底设计,被明确排除在夜间驾驶首屏之外——浅底在夜间的反差不足。这条排除规则和电子纸一样,属于设计约束而非审美取舍。

    余光可读靠排版,不只靠字号

    标签统一加字距,数值走 Bahnschrift 类窄体无衬线。窄体能让同样的横向空间容纳更多字符,加字距则让标签在余光扫过时更容易被区分。这两个手段加起来的效果,比单纯放大字号更省空间。

    需要提醒的是,预览使用的是系统字体(Bahnschrift / Microsoft YaHei / Impact / Georgia / Consolas)。固件移植前必须选定允许嵌入式再分发的字体,并重新检查文字边界——换字体就会改变字宽,越界检测要重跑一遍。

    主题切换在设计上有一个可复现的前提:五套主题共享同一组模拟 OBD 数据、计时与告警状态,切换主题不重置回放。这让主题对比变成可比较的实验,而不是五次不同的演示。像 鄂尔多斯国际赛车场 这类高差明显的场地,坡度信息在底部辅助条里的价值更高;而赛道数据的赛后分段复盘可以交给 SR-Data 圈速分析套件,HMI 只负责当场能读懂的那一屏。

    FAQ

    一套令牌真的能覆盖 456×280 到 1280×720?

    能。令牌定义的是色板与字号层级,布局由可用区宽与高度共同推导。例如双圆表的半径与圆心会按可用区计算,以保证宽屏下不重叠。

    1.64 寸是圆屏吗?

    不是。它的原生面板是 280×456 长方形 AMOLED,UI 横屏使用为 456×280,早期视觉稿里的 400×400 圆表是过时概念稿。

    为什么切换主题不会重置回放?

    因为五套主题共享同一组模拟 OBD 数据、计时与告警状态,主题只改变渲染方式,不重置数据。

    语义色可以跟着主题改吗?

    不可以。红 / 琥珀 / 绿在五套主题中分别对应报警、预警与正常,主题只改变底色与版式。

    参考资料

    • 项目 06 —— D:/AI/PROJECTS/kno/README.md(五屏五主题、设计令牌与布局推导)
    • 项目 06 —— D:/AI/PROJECTS/kno/style-skill-research.md(原创风格与检索边界)
    • 项目 04 —— research/five-board-hardware-facts.md(各板原生分辨率与旋转关系)
    • 项目 04 —— research/instrument-matrix.md(风格覆盖规则与 52 张预览)

    更新记录

    首次发布 2026-10-11 最近核对:2026-10-11

    {“@context”:”https://schema.org”,”@graph”:[{“@type”:”FAQPage”,”mainEntity”:[{“@type”:”Question”,”name”:”一套设计令牌真的能覆盖 456×280 到 1280×720 五种分辨率?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”能。令牌定义的是色板与字号层级,布局由可用区宽与高度共同推导。双圆表的半径与圆心会按可用区计算,以保证宽屏下不重叠。”}},{“@type”:”Question”,”name”:”1.64 寸车载屏是圆屏吗?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”不是。它的原生面板是 280×456 长方形 AMOLED,UI 横屏使用为 456×280。早期视觉稿里的 400×400 圆表是过时概念稿。”}},{“@type”:”Question”,”name”:”为什么切换主题不会重置 OBD 回放?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”五套主题共享同一组模拟 OBD 数据、计时与告警状态,主题只改变渲染方式,不重置数据,因此主题对比是可复现的实验。”}},{“@type”:”Question”,”name”:”HMI 的语义色可以跟着主题改变吗?”,”acceptedAnswer”:{“@type”:”Answer”,”text”:”不可以。红、琥珀、绿在五套主题中分别对应报警、预警与正常状态,主题只改变底色与版式,语义色不得用于装饰。”}}]}]}

    延伸阅读

  • 电子纸路书:3.97 寸离线路书为什么用黑白

    结论:3.97 寸电子纸路书的定位是离线静态阅读,而不是实时仪表,所以它采用白底黑字、单色大 tulip 图与简短中文路书,并且不套用彩屏的五套主题。它的刷新方式、局刷能力与残影表现目前仍是待实测项——微雪概览页未列出屏控 IC、色阶与刷新方式。

    电子纸路书为什么用黑白,而不是彩屏

    因为角色不同:彩屏承担实时仪表与告警,电子纸只承担离线阅读路书,所以它不参与彩屏主题体系。在 kno 赛道 HMI 原型里,3.97 寸是唯一一块白底黑字、大 tulip 路线图、简短中文路书的画布,并明确不套用彩屏主题、不受主题切换影响。它的色彩令牌也只有两个值:#F1F1EA 与 #202A2A,用途写的是「单色静态路书」。

    这个取舍是有道理的。路书是上车前要记住、上车后偶尔翻一眼的东西,不是需要每秒刷新的数据。把它放在电子纸上,好处是静态内容在强光下可读、断电也不丢画面;代价则是放弃实时性——电子纸不承担圈速、转速、告警这类必须实时的信息。彩屏侧的信息架构与告警设计另见 赛道仪表的信息架构:从圈速到告警的设计顺序。

    3.97 板上的硬件事实有哪些?

    这块板的官方概览页确认了主控、存储、屏幕分辨率与板载外设,但没有列出屏控 IC、色阶与刷新方式。下表逐项列出,方便核对。

    项目 官方概览页事实 备注
    采购型号 ESP32-S3-ePaper-3.97-EN -EN 为采购记录中的语言 / 销售后缀;实际 PCB 修订版需核对丝印
    主控与存储 ESP32-S3-WROOM-1-N16R8;8MB PSRAM,16MB Flash —
    屏幕 800×480 电子纸,横屏路书 概览页未列屏控 IC、色阶与刷新方式
    触摸 概览页未列触摸 不作为交互假设
    板载外设 Micro SD、PCF85063 RTC、QMI8658 IMU、SHTC3、ES8311、TG28 RTC 与 IMU 是板上实际存在的外设
    供电与接口 3.7V 电池接口 / 充电、USB-C —

    需要强调的是表格的空白项也是一种事实。「概览页未列屏控 IC、色阶或刷新方式」意味着这些参数不能凭经验填值——同厂的彩屏板型号各不相同,把彩屏驱动方案套到电子纸上没有依据。按项目现有的核对流程,这类缺失项要回到该型号的官方资料继续查,而不是估算。

    离线路书在原型里怎么组织?

    原型用「18 页示意路书 + 3 张示意 tulip 图循环」来组织,并用上一页 / 下一页切换;刷新能力与残影没有在浏览器中模拟。

    这里有两层信息要分开看。第一层是内容结构:18 页路书、3 张示意 tulip 图循环复用,说明路书在原型里的组织单位是「页」,而不是滚动列表——这符合电子纸的阅读方式,一次刷一整页。第二层是验证边界:浏览器里的翻页只是布局与分页逻辑的演示,它不产生任何关于刷新速度、残影或功耗的数据。tulip 是路书里的示意图形代号,本轮使用的是示意图,不是真实赛道的测量路书。

    如果要把示意路书换成真实赛道路书,数据侧可对照 SR-Track 中国赛道数据包;赛道几何与长度基准可参考 珠海国际赛车场。选屏形态(圆屏还是方屏、黑白还是彩色)的判断逻辑另见 圆屏还是方屏:车载仪表的显示形态该怎么选。

    电子纸的刷新能力为什么还算「待实测」?

    因为概览页没有给出屏控 IC、色阶与刷新方式,所以局部刷新、200 次翻页后的残影、以及休眠电流都只能列为实测项目,不能写成已达成。

    这是本项目在数据分寸上的一条硬规则:在确认波形与刷新能力之前,不把「部分刷新」写成必然支持。电子纸的刷新行为高度依赖具体屏体与波形配置——同一块 800×480 面板,全刷与局刷的表现、刷新耗时与残影积累都可能完全不同。缺了屏控 IC 与刷新方式这两项前提,任何关于「支持局刷」的结论都是推断而非事实。

    维度 彩屏(1.64 / 3.5 / 4.3 / 5.0 寸) 电子纸(3.97 寸)
    介质 彩色 AMOLED / IPS 单色电子纸 800×480
    角色 实时仪表、圈速、告警 离线静态路书
    主题 五套主题可切换 不套用彩屏主题,不受切换影响
    色彩令牌 背景层 / 文字层 / 语义四色 #F1F1EA / #202A2A 双色
    刷新与功耗 原型未验证实机帧率(30 FPS 为验收目标) 局刷、200 次翻页残影、休眠电流均为待实测

    顺带说明:这块板上另有 RTC(PCF85063)与六轴 IMU(QMI8658)。它们的存在不等于已经用上——在路书场景里,RTC 与 IMU 的用途需要在固件阶段单独设计,目前原型并未把它们接入路书的展示逻辑。另外,原型的预览使用系统字体,固件移植前同样须选定允许嵌入式再分发的字体并重新检查文字边界。

    常见问题

    3.97 寸电子纸路书支持局部刷新吗?

    目前不能下结论。微雪的概览页未列出该型号的屏控 IC、色阶与刷新方式,因此局刷能力、200 次翻页后的残影表现和休眠电流都列为实测项目。在确认波形与刷新能力之前,不把「部分刷新」写成必然支持。

    电子纸路书为什么不用彩屏的那五套主题?

    因为用途不同。五套彩屏主题(厂商 / JDM / 赛道 / 复古机械 / 霓虹遥测)服务的是实时仪表与告警,靠颜色表达状态;电子纸是单色静态介质,只负责离线阅读路书,不承担实时告警,因此保持白底黑字、单色 tulip 图与简短中文路书,也不受主题切换影响。

    原型里的 18 页路书是真实赛道数据吗?

    不是。原型使用的是示意路书:18 页内容与 3 张循环使用的示意 tulip 图,用于演示分页与布局逻辑。真实的赛道路书需要接入赛道测量数据后重新生成。

    浏览器里的翻页效果等于实机刷新效果吗?

    不等于。原型在浏览器中翻页只是布局与分页逻辑的演示,刷新能力与残影没有在浏览器中模拟。实机的刷新耗时、残影积累与功耗必须实机实测。

    本文数据来自星核火花赛车科技内部两个项目:赛道 HMI 原型项目(kno)的《赛道 HMI 原型(kno 副本 · 统一厂商风)》README(2026-10 版),以及车载小仪表开发板调研项目的《五块赛道产品候选板:硬件事实表》(核查日期 2026-10-03,参数以微雪各型号 Wiki 概览页为准)。硬件参数为官方概览页标称值,不代表实机测试完成;局部刷新、200 次翻页残影与休眠电流为源文档明确标注的待实测项目,文中未写成已达成。原型中除分辨率与色彩令牌外的数值均为明确标注的模拟数据。

  • 五套赛道 HMI 主题:配色、栅格与余光可读性

    结论:五套赛道 HMI 主题(厂商 / JDM / 赛道 / 复古机械 / 霓虹遥测)只改视觉语言,不改信息架构:它们共享同一组模拟 OBD 数据、计时与告警状态,切换主题不重置回放。决定余光可读性的不是配色本身,而是固定位置的告警区、统一字距的标签与窄无衬线大数值。

    五套主题改的是视觉语言,不是信息架构

    五套主题的差异只落在配色、字形与动效这一层,数据优先级与告警逻辑完全一致。这一点在 kno 赛道 HMI 原型里是硬约束:五套主题共享同一组模拟 OBD 数据、计时与告警状态,切换主题不重置回放。换句话说,主题是一层皮,不是一套新逻辑。

    这条约束的价值在于可验证性。如果每个主题各带一套自己的数据流或计时状态,就没法判断「同一个工况下五种视觉是否都读得出来」——变量太多。把主题限制在视觉层,才能让「换主题」这件事变成纯粹的视觉对照。信息架构本身的设计顺序另见 赛道仪表的信息架构:从圈速到告警的设计顺序。

    五套主题分别在强调什么?

    五套主题各有明确取向:厂商主题求统一克制,JDM 与霓虹求动效层次,赛道与复古求朴素可读。下表是各主题的视觉规则与数据驱动的动效。

    主题 视觉规则 数据与动效
    厂商 pro(默认) 统一深底、统一字距标签、窄无衬线大数值、青 / 琥珀 / 绿 / 红告警色板 换挡灯条与转速弧由 RPM 驱动;右侧告警柱与底栏随工况变色
    JDM 深底、压缩展示字、机械刻度、红针、湖绿车速色块 RPM 驱动分段换挡灯与指针;车速驱动进度块
    赛道 中性深底、大数字和清晰分隔线 优先突出 OBD 车速、圈速和告警
    复古机械 中性浅色表盘、细刻度、红针、衬线数字 指针随车速和转速变化,状态以文字和颜色双重表达
    霓虹遥测 深色数码排版、青 / 蓝 / 粉色量化条、模块化信息区 速度和转速用分段色块推进;报警区随工况变色

    「厂商」是这一轮新增并设为默认的主题。它的参考对象(RaceLogic / AiM MXS / PLEX SDM / MoTeC / Forza / iRacing / SimHub / RaceLab 等)在本轮只以文字描述的形式提供,图片文件不在工作区内,因此该主题是按描述建立的信息架构与原创视觉,未做逐图参考比对。所有图形、文字与布局均重新绘制,不使用任何参考品牌的 logo、商标字体或截图素材。

    颜色为什么必须写成「有用途的令牌」,而不是随手取色?

    把颜色写成有用途的令牌,是让五块屏、五套主题保持一致的前提;pro 主题的令牌按背景层、文字层、语义层三级组织。

    层级 令牌 色值 用途
    背景层 背景 #05080A 夜间主屏
    背景层 面板 #0D1417 卡片、次级底条
    背景层 抬升面 #131D21 强调格(如最佳成绩、告警格底)
    背景层 描边 #1E2B31 卡片边框
    背景层 分隔线 #16242A 字段分区
    文字层 主读数 #EDF3F4 车速、转速、时间
    文字层 次级文字 #93A7AC 标签、单位
    文字层 三级文字 #5B6E75 指标名、弱化信息
    语义层 青色 #4FD1C5 最佳圈、速度弧、强调
    语义层 琥珀 #F5B942 DELTA、预警、转速弧
    语义层 绿色 #7CD98A 低转换挡灯、正常状态
    语义层 红色 #FF5A4E 高转灯、报警
    单色介质 电子纸 #F1F1EA / #202A2A 单色静态路书

    把颜色分成三层,解决的是「改一处、乱一片」的问题。背景层只负责层次,五档灰阶拉开卡片与底条的关系;文字层只负责可读性,主读数与次级、三级文字之间有明确的亮度落差;语义层只负责含义,青 / 琥珀 / 绿 / 红各自绑定一种状态,不参与装饰。语义色一旦被拿去当装饰,告警就不再可靠——这是配色表里最需要守住的一条。

    余光可读性靠哪三条规则保证?

    余光可读性靠三条可执行的规则:告警位置固定、标签统一加字距、数值走窄无衬线大字号。它们都是可检查的工程约束,不是审美偏好。

    第一条是告警位置固定。赛道驾驶时不可能逐字阅读,只能靠余光判断颜色和位置:在 3.5 寸上是顶部换挡灯条加下方四格,告警时水温与油压两格转红并描红边;在 4.3 与 5.0 寸上是右侧独立的告警状态柱,固定显示油压、水温、电压、OBD 四项。位置不随数据变化而移动,是余光可读的前提——告警一旦会「跳」,余光就失效了。

    第二条是标签统一加字距(letter-spacing)。中文标签在深底窄间距下容易糊成一团,统一拉开字距能让字符边界在余光下更清楚。

    第三条是数值走 Bahnschrift 类窄无衬线字体。窄无衬线在相同物理宽度内能塞下更大的字号,这对 1.64 寸这类小画布尤其关键。

    这些主题目前能证明什么、不能证明什么?

    能证明的是信息架构与视觉语言的自洽性,不能证明的是任何实机显示与计时性能。原型的自动校验用 Playwright 遍历 5 块屏 × 5 套主题 × 全部副视图,逐项检查:SVG viewBox 是否为各板原生像素尺寸;所有 <text> 元素是否越出画布(用 getBBox() 逐项检测);SVG 内容中是否泄漏 undefined 字符串;默认主题是否为 pro、主题切换是否生效;以及 OBD 回放推进、计时完成、断连状态、路书翻页、移动端横向溢出等交互状态。

    但边界必须写明——这套原型不证明 ESP-IDF / LVGL 点屏、SPI / DSI 帧率、实车 PID 支持或计时精度。显示链路的帧率约束可参考 车载 HMI 的 30 FPS:SPI 与 MIPI-DSI 显示链路差在哪。另外两条限制同样要留档:预览使用的是系统字体(Bahnschrift / Microsoft YaHei / Impact / Georgia / Consolas),固件移植前须选定允许嵌入式再分发的字体并重新检查文字边界;圈速、侧向 G、胎压等数值为示意值,档位与油压尚无车型适配,零百计时只使用模拟 OBD 车速,实机须接入受保护的 OBD 网关。

    还有一层方法论上的取舍值得记录。本轮在动手之前先检索了可核验的 UI 设计 skill:本机 skill-installer 的 OpenAI curated 目录接口返回 HTTP 403,应用内浏览器的设计系统检索连接超时,本机 visualize skill 的说明明确其用于对话内可视化、不适用于修改现有项目页面。因此本轮没有安装或引用任何未经核验的第三方 skill,风格直接落在已有 HMI 工程里实现。这比先引入一个来路不明的设计系统再回退要省事得多。赛道数据侧可对照 SR-Data 圈速分析套件,赛道几何与圈速基准可参考 上海国际赛车场。

    常见问题

    赛道仪表的配色应该先定哪一层?

    先定语义层,再定文字层,最后定背景层。语义色(青 / 琥珀 / 绿 / 红)绑定告警含义,一旦被装饰占用就失去可靠性;文字层要保证主读数与次级、三级文字有明确亮度落差;背景层只是把卡片与底条分出层次。顺序反了,改配色时会连带改掉信息层级。

    JDM 主题和霓虹主题的核心区别是什么?

    区别在动效的表达方式。JDM 用机械刻度、实体指针和珊瑚红 / 湖绿实色色块,靠 RPM 驱动分段换挡灯与指针、车速驱动进度块;霓虹遥测则用深色数码排版、青 / 蓝 / 粉色量化条和模块化信息区,靠速度和转速的分段色块推进。前者模仿机械表,后者模仿数码遥测。

    切换视觉主题会重置计时或 OBD 数据吗?

    不会。五套主题共享同一组模拟 OBD 数据、计时与告警状态,切换主题不重置回放。这正是把主题限制在视觉层的目的——保证换主题时变量只有一个。

    这五套主题能直接烧进固件吗?

    不能直接移植。它们用系统字体渲染,且不证明 ESP-IDF / LVGL 点屏、SPI / DSI 帧率、实车 PID 支持或计时精度。固件移植前须选定允许嵌入式再分发的字体并重新检查文字边界,并完成实机验证。

    本文数据来自星核火花赛车科技内部赛道 HMI 原型项目(kno)的《赛道 HMI 原型(kno 副本 · 统一厂商风)》README(2026-10 版)与《仪表 UI 风格与 skill 检索》(检索日期 2026-10-04)。五套主题共享的 OBD、计时与告警状态均为明确标注的模拟数据;「厂商」主题未做逐图参考分析,参考图仅以文字描述形式提供。文中的 skill 检索结果(HTTP 403、连接超时、visualize 不适用)为 2026-10-04 当次实测结论,仅代表当日状态。本原型不构成对 ESP-IDF / LVGL 点屏、SPI / DSI 帧率、实车 PID 支持或计时精度的验证。