JetWave 航行日志分析系统改进方案 v2.0
| 项 | 内容 |
|---|---|
| 版本 | v2.0 |
| 日期 | 2026-06-01 |
| 状态 | 设计稿(待研发评审) |
| 基准版本 | TLA v1.0.2,故障码分级表 v1.0 |
| 依据文档 | FAULT_CODE_GRADED_REFERENCE.md、LOG_ANALYSIS_IMPROVEMENT_PLAN_PROTOCOL.md |
目录
- 现状诊断
- 核心问题清单
- 改进目标
- 数据模型重设计(Schema v2)
- 码表架构重设计(fault_catalog)
- 分析引擎重设计
- 三级分级落地方案
- 迁移策略
- 分阶段路线图
- 各领域视角补充
- 待研发确认项
1. 现状诊断
1.1 系统架构(已稳定,保留)
cron (15 min)
└─ run.py → worker.run_incremental()
├─ db/pending.py → SQL_PENDING(水位 + 版本过滤)
├─ oss_client.py → OSS JSON 下载 + 本地缓存
├─ session_analyzer.py → analyze_trajectory_row()
│ └─ fault_engine.py → analyze_session()
│ └─ esc_faults.py → 故障码掩码字典
└─ db/repository.py → upsert_analysis() + fault_detail
架构本身合理:增量水位、幂等 UPSERT、指纹跳过、版本触发重算,均设计正确,不动骨架,改填充。
1.2 当前 esc_faults.py 实际覆盖(仅 12 个码)
| 域 | 已覆盖 | 实际协议码数 | 覆盖率 |
|---|---|---|---|
| ESC | 6 | 24 | 25% |
| ECU | 3 | 6 | 50% |
| BMS | 4 | 22 | 18% |
1.3 核心痛点量化
| 问题 | 影响 |
|---|---|
has_fault 过宽 |
BMS 0x10(低电 10%)触发 has_fault=1,大量「故障会话」是电量告警 |
severity 与协议无关 |
纯自研打分,无法与 App 红/黄/蓝弹窗分级对应 |
overvoltage_points 语义混乱 |
0x400000 在 motorstuck 固件分支实为异常转速,报表误导研发 |
| 缺板体失控字段 | 研发三条 OR 逻辑无法一键筛出 |
| 转速超范围未检测 | |motorSpeed| >= 20000 是失控第三条,完全缺失 |
| 码表硬编码 | 新码入库须改 Python 代码、重新部署 |
| BMS 详情归并 | bms_fault_points 是所有 BMS 码之和,无法区分「低电告警」和「电芯失效」 |
| 日聚合缺失告警/失控统计 | surf_log_version_daily_stat 无 session_board_out_of_control、session_warning 列 |
2. 核心问题清单
P0 — 影响数据正确性(立即修)
- [ ] P0-1 新增
invalid_speed_points:|motorSpeed| >= 20000计数 - [ ] P0-2 新增
has_board_out_of_control:研发三条 OR 合成字段 - [ ] P0-3
0x400000中性命名:esc_faults.py中改名ESC_EVENT_0x400000,session_analyzer.py中overvoltage_points双写保留字段、新增esc_event_0x400000_points - [ ] P0-4 版本 bump →
1.0.3,触发全量重算
P1 — 影响报表可用性(1~2 周)
- [ ] P1-1 ESC 码表扩充至全部 24 码(含分级标注)
- [ ] P1-2 ECU 码表扩充至 6 码,使用协议常量名
- [ ] P1-3 BMS 码表扩充至 22 码,含分级
- [ ] P1-4 新增
has_protocol_fault、has_warning,has_fault改为收口字段 - [ ] P1-5
fault_severity_display字段:fault > warning > notice > none - [ ] P1-6 BMS 细分字段:
bms_warning_points、bms_fault_points(重定义) - [ ] P1-7 日聚合表新增
session_board_out_of_control、session_warning
P2 — 长期可维护性(1 月内)
- [ ] P2-1 码表外置为
fault_catalog.yaml,esc_faults.py从 YAML 加载 - [ ] P2-2 故障明细表新增
severity_level列 - [ ] P2-3
analysis/session_analyzer.py与tla/版本对齐 - [ ] P2-4 告警规则可配置化(YAML)
3. 改进目标
| 目标 | 指标 |
|---|---|
| 故障定级与 App 一致 | has_protocol_fault 与 App 红色弹窗 backIdx=2 对齐 |
| 板体失控可复现 | has_board_out_of_control=1 的会话即研发 failsafe 关注对象 |
| 报表误报率 | 原「故障会话」里 BMS 低电告警占比降至可区分 |
| 码表覆盖率 | ESC≥90%、ECU=100%、BMS≥90% |
| 更新无需部署 | P2 完成后,新增故障码只改 YAML 并重算 |
4. 数据模型重设计(Schema v2)
4.1 主表新增列(迁移 SQL)
-- 迁移文件: sql/migrations/20260601_tla_v1_0_3_graded_fault.sql
ALTER TABLE surf_motion_trajectory_analysis
-- P0: 板体失控
ADD COLUMN `invalid_speed_points` INT NOT NULL DEFAULT 0
COMMENT '|motorSpeed|>=20000 的轨迹点数(固件异常转速阈值)'
AFTER `stall_thr_motor_mismatch`,
ADD COLUMN `has_board_out_of_control` TINYINT(1) NOT NULL DEFAULT 0
COMMENT '板体失控:堵转 OR ESC_0x400000 OR 超范围转速(研发三条 OR)'
AFTER `invalid_speed_points`,
-- P1: 三级分级
ADD COLUMN `has_protocol_fault` TINYINT(1) NOT NULL DEFAULT 0
COMMENT '命中协议级故障(对应 App 红色弹窗 backIdx=2)'
AFTER `has_board_out_of_control`,
ADD COLUMN `has_warning` TINYINT(1) NOT NULL DEFAULT 0
COMMENT '命中告警/提醒(App 黄/蓝弹窗)但未达故障级'
AFTER `has_protocol_fault`,
ADD COLUMN `fault_severity_display` VARCHAR(16) NOT NULL DEFAULT 'none'
COMMENT '展示用最高级别: fault|warning|notice|none'
AFTER `has_warning`,
-- P1: 0x400000 中性字段(同时保留 overvoltage_points 向后兼容)
ADD COLUMN `esc_event_0x400000_points` INT NOT NULL DEFAULT 0
COMMENT 'escEventCode & 0x400000 点数(语义待研发确认)'
AFTER `overvoltage_ratio`,
-- P1: BMS 细分
ADD COLUMN `bms_notice_points` INT NOT NULL DEFAULT 0
COMMENT 'BMS 提醒级事件点数(低电20%/单体低压偏低等)'
AFTER `bms_fault_points`,
ADD COLUMN `bms_warning_points` INT NOT NULL DEFAULT 0
COMMENT 'BMS 告警级事件点数(低电10%/高温限速等)'
AFTER `bms_notice_points`,
ADD COLUMN `bms_critical_points` INT NOT NULL DEFAULT 0
COMMENT 'BMS 故障级事件点数(压差过大/单体失效/过流等)'
AFTER `bms_warning_points`;
-- 索引
ALTER TABLE surf_motion_trajectory_analysis
ADD KEY `idx_board_out_of_control` (`has_board_out_of_control`),
ADD KEY `idx_fault_severity` (`fault_severity_display`),
ADD KEY `idx_protocol_fault` (`has_protocol_fault`);
4.2 故障明细表新增列
ALTER TABLE surf_motion_trajectory_fault_detail
ADD COLUMN `severity_level` VARCHAR(8) NOT NULL DEFAULT 'unknown'
COMMENT 'fault|warning|notice|unknown'
AFTER `fault_code`,
ADD COLUMN `board_out_of_control_related` TINYINT(1) NOT NULL DEFAULT 0
COMMENT '是否参与板体失控合成'
AFTER `severity_level`;
4.3 日聚合表新增列
ALTER TABLE surf_log_version_daily_stat
ADD COLUMN `session_board_out_of_control` INT NOT NULL DEFAULT 0
COMMENT '板体失控会话数' AFTER `session_overvoltage`,
ADD COLUMN `session_warning` INT NOT NULL DEFAULT 0
COMMENT '纯告警(非故障)会话数' AFTER `session_board_out_of_control`,
ADD COLUMN `session_protocol_fault` INT NOT NULL DEFAULT 0
COMMENT '协议故障会话数' AFTER `session_warning`,
ADD COLUMN `invalid_speed_points_sum` BIGINT NOT NULL DEFAULT 0
COMMENT '超范围转速点数合计' AFTER `session_protocol_fault`;
4.4 字段语义重新定义
| 字段 | v1.0.2 语义 | v1.0.3 新语义 |
|---|---|---|
has_fault |
severity∈{high,critical} OR 任意码命中 | has_protocol_fault OR has_board_out_of_control(收口,不再因 BMS 提醒触发) |
has_anomaly |
D4A081 OR 轨迹空洞 | 不变 |
severity |
自研打分 none/medium/high/critical | 不变(保留,用于内部评分) |
fault_severity_display |
新增 | 对外展示级别,从码表 severity_level 取最高 |
overvoltage_points |
0x400000 计数 |
保留不变(向后兼容),与 esc_event_0x400000_points 值相同 |
bms_fault_points |
全 BMS 码之和 | 仅 BMS 故障级之和(breaking change,需 bump version) |
5. 码表架构重设计(fault_catalog)
5.1 目标文件结构
trajectory-log-analyzer/tla/
fault_catalog.yaml ← 新增,人工维护码表
esc_faults.py ← 改为从 YAML 加载(P2);P0/P1 阶段先内联扩充
fault_engine.py ← 使用新码表字段
session_analyzer.py ← 新字段 + bump version
5.2 fault_catalog.yaml 规范(P2 目标)
# fault_catalog.yaml — JetWave 故障码表(由此生成 esc_faults.py 运行时字典)
# 维护者: 固件/协议组 + 数据组
# 每次更新后: analyzer_version bump + FORCE_REANALYZE=1
version: "1.0.3"
updated: "2026-06-01"
esc:
# ── 故障级 (fault) ─────────────────────────────────────────────────────────
- code: ESC_FAULT_MOTOR_LINE_CURRENT_OUTPUT_1
mask: 0x00000001
severity: fault
display_zh: 电机线电流输出异常1
app_text: 电调模块故障,请联系售后
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_TOTAL_CURRENT_OUTPUT
mask: 0x00000002
severity: fault
display_zh: 总电流输出异常
app_text: 电调模块故障,请联系售后
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_MOTOR_LINE_VOLTAGE
mask: 0x00000004
severity: fault
display_zh: 电机线电压异常
app_text: 电调模块故障,请联系售后
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_ELECTROLYTIC_CAP_NTC_OUTPUT
mask: 0x00000008
severity: fault
display_zh: 电解电容NTC异常
app_text: 电调模块故障,请联系售后
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_MOSFET_NTC_OUTPUT
mask: 0x00000010
severity: fault
display_zh: MOS管NTC异常
app_text: 电调模块故障,请联系售后
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_MOTOR_LINE_LOOP_IMPEDANCE_SMALL
mask: 0x00000080
severity: fault
display_zh: 电机线回路阻抗偏小
app_text: 电调模块故障
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_MOTOR_LINE_LOOP_IMPEDANCE_LARGE
mask: 0x00000100
severity: fault
display_zh: 电机线回路阻抗偏大
app_text: 电调模块故障
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_MOTOR_LINE_VOLTAGE_DETECTION_1
mask: 0x00000200
severity: fault
display_zh: 电机线电压检测电路异常1
app_text: 电调模块故障,请联系售后
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_MOTOR_LINE_VOLTAGE_DETECTION_2
mask: 0x00000400
severity: fault
display_zh: 电机线电压检测电路异常2
app_text: 电调模块故障,请联系售后
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_MOTOR_LINE_CURRENT_OUTPUT_2
mask: 0x00000800
severity: fault
display_zh: 电机线电流输出异常2
app_text: 电调模块故障,请联系售后
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_SW_HW_INCOMPATIBLE
mask: 0x00002000
severity: fault
display_zh: 软硬件版本不兼容
app_text: ~
board_out_of_control: false
confirmed: true
notes: ECU 上报前通常已屏蔽
- code: ESC_FAULT_BOOTLOADER_UNSUPPORTED
mask: 0x00004000
severity: fault
display_zh: Bootloader不支持
app_text: ~
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_OVERCURRENT_SHORT_CIRCUIT_PROTECTION
mask: 0x00010000
severity: fault
display_zh: 过流/短路保护
app_text: 电调过流异常
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_OVERTEMPERATURE_PROTECTION
mask: 0x00040000
severity: fault
display_zh: 过温保护
app_text: 电调过温异常
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_PWM_SIGNAL_LOST
mask: 0x00080000
severity: fault
display_zh: PWM油门信号丢失
app_text: ~
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_THROTTLE_SATURATION
mask: 0x00200000
severity: fault
display_zh: 油门饱和
app_text: ~
board_out_of_control: false
confirmed: true
# ── 告警级 (warning) ────────────────────────────────────────────────────────
- code: ESC_FAULT_BUS_VOLTAGE_SAMPLING
mask: 0x00000040
severity: fault # selfcheck,归故障
display_zh: 母线电压采样异常
app_text: 电调模块故障,请联系售后
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_STALL_PROTECTION
mask: 0x00020000
severity: warning
display_zh: 电机堵转保护
app_text: 电机堵转,请检查螺旋桨
board_out_of_control: true
confirmed: true
notes: running_error bit1;研发口径 P0
- code: ESC_FAULT_CURRENT_HIGH
mask: 0x00800000
severity: warning
display_zh: 电调电流高(限速保护中)
app_text: 电调过流,限速保护中
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_TEMPERATURE_HIGH
mask: 0x01000000
severity: warning
display_zh: 电调温度高(限速保护中)
app_text: 电调温度高,限速保护中
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_PROPELLER_OUT_OF_WATER
mask: 0x02000000
severity: warning
display_zh: 螺旋桨离水空转保护
app_text: 螺旋桨未入水的空转保护
board_out_of_control: false
confirmed: true
# ── 提醒级 (notice) ─────────────────────────────────────────────────────────
- code: ESC_FAULT_BUS_VOLTAGE_OV_UV
mask: 0x00000020
severity: notice
display_zh: 母线电压过压或欠压
app_text: 电调输入电压异常
board_out_of_control: false
confirmed: true
- code: ESC_FAULT_NO_LOAD
mask: 0x00100000
severity: notice
display_zh: 无负载/电机空转
app_text: 电机空转
board_out_of_control: false
confirmed: true
# ── 待确认 ──────────────────────────────────────────────────────────────────
- code: ESC_EVENT_0x400000
mask: 0x00400000
severity: warning # 暂按告警;语义待研发确认
display_zh: ESC事件0x400000(过压/固件误映射,待确认)
app_text: ~
board_out_of_control: true
confirmed: false
notes: |
JetWave.xml 定义为过压保护;motorstuck 固件分支中 ECU 将 |speed|>=20000
(running_error bit6) 错误映射到此位。建议展示时标注"待确认"。
与 ECU ecuEventCode 0x40000000(ESC通信故障) 不同,注意区分。
ecu:
- code: FAULT_BOARD_ATTITUDE
mask: 0x04000000
severity: fault
display_zh: 板体姿态异常
app_text: 板体姿态异常
board_out_of_control: false
confirmed: true
- code: FAULT_FLASH_COMMUNICATION
mask: 0x08000000
severity: fault
display_zh: FLASH/SD通信故障
app_text: 主控模块故障,请联系售后
board_out_of_control: false
confirmed: true
- code: FAULT_WATER_PRESSURE_SENSOR_COMMUNICATION
mask: 0x10000000
severity: fault
display_zh: 水压传感器通信异常
app_text: 主控模块故障,请联系售后
board_out_of_control: false
confirmed: true
- code: FAULT_IMU_COMMUNICATION
mask: 0x20000000
severity: fault
display_zh: IMU通信故障
app_text: 主控模块故障,请联系售后
board_out_of_control: false
confirmed: true
notes: 勿与 ESC escEventCode 0x02000000 混淆
- code: FAULT_ESC_COMMUNICATION
mask: 0x40000000
severity: fault
display_zh: 电调通信故障(12s无数据)
app_text: 主控模块故障,请联系售后
board_out_of_control: false
confirmed: true
notes: 勿与 ESC escEventCode 0x00400000 混淆
- code: FAULT_BATTERY_COMMUNICATION
mask: 0x80000000
severity: fault
display_zh: 电池通信故障
app_text: 主控模块故障,请联系售后
board_out_of_control: false
confirmed: true
bms:
# ── 提醒级 ──────────────────────────────────────────────────────────────────
- code: BMS_LOW_SOC_WARNING_20
mask: 0x00000020
severity: notice
display_zh: 电量低于20%
app_text: 板体低电量20%
confirmed: true
- code: BMS_CELL_VOLTAGE_LOW
mask: 0x00000400
severity: notice
display_zh: 电池单体电压偏低
app_text: (仅埋点)
confirmed: true
- code: BMS_CELL_VOLTAGE_HIGH
mask: 0x00000800
severity: notice
display_zh: 电池单体电压偏高
app_text: ~
confirmed: true
- code: BMS_TOTAL_VOLTAGE_LOW
mask: 0x00001000
severity: notice
display_zh: 电池总电压偏低
app_text: (仅埋点)
confirmed: true
- code: BMS_TOTAL_VOLTAGE_HIGH
mask: 0x00002000
severity: notice
display_zh: 电池总电压偏高
app_text: ~
confirmed: true
# ── 告警级 ──────────────────────────────────────────────────────────────────
- code: BMS_LOW_SOC_WARNING_10
mask: 0x00000010
severity: warning
display_zh: 电量低于10%(严重低电)
app_text: 板体严重低电量10%
confirmed: true
- code: BMS_LOW_SOH_WARNING
mask: 0x00000040
severity: warning
display_zh: 电池健康度偏低
app_text: 电池健康度低
confirmed: true
- code: BMS_CELL_TEMP_DIFFERENCE_WARNING
mask: 0x00000080
severity: warning
display_zh: 电芯温差大
app_text: 电芯温差大
confirmed: true
- code: BMS_CELL_VOLTAGE_DIFFERENCE_WARNING
mask: 0x00000100
severity: warning
display_zh: 电芯压差大
app_text: 电芯压差大
confirmed: true
- code: BMS_BATTERY_CURRENT_HIGH
mask: 0x00000200
severity: warning
display_zh: 电池电流高(限速保护)
app_text: 电池过流,限速保护中
confirmed: true
- code: BATTERY_TEMP_LOW
mask: 0x00004000
severity: warning
display_zh: 电池温度偏低(保护中)
app_text: 电池温度过低保护中
confirmed: true
- code: BATTERY_TEMP_HIGH
mask: 0x00008000
severity: warning
display_zh: 电池温度偏高(限速)
app_text: 电池温度高,限速保护中
confirmed: true
# ── 故障级 ──────────────────────────────────────────────────────────────────
- code: BMS_CELL_VOLTAGE_DIFF_TOO_HIGH
mask: 0x00400000
severity: fault
display_zh: 电池压差过大
app_text: 电池压差过大,请联系售后
confirmed: true
- code: BMS_CELL_VOLTAGE_LOW_FAILURE
mask: 0x00800000
severity: fault
display_zh: 单体低压失效
app_text: 电池故障,请联系售后
confirmed: true
- code: BMS_CELL_VOLTAGE_HIGH_FAILURE
mask: 0x01000000
severity: fault
display_zh: 单体过压失效
app_text: 电池故障,请联系售后
confirmed: true
- code: BATTERY_CURRENT_TOO_HIGH
mask: 0x02000000
severity: fault
display_zh: 电池电流过高
app_text: 电池过流异常
confirmed: true
- code: BMS_CELL_VOLTAGE_TOO_LOW
mask: 0x04000000
severity: fault
display_zh: 电池单体电压过低
app_text: 电池故障,请联系售后
confirmed: true
- code: BMS_CELL_VOLTAGE_TOO_HIGH
mask: 0x08000000
severity: fault
display_zh: 电池单体电压过高
app_text: 电池故障,请联系售后
confirmed: true
- code: BMS_TOTAL_VOLTAGE_TOO_LOW
mask: 0x10000000
severity: fault
display_zh: 电池总电压过低(低电关机)
app_text: 板体低电量关机
confirmed: true
- code: BMS_TOTAL_VOLTAGE_TOO_HIGH
mask: 0x20000000
severity: fault
display_zh: 电池总电压过高
app_text: 电池故障,请联系售后
confirmed: true
notes: 勿与 ECU ecuEventCode 0x20000000 (IMU通信故障) 混淆
- code: BATTERY_TEMP_TOO_LOW
mask: 0x40000000
severity: fault
display_zh: 电池温度过低
app_text: 电池温度过低保护中
confirmed: true
- code: BATTERY_TEMP_TOO_HIGH
mask: 0x80000000
severity: fault
display_zh: 电池温度过高
app_text: 电池高温异常
confirmed: true
motor_speed_rules:
- rule: out_of_range
condition: "abs(motorSpeed) >= 20000"
severity: warning
board_out_of_control: true
display_zh: 转速反馈超范围(固件异常转速阈值)
confirmed: true
notes: 固件 esc_manager.c 阈值一致;单位 0.1RPM,即>=2000RPM
- rule: corrupt_d4a081
condition: "(motorSpeed >> 8) == 0xD4A081"
severity: anomaly
board_out_of_control: false
display_zh: 转速数据脏包(CAN通信异常)
confirmed: true
6. 分析引擎重设计
6.1 esc_faults.py — P0/P1 内联扩充(YAML 未上线前)
# P0/P1 过渡版本,P2 完成后由 fault_catalog.yaml 生成
SEVERITY = {
"fault": "fault",
"warning": "warning",
"notice": "notice",
"anomaly": "anomaly",
}
ESC_FAULTS: dict[str, int] = {
# ── 故障级 ──────────────────────────────────────────────────────────
"ESC_FAULT_MOTOR_LINE_CURRENT_OUTPUT_1": 0x00000001,
"ESC_FAULT_TOTAL_CURRENT_OUTPUT": 0x00000002,
"ESC_FAULT_MOTOR_LINE_VOLTAGE": 0x00000004,
"ESC_FAULT_ELECTROLYTIC_CAP_NTC_OUTPUT": 0x00000008,
"ESC_FAULT_MOSFET_NTC_OUTPUT": 0x00000010,
"ESC_FAULT_BUS_VOLTAGE_SAMPLING": 0x00000040,
"ESC_FAULT_MOTOR_LINE_LOOP_IMPEDANCE_SMALL": 0x00000080,
"ESC_FAULT_MOTOR_LINE_LOOP_IMPEDANCE_LARGE": 0x00000100,
"ESC_FAULT_MOTOR_LINE_VOLTAGE_DETECTION_1": 0x00000200,
"ESC_FAULT_MOTOR_LINE_VOLTAGE_DETECTION_2": 0x00000400,
"ESC_FAULT_MOTOR_LINE_CURRENT_OUTPUT_2": 0x00000800,
"ESC_FAULT_SW_HW_INCOMPATIBLE": 0x00002000,
"ESC_FAULT_BOOTLOADER_UNSUPPORTED": 0x00004000,
"ESC_FAULT_OVERCURRENT_SHORT_CIRCUIT_PROTECTION": 0x00010000,
"ESC_FAULT_OVERTEMPERATURE_PROTECTION": 0x00040000,
"ESC_FAULT_PWM_SIGNAL_LOST": 0x00080000,
"ESC_FAULT_THROTTLE_SATURATION": 0x00200000,
# ── 告警级 ──────────────────────────────────────────────────────────
"ESC_FAULT_STALL_PROTECTION": 0x00020000,
"ESC_FAULT_CURRENT_HIGH": 0x00800000,
"ESC_FAULT_TEMPERATURE_HIGH": 0x01000000,
"ESC_FAULT_PROPELLER_OUT_OF_WATER": 0x02000000,
"ESC_EVENT_0x400000": 0x00400000, # 语义待确认
# ── 提醒级 ──────────────────────────────────────────────────────────
"ESC_FAULT_BUS_VOLTAGE_OV_UV": 0x00000020,
"ESC_FAULT_NO_LOAD": 0x00100000,
}
ESC_SEVERITY: dict[str, str] = {
"ESC_FAULT_MOTOR_LINE_CURRENT_OUTPUT_1": "fault",
"ESC_FAULT_TOTAL_CURRENT_OUTPUT": "fault",
"ESC_FAULT_MOTOR_LINE_VOLTAGE": "fault",
"ESC_FAULT_ELECTROLYTIC_CAP_NTC_OUTPUT": "fault",
"ESC_FAULT_MOSFET_NTC_OUTPUT": "fault",
"ESC_FAULT_BUS_VOLTAGE_SAMPLING": "fault",
"ESC_FAULT_MOTOR_LINE_LOOP_IMPEDANCE_SMALL": "fault",
"ESC_FAULT_MOTOR_LINE_LOOP_IMPEDANCE_LARGE": "fault",
"ESC_FAULT_MOTOR_LINE_VOLTAGE_DETECTION_1": "fault",
"ESC_FAULT_MOTOR_LINE_VOLTAGE_DETECTION_2": "fault",
"ESC_FAULT_MOTOR_LINE_CURRENT_OUTPUT_2": "fault",
"ESC_FAULT_SW_HW_INCOMPATIBLE": "fault",
"ESC_FAULT_BOOTLOADER_UNSUPPORTED": "fault",
"ESC_FAULT_OVERCURRENT_SHORT_CIRCUIT_PROTECTION": "fault",
"ESC_FAULT_OVERTEMPERATURE_PROTECTION": "fault",
"ESC_FAULT_PWM_SIGNAL_LOST": "fault",
"ESC_FAULT_THROTTLE_SATURATION": "fault",
"ESC_FAULT_STALL_PROTECTION": "warning",
"ESC_FAULT_CURRENT_HIGH": "warning",
"ESC_FAULT_TEMPERATURE_HIGH": "warning",
"ESC_FAULT_PROPELLER_OUT_OF_WATER": "warning",
"ESC_EVENT_0x400000": "warning",
"ESC_FAULT_BUS_VOLTAGE_OV_UV": "notice",
"ESC_FAULT_NO_LOAD": "notice",
}
ESC_BOARD_OUT_OF_CONTROL: set[str] = {
"ESC_FAULT_STALL_PROTECTION",
"ESC_EVENT_0x400000",
}
ECU_FAULTS: dict[str, int] = {
"FAULT_BOARD_ATTITUDE": 0x04000000,
"FAULT_FLASH_COMMUNICATION": 0x08000000,
"FAULT_WATER_PRESSURE_SENSOR_COMMUNICATION": 0x10000000,
"FAULT_IMU_COMMUNICATION": 0x20000000,
"FAULT_ESC_COMMUNICATION": 0x40000000,
"FAULT_BATTERY_COMMUNICATION": 0x80000000,
}
ECU_SEVERITY: dict[str, str] = {k: "fault" for k in ECU_FAULTS}
BMS_FAULTS: dict[str, int] = {
# 提醒级
"BMS_LOW_SOC_WARNING_20": 0x00000020,
"BMS_CELL_VOLTAGE_LOW": 0x00000400,
"BMS_CELL_VOLTAGE_HIGH": 0x00000800,
"BMS_TOTAL_VOLTAGE_LOW": 0x00001000,
"BMS_TOTAL_VOLTAGE_HIGH": 0x00002000,
# 告警级
"BMS_LOW_SOC_WARNING_10": 0x00000010,
"BMS_LOW_SOH_WARNING": 0x00000040,
"BMS_CELL_TEMP_DIFFERENCE_WARNING": 0x00000080,
"BMS_CELL_VOLTAGE_DIFFERENCE_WARNING": 0x00000100,
"BMS_BATTERY_CURRENT_HIGH": 0x00000200,
"BATTERY_TEMP_LOW": 0x00004000,
"BATTERY_TEMP_HIGH": 0x00008000,
# 故障级
"BMS_CELL_VOLTAGE_DIFF_TOO_HIGH": 0x00400000,
"BMS_CELL_VOLTAGE_LOW_FAILURE": 0x00800000,
"BMS_CELL_VOLTAGE_HIGH_FAILURE": 0x01000000,
"BATTERY_CURRENT_TOO_HIGH": 0x02000000,
"BMS_CELL_VOLTAGE_TOO_LOW": 0x04000000,
"BMS_CELL_VOLTAGE_TOO_HIGH": 0x08000000,
"BMS_TOTAL_VOLTAGE_TOO_LOW": 0x10000000,
"BMS_TOTAL_VOLTAGE_TOO_HIGH": 0x20000000,
"BATTERY_TEMP_TOO_LOW": 0x40000000,
"BATTERY_TEMP_TOO_HIGH": 0x80000000,
}
BMS_SEVERITY: dict[str, str] = {
"BMS_LOW_SOC_WARNING_20": "notice",
"BMS_CELL_VOLTAGE_LOW": "notice",
"BMS_CELL_VOLTAGE_HIGH": "notice",
"BMS_TOTAL_VOLTAGE_LOW": "notice",
"BMS_TOTAL_VOLTAGE_HIGH": "notice",
"BMS_LOW_SOC_WARNING_10": "warning",
"BMS_LOW_SOH_WARNING": "warning",
"BMS_CELL_TEMP_DIFFERENCE_WARNING": "warning",
"BMS_CELL_VOLTAGE_DIFFERENCE_WARNING": "warning",
"BMS_BATTERY_CURRENT_HIGH": "warning",
"BATTERY_TEMP_LOW": "warning",
"BATTERY_TEMP_HIGH": "warning",
"BMS_CELL_VOLTAGE_DIFF_TOO_HIGH": "fault",
"BMS_CELL_VOLTAGE_LOW_FAILURE": "fault",
"BMS_CELL_VOLTAGE_HIGH_FAILURE": "fault",
"BATTERY_CURRENT_TOO_HIGH": "fault",
"BMS_CELL_VOLTAGE_TOO_LOW": "fault",
"BMS_CELL_VOLTAGE_TOO_HIGH": "fault",
"BMS_TOTAL_VOLTAGE_TOO_LOW": "fault",
"BMS_TOTAL_VOLTAGE_TOO_HIGH": "fault",
"BATTERY_TEMP_TOO_LOW": "fault",
"BATTERY_TEMP_TOO_HIGH": "fault",
}
PRIMARY_ESC_FAULTS = (
"ESC_FAULT_STALL_PROTECTION",
"ESC_EVENT_0x400000",
)
SEVERITY_ORDER = {"fault": 3, "warning": 2, "notice": 1, "none": 0, "anomaly": 0}
def severity_max(*levels: str) -> str:
"""取多个 severity 的最高级。"""
return max(levels, key=lambda s: SEVERITY_ORDER.get(s, 0))
6.2 session_analyzer.py — P0/P1 关键新字段伪码
ANALYZER_VERSION = "1.0.3" # bump
def is_invalid_motor_speed(motor_speed) -> bool:
"""固件阈值:|speed| >= 20000 (0.1 RPM = 2000 RPM)"""
if motor_speed is None:
return False
v = int(motor_speed)
return v <= -20000 or v >= 20000
def analyze_trajectory_row(row, data, ...):
rep = analyze_session(row, data) # fault_engine (不变)
tl = data.get("trajectoryList") or []
n = max(len(tl), 1)
# ── 新增: invalid_speed_points ─────────────────────────
invalid_speed_cnt = sum(
1 for p in tl
if not is_corrupt_motor_speed(p.get("motorSpeed")) # 排除脏包
and is_invalid_motor_speed(p.get("motorSpeed"))
)
# ── 新增: 分级统计 ─────────────────────────────────────
esc_matched_severity = {} # code -> severity
ecu_matched_severity = {}
bms_notice_cnt = bms_warning_cnt = bms_fault_cnt = 0
for p in tl:
for name in match_esc_faults(int(p.get("escEventCode") or 0)):
esc_matched_severity[name] = ESC_SEVERITY.get(name, "unknown")
for name in match_ecu_faults(int(p.get("ecuEventCode") or 0)):
ecu_matched_severity[name] = ECU_SEVERITY.get(name, "unknown")
for name in match_bms_faults(int(p.get("bmsEventCode") or 0)):
sev = BMS_SEVERITY.get(name, "unknown")
if sev == "notice": bms_notice_cnt += 1
elif sev == "warning": bms_warning_cnt += 1
elif sev == "fault": bms_fault_cnt += 1
has_protocol_fault = (
any(s == "fault" for s in esc_matched_severity.values()) or
any(s == "fault" for s in ecu_matched_severity.values()) or
bms_fault_cnt > 0
)
has_warning = (
any(s in ("warning","notice") for s in esc_matched_severity.values()) or
any(s in ("warning","notice") for s in ecu_matched_severity.values()) or
bms_warning_cnt > 0 or bms_notice_cnt > 0
) and not has_protocol_fault
stall_cnt = rep.esc_fault_points.get("ESC_FAULT_STALL_PROTECTION", 0)
esc0x400000 = rep.esc_fault_points.get("ESC_EVENT_0x400000", 0)
has_board_out_of_control = bool(
stall_cnt > 0
or esc0x400000 > 0
or invalid_speed_cnt > 0
)
# has_fault 重定义(收口)
has_fault = has_protocol_fault or has_board_out_of_control
# 展示级别
if has_protocol_fault:
fault_severity_display = "fault"
elif has_board_out_of_control:
fault_severity_display = "warning"
elif has_warning:
fault_severity_display = "warning"
elif any(s == "notice" for s in {**esc_matched_severity, **ecu_matched_severity}.values()) or bms_notice_cnt > 0:
fault_severity_display = "notice"
else:
fault_severity_display = "none"
return {
# ... 原有字段 ...
"invalid_speed_points": invalid_speed_cnt,
"has_board_out_of_control": 1 if has_board_out_of_control else 0,
"has_protocol_fault": 1 if has_protocol_fault else 0,
"has_warning": 1 if has_warning else 0,
"fault_severity_display": fault_severity_display,
"esc_event_0x400000_points": esc0x400000,
"overvoltage_points": esc0x400000, # 向后兼容,同值双写
"bms_notice_points": bms_notice_cnt,
"bms_warning_points": bms_warning_cnt,
"bms_critical_points": bms_fault_cnt,
"bms_fault_points": bms_fault_cnt, # v1.0.3 重定义:仅故障级
# ...
}
6.3 故障明细 _build_fault_details 扩充
def _build_fault_details(trajectory_id, tl):
...
rows.append({
"trajectory_id": trajectory_id,
"fault_domain": domain,
"fault_code": name,
"severity_level": severity_map.get(name, "unknown"), # 新增
"board_out_of_control_related": 1 if name in BOC_CODES else 0, # 新增
"fault_mask": mask,
"point_count": cnt,
"point_ratio": round(cnt / n, 4),
"first_seen_ms": first_ms,
})
7. 三级分级落地方案
7.1 分级判定决策树
每条轨迹点 event_code
├─ ESC: match_esc_faults()
│ → 记录 severity (fault/warning/notice)
│ → 若 board_out_of_control=true → 累计
├─ ECU: match_ecu_faults() → severity 均为 fault
└─ BMS: match_bms_faults()
→ 按 severity 分桶计数
会话级合成:
has_protocol_fault = 任一 fault 级码命中
has_board_out_of_control = stall OR 0x400000 OR invalid_speed
has_warning = 有 warning/notice 且无 fault
has_fault = protocol_fault OR board_out_of_control
fault_severity_display = fault > warning > notice > none
7.2 has_fault 新旧对比示例
| 会话类型 | v1.0.2 has_fault |
v1.0.3 has_fault |
说明 |
|---|---|---|---|
只有 BMS 0x10(低电 10%) |
1 ❌误判 | 0 ✅ | 告警,不是故障 |
BMS 0x10 + ESC 堵转 |
1 | 1 ✅ | 有 board_out_of_control |
只有 ESC 堵转 0x20000 |
1 | 1 ✅ | has_board_out_of_control |
只有 invalid_speed |
0 ❌漏检 | 1 ✅ | 第三条失控未落地 |
| 只有 ECU 通信故障 | 1 | 1 ✅ | 协议级故障 |
只有 ESC 离水空转 0x2000000 |
1 ❌误判 | 0(has_warning=1)✅ |
告警 |
8. 迁移策略
8.1 版本兼容矩阵
| 字段 | v1.0.2 值 | v1.0.3 变化 | 向后兼容 |
|---|---|---|---|
overvoltage_points |
0x400000 计数 | 同值(双写) | ✅ |
bms_fault_points |
全 BMS 之和 | 仅故障级之和 | ❌ breaking,需重算 |
has_fault |
宽定义 | 收口定义 | ❌ breaking |
severity |
自研打分 | 不变 | ✅ |
fault_codes JSON |
esc/ecu/bms | 不变 | ✅ |
| 新增列 | — | DEFAULT 0/'none' | ✅ 存量行安全 |
8.2 部署顺序
# Step 1: 执行迁移 SQL(新列 DEFAULT 安全,不阻塞读)
mysql -h HOST -u USER -p surf-dev < sql/migrations/20260601_tla_v1_0_3_graded_fault.sql
# Step 2: 部署新代码(ANALYZER_VERSION = "1.0.3")
docker compose build && docker compose up -d
# Step 3: 触发全量重算(仅重算 bms_fault_points/has_fault 语义变化行)
FORCE_REANALYZE=1 BATCH_SIZE=200 docker compose run --rm analyzer
# 或分批:设置 WATERMARK_ADD_TIME 从头跑
# Step 4: 验证
# - 查 bms_fault_points=0 但 bms_warning_points>0 的会话(原来 has_fault=1 的变化)
# - 查 has_board_out_of_control=1 的会话(新增失控标记)
# - 查 invalid_speed_points>0 的会话(新增超范围转速)
8.3 回滚方案
# 回滚代码到 v1.0.2
git checkout v1.0.2-tag && docker compose build && docker compose up -d
# 新列不影响旧代码(DEFAULT 值),无需 DROP
# 如需清空新列数据:
UPDATE surf_motion_trajectory_analysis
SET invalid_speed_points=0, has_board_out_of_control=0,
has_protocol_fault=0, has_warning=0,
fault_severity_display='none'
WHERE analyzer_version = '1.0.3';
9. 分阶段路线图
Phase 0(立即,P0,预计 1-2 天)
| 任务 | 文件 | 说明 |
|---|---|---|
ESC_EVENT_0x400000 改名 |
esc_faults.py |
ESC_FAULT_OVERVOLTAGE_PROTECTION → ESC_EVENT_0x400000 |
invalid_speed_points 计算 |
session_analyzer.py |
|motorSpeed| >= 20000,排除脏包 |
has_board_out_of_control 合成 |
session_analyzer.py |
三条 OR |
esc_event_0x400000_points + 双写 |
session_analyzer.py |
overvoltage 向后兼容 |
| 迁移 SQL P0 列 | sql/migrations/ |
4 个新列 |
| bump → 1.0.3 | session_analyzer.py |
触发重算 |
Phase 1(1~2 周,P1)
| 任务 | 文件 | 说明 |
|---|---|---|
| ESC 码表扩至 24 码 + severity dict | esc_faults.py |
参考第 6.1 节 |
| ECU 码表换用协议名 + severity | esc_faults.py |
6 码全覆盖 |
| BMS 码表扩至 22 码 + severity | esc_faults.py |
分三级 |
has_protocol_fault / has_warning |
session_analyzer.py |
见第 6.2 节 |
fault_severity_display |
session_analyzer.py |
展示最高级别 |
| BMS 细分三列 | session_analyzer.py + SQL |
notice/warning/critical |
| 故障明细表扩列 | repository.py + SQL |
severity_level、boc_related |
日聚合表扩列 + refresh_daily_stats 更新 |
repository.py + SQL |
4 个新聚合列 |
analysis/session_analyzer.py 同步 |
analysis/ |
与 tla 版本对齐 |
Phase 2(1 月内,P2)
| 任务 | 文件 | 说明 |
|---|---|---|
fault_catalog.yaml 实现 |
tla/fault_catalog.yaml |
见第 5 节 |
esc_faults.py 改为 YAML 加载 |
esc_faults.py |
热更新能力 |
| 告警规则 YAML | tla/alarm_rules.yaml |
阈值配置化 |
| 单元测试 | tests/ |
每条协议码覆盖 |
| 监控面板 SQL 视图 | sql/views/ |
报表/接口用 |
10. 各领域视角补充
10.1 产品经理视角
用户感知一致性原则:后台「故障会话」必须与 App 红色弹窗体验一致。当前 App 用 backIdx 明确区分提醒/告警/故障,后台分析应 1:1 映射。
可量化的 KPI:
- 「板体失控率」= has_board_out_of_control 会话数 / 总会话数,按固件版本分组
- 「纯告警会话」= has_warning AND NOT has_fault,监控是否因低电量引起大量误报
- 「故障转化率」= 同一设备 SN 首次 has_protocol_fault 后 7 天内是否报修
决策建议:每次固件发版前,比对新旧版本的 session_board_out_of_control 日率,作为发版 Go/No-Go 依据之一。
10.2 嵌入式工程师视角
关键对齐点:
1. esc_event = (running_error << 16) | selfcheck_error — 这个编码公式是分析正确性的根基,分析器需严格对齐。
2. feature_motorstuck 固件中 ECU 将 |speed| >= 20000 置到 running_error bit6(0x400000),而非 ESC 固件 bit1(0x20000)。两个固件分支并存时会看到不同的码,分析器必须两条都检测。
3. 转速单位:CAN 协议 0.1 RPM,20000 = 2000 RPM,在分析日志中 motorSpeed 的原始值与此一致,无需换算。
4. MAVLink EventCodeProcessByBit 每 bit 间隔约 12s 发一次,轨迹点事件码不是每点必有,分析时应用累计而非瞬时判断。
建议:在 fault_catalog.yaml 的 notes 字段标注每个码的固件来源文件和函数,便于固件升级时的影响面评估。
10.3 软件架构视角
当前架构优点(保留): - 无状态 cron + 幂等 UPSERT,可随时重跑 - 指纹 + 版本跳过逻辑,避免重复计算 - job 表水位,支持断点续跑
改进点:
1. 配置与代码解耦:P2 阶段 fault_catalog.yaml 外置后,新增故障码无需重新部署,只需 FORCE_REANALYZE=1 重跑即可
2. 版本语义化:ANALYZER_VERSION 应遵循语义版本(major.minor.patch),major bump = schema breaking change,minor = 新字段,patch = bug fix
3. 错误隔离:当前 upsert_failed 在主流程异常时调用,建议增加重试 DLQ(Dead Letter Queue)机制,避免单条 OSS 下载失败阻塞整批
10.4 系统架构视角
数据流全貌:
固件 (ECU/ESC/BMS)
→ MAVLink 事件 (111)
→ RC App 采样 (HomeFragment, 定时)
→ SailingRecordItem (本地 SQLite)
→ OSS JSON 上传
→ surf_motion_trajectory_history (MySQL)
→ TLA 分析 (cron)
→ surf_motion_trajectory_analysis (MySQL)
→ 报表/接口
瓶颈与风险:
- OSS JSON 下载无并发(顺序处理),批量大时延迟高 → 建议 P2 阶段引入 concurrent.futures.ThreadPoolExecutor 并发下载,IO 密集型适合线程池
- MySQL 分析表无分区,随数据量增长单表扫描变慢 → 建议 session_date 分区(按月)或建专用只读副本供报表
- 单进程 cron 无监控 → 建议暴露 Prometheus metrics 或写日志到可观测平台
10.5 C/固件工程师视角
UpdateESCErrorCodeByRunningStatus 编码行为(esc_manager.c)需与分析对齐的细节:
running_error由 ESC 固件上报,ECU 可能 覆盖 某些位(motorstuck 分支 bit6)- 分析器检测
0x400000时无法区分「真过压」vs「ECU 合成」,只能通过以下辅助信号判断: - 同时
|motorSpeed| >= 20000→ 大概率是 ECU 合成 electricCurrent极低(近 0)且motorSpeed极高 → 可能是真过压ESC_FAULT_MASK(ECU 上报前屏蔽掉SW_HW_INCOMPATIBLE、BOOTLOADER_UNSUPPORTED等)导致这些码在日志里极少出现,分析器覆盖即可,不必为其设告警阈值
10.6 C++ 工程师视角(MAVLink 协议层)
- MAVLink 码
uint32_t,Java/Python 侧注意 符号扩展:0x80000000在 Javaint中是负数,BmsFaultMask 用long规避;Pythonint无限精度无此问题,但& 0xFFFFFFFF时需注意 bms_event字段来自msg_deviceeventnotice,RC App 做等值比较(不是位与),意味着 BMS 每次上报是单一事件码(非组合掩码);ESCesc_event是合成掩码,可多 bit 同时置位 — 分析器对 BMS 用等值或位与均可,但需确认实际上报行为
10.7 硬件工程师视角
传感器链路影响分析:
- D4A081xx 脏包是 CAN 总线 bit error 或 UART framing 错误导致,与电气质量相关;高频出现说明 PCB 走线/屏蔽/接地有问题
- |motorSpeed| >= 20000 超范围既可能是 ESC 霍尔传感器故障,也可能是 CAN 帧解码错误(降频 10:1 过程中)
- 建议:在故障明细表中增加 hardware_suspect 标注,将 D4A081 + 超范围转速合并为「硬件/链路异常」维度,供硬件工程师排查
10.8 数据工程师视角
SQL 视图建议(报表层):
-- 板体失控监控视图(按固件版本分组)
CREATE OR REPLACE VIEW v_board_out_of_control_by_version AS
SELECT
session_date,
esc_version, ecu_version, bms_version,
COUNT(*) AS total_sessions,
SUM(has_board_out_of_control) AS boc_sessions,
ROUND(AVG(has_board_out_of_control)*100, 2) AS boc_rate_pct,
SUM(stall_points) AS stall_pts_total,
SUM(invalid_speed_points) AS invalid_spd_total,
SUM(esc_event_0x400000_points) AS esc_0x400000_total
FROM surf_motion_trajectory_analysis
WHERE analyze_status = 'done'
GROUP BY session_date, esc_version, ecu_version, bms_version;
-- 故障分级分布视图
CREATE OR REPLACE VIEW v_fault_severity_dist AS
SELECT
session_date,
fault_severity_display,
COUNT(*) AS cnt
FROM surf_motion_trajectory_analysis
WHERE analyze_status = 'done'
GROUP BY session_date, fault_severity_display;
-- 设备健康度视图(按遥控器 SN)
CREATE OR REPLACE VIEW v_device_health AS
SELECT
remote_sn,
COUNT(*) AS total_sessions,
SUM(has_board_out_of_control) AS boc_count,
SUM(has_protocol_fault) AS fault_count,
MAX(session_date) AS last_session_date,
MAX(esc_version) AS latest_esc_version
FROM surf_motion_trajectory_analysis
WHERE analyze_status = 'done'
GROUP BY remote_sn;
数据质量监控(建议纳入 cron 告警):
-- 异常重算比例过高时预警
SELECT COUNT(*) AS reanalyzed
FROM surf_motion_trajectory_analysis
WHERE analyzer_version = '1.0.3'
AND analyzed_at > NOW() - INTERVAL 1 HOUR;
-- 失败率监控
SELECT
SUM(sessions_failed) / SUM(sessions_scanned) AS fail_rate
FROM surf_log_analysis_job
WHERE started_at > NOW() - INTERVAL 1 DAY;
10.9 全栈架构视角
下游接口影响(如后台 API 消费分析表):
| 接口字段 | v1.0.2 语义 | v1.0.3 变化 | 前端适配建议 |
|---|---|---|---|
has_fault |
宽 | 收口 | 原来「故障」列表会变短,需告知前端 |
severity |
自研分 | 不变 | 不影响 |
fault_severity_display |
无 | 新增 | 推荐用此字段驱动 UI 色标 |
has_board_out_of_control |
无 | 新增 | 新增「失控会话」筛选入口 |
overvoltage_points |
0x400000 | 同值双写 | 无需改 |
bms_fault_points |
全 BMS 之和 | 仅故障级 | ⚠️ 破坏性,前端数值会降低 |
建议:后台 API 在 v1.0.3 发版后增加版本字段返回 analyzer_version,前端按版本渲染说明文案。
11. 待研发确认项
| # | 问题 | 影响范围 | 优先级 |
|---|---|---|---|
| A | 0x400000 语义:真过压 vs ECU 合成 vs 协议跌落位?固件是否计划统一? |
ESC_EVENT_0x400000 命名、board_out_of_control 纳入是否正确 |
P0 |
| B | |motorSpeed| >= 20000 阈值是否在 master 固件与 motorstuck 分支一致?其他固件版本是否相同? |
invalid_speed_points 准确性 |
P0 |
| C | running_error bit6 在 motorstuck 分支是否已计划修复(映射到正确的 bit1)? |
如修复,0x400000 在新固件不再出现,无需 board_out_of_control |
P1 |
| D | BMS bms_event 是单一事件码(等值)还是组合掩码(位与)?RC App 用等值比较,但日志里多 bit 同时置位的情况是否存在? |
BMS 码匹配方式 | P1 |
| E | 超速告警 是否在 escEventCode 中有对应 bit?还是仅靠 motorSpeed 阈值检测? |
告警分级完整性 | P2 |
| F | FAULT_BOARD_ATTITUDE (0x04000000) 协议候选 tilt_fault,是否等同于「倾斜故障」?还是仅指航行姿态判断? |
ECU 故障展示文案 | P2 |
12. 变更记录
| 版本 | 日期 | 说明 |
|---|---|---|
| v1.0 | 2026-05-31 | 原改进方案(LOG_ANALYSIS_IMPROVEMENT_PLAN_PROTOCOL.md) |
| v2.0 | 2026-06-01 | 基于故障码分级表 v1.0,多领域视角完整方案;Schema v2、码表重设计、迁移策略 |