diff --git a/docs/devlog.md b/docs/devlog.md index 1085fbd..29ecfd3 100644 --- a/docs/devlog.md +++ b/docs/devlog.md @@ -4,6 +4,43 @@ --- +## 2026-09-01 — 方案A 现场复核修正:RELEASE_ALFA 18→21 + 进入 snap(固件 V4.04) + +> **固件版本:V4.04**(cmcng.h:FIRMWARE_VER="4.04" + MAIN=4/SUB=4)。devlog 修订 V2.13。 + +### 背景(现场复核) + +方案A(V4.03)落地后金属板复测,两个现象: + +1. **慢速抬板释放高度 V4B 仍比 PD132T 高一点**,且跟手速有关(抬得越慢越接近) +2. **定在 HR0/2(释放高度一半)保持 ~1s,V4B 释放继电器,PD132T 不释放** + +### 根因分析 + +| 现象 | 根因 | 证据 | +|------|------|------| +| 1 释放偏高 | τ 对齐用了近似口径:方案A α18 精确 τ≈137ms,PD132T α79@43.7ms 精确 τ≈118ms(α=79 时 `T×256/α` 近似公式高估 19.6%)+ V4B 释放 3 次确认 30ms | 仿真:2s 抬升 V4B +14mm、8s 抬升 +2mm,与现场"跟手速有关"吻合 | +| 2 HR0/2 假释放 | 双滤波结构(快进+慢出):进入由快滤波(τ≈22ms)30ms 确认,释放判定用慢滤波——进入确认瞬间慢滤波还悬在基线附近,残余信号落在窄带(SENS=3 时 0.032%~0.044%)时释放条件瞬时为真 → 3 次确认数满 → 假释放。PD132T 进出共用同一滤波,进入确认时滤波值已沉过离开线,结构性免疫 | 仿真:0.10% 板 HR0/2 放置 V4B 释放@0.18s,PD132T 不释放 | + +### 修正(V4.04) + +1. **RELEASE_ALFA 18 → 21**:精确 τ = −T/ln(1−α) = −10/ln(1−21/256) ≈ **117ms**,对齐 PD132T α79@43.7ms 精确 τ≈118ms。仿真释放高度差 3s 抬升 +9mm → **+3mm**(剩余为 3 次确认 30ms 固有延迟) +2. **进入确认 snap**:`loop1_CAPVD_slow = loop1_CAPVD`(进入线档3 0.032% 恒深于离开线 0.021%,snap 后释放条件结构性为假)→ HR0/2 假释放窗口彻底消除 + +### 验证 + +- `tests/test_release_slow_filter.c` 更新 ALFA_SLOW=21:τ fast=30ms/slow=120ms(理论 22/117ms);释放时机差 200ms ✓ +- 仿真(Origin=100000, SENS=3):α21+snap 下 0.10% 板 HR0/2 放置,原版释放@0.18s → 未释放 ✓ +- ⚠ 待板级:真机金属板复测确认释放高度对齐 + HR0/2 保持不再释放 + +### 文档同步 + +- technical-spec §4.3.3 补 V4.04 修正说明 +- analysis/docs/filter-coefficient-79-vs-64.md §4.4 方案A 同步 α21 + snap +- release-notes 待发布时更新 + +--- + ## 2026-08-31 — 释放手感对齐 PD132T:释放慢滤波(方案 A,固件 V4.03) > **固件版本:V4.03**(cmcng.h:FIRMWARE_VER="4.03" + MAIN=4/SUB=3;⚠ 顺带修正字符串 "4.00" 与数字 4/2 不一致的历史问题)。devlog 修订 V2.12。 diff --git a/docs/technical-spec.md b/docs/technical-spec.md index 3f1dd43..7d30ef2 100644 --- a/docs/technical-spec.md +++ b/docs/technical-spec.md @@ -276,6 +276,8 @@ if ((Origin - dlt_ORG) < CAPVD) { // CAPVD 回升至距基线不 > **⚠ V4.03(2026-08-31)释放慢滤波(方案 A,USE_SLOW_RELEASE)**:现场金属板测试——灵敏度表已对齐,但**释放高度 V4B 比 PD132T 低**(V4B 刚离开触发位置即释放,PD132T 需离得更远)。根因:**IIR 滤波时间常数差异**(V4B 10ms tick + α79 → τ≈32ms;PD132T 43.7ms tick + α79/64 → τ≈142~175ms,慢 4.4~5.5×),释放阈值浅(进入的 20%)放大差异。修复:离开判定改用**独立慢滤波值** `loop1_CAPVD_slow`(α=18/256 @10ms → τ≈142ms,复刻 PD132T 恢复速度,吃原始 Value 不经斜率限幅),进入路径不变。开关 `USE_SLOW_RELEASE`(TaskLoop.h,默认 1;0=原快滤波释放)。单测:τ fast=30ms/slow=140ms,释放时机差 260ms(`tests/test_release_slow_filter.c`)。⚠ 若现场 PD132T 的 SET_FLT=ON(α64 → τ≈175ms),可调 `RELEASE_ALFA` 15(τ≈170ms)更贴近。 +> **⚠ V4.04(2026-09-01)方案A 现场复核修正(RELEASE_ALFA 18→21 + 进入 snap)**:金属板复测两现象——① 慢速抬板释放高度 V4B 仍比 PD132T 高一点(跟手速有关);② 定在 HR0/2(释放高度一半)保持 ~1s V4B 释放、PD132T 不释放。根因:① **τ 对齐用了近似口径**——α18 精确 τ≈137ms vs PD132T α79@43.7ms 精确 τ≈118ms(α=79 时 `T×256/α` 近似公式高估 19.6%),叠加 3 次确认 30ms;② **双滤波进入瞬态假释放**——进入由快滤波 30ms 确认、释放判定用慢滤波,进入确认瞬间慢滤波还悬在基线附近,残余信号落在窄带(SENS=3 时 0.032%~0.044%)时释放条件瞬时为真 → 假释放;PD132T 进出共用同一滤波,结构性免疫。修正:① `RELEASE_ALFA` 18→**21**(精确 τ≈117ms 对齐 PD132T 118ms);② 进入确认处 **snap `loop1_CAPVD_slow = loop1_CAPVD`**(进入线 0.032% 恒深于离开线 0.021%,snap 后释放条件结构性为假)。单测:τ fast=30ms/slow=120ms,释放时机差 200ms;仿真 3s 抬升高度差 +9mm→+3mm,0.10% 板 HR0/2 假释放消除。⚠ 待板级复测。 + ##### 模式 2:平坦性判定 (USE_FLATNESS_EXIT=1) — ⚠ 默认禁用(#if 0,代码保留) 基于专利 **CN200910309382**(中山大学),解决大车通行时频率多峰导致的多次误触发。 diff --git a/tests/test_release_slow_filter.c b/tests/test_release_slow_filter.c index 64451ea..5f765e2 100644 --- a/tests/test_release_slow_filter.c +++ b/tests/test_release_slow_filter.c @@ -1,9 +1,9 @@ /* * test_release_slow_filter.c — 方案A 释放慢滤波单测 * - * 验证: V4B 主滤波(ALFA=79 @10ms, τ≈32ms) vs 释放慢滤波(ALFA=18 @10ms, τ≈142ms) + * 验证: V4B 主滤波(ALFA=79 @10ms, τ≈22ms) vs 释放慢滤波(ALFA=21 @10ms, 精确τ≈117ms) * 在"金属板离开"(信号缓慢恢复)场景下,慢滤波释放时机应显著晚于快滤波, - * 从而对齐 PD132T 释放手感。 + * 从而对齐 PD132T 释放手感 (PD132T α79@43.7ms 精确τ≈118ms, V4.04 对齐)。 * * 编译: gcc -o /tmp/test_release_slow test_release_slow_filter.c && /tmp/test_release_slow */ @@ -13,7 +13,7 @@ #include #define ALFA_FAST 79 -#define ALFA_SLOW 18 +#define ALFA_SLOW 21 #define TICK_MS 10 /* 与 TaskLoop.c get_flt_value 同构 */ @@ -37,7 +37,7 @@ static void test_tau(void) if (t_fast < 0 && v_fast <= target_fast) t_fast = t; if (t_slow < 0 && v_slow <= target_slow) t_slow = t; } - printf("[tau] fast=%dms slow=%dms (理论 32ms/142ms)\n", t_fast * TICK_MS, t_slow * TICK_MS); + printf("[tau] fast=%dms slow=%dms (理论 22ms/117ms)\n", t_fast * TICK_MS, t_slow * TICK_MS); assert(t_fast * TICK_MS <= 60); /* 快滤波 τ < 60ms */ assert(t_slow * TICK_MS >= 100); /* 慢滤波 τ > 100ms */ assert(t_slow > t_fast * 3); /* 慢/快 > 3× */ diff --git a/utilities/at32f421_freertos_demo/inc/TaskLoop.h b/utilities/at32f421_freertos_demo/inc/TaskLoop.h index fc4abd6..6a6f1ad 100644 --- a/utilities/at32f421_freertos_demo/inc/TaskLoop.h +++ b/utilities/at32f421_freertos_demo/inc/TaskLoop.h @@ -35,7 +35,7 @@ * - 进入确认 (ENTRY_CONFIRM) 替代单次阈值判定 *===========================================================================*/ #define ALFA_CAP1 79 // IIR α = 79/256 ≈ 0.31 (@10ms → τ≈32ms) -#define RELEASE_ALFA 18 // 释放慢滤波 α = 18/256 ≈ 0.07 (@10ms → τ≈142ms, 方案A: 对齐 PD132T Flt_Reg=79 @43.7ms 释放手感) +#define RELEASE_ALFA 21 // 释放慢滤波 α = 21/256 ≈ 0.082 (@10ms → 精确τ≈117ms, V4.04: 对齐 PD132T α79@43.7ms 精确τ≈118ms; 原18→精确τ137ms偏慢) #define USE_SLOW_RELEASE 1 // 方案A总开关: 1=释放走慢滤波(对齐PD132T) 0=原快滤波释放 #define MAX_SLOPE_RATE 5 // 斜率限幅: 单次最大变化 5% (物理限制, 拒绝 EMI 尖峰) #define ENTRY_CONFIRM 3 // 进入确认: 连续 N 次低于阈值才判定有车 @@ -89,7 +89,7 @@ extern uint16_t loop1_CapCnt; // 当前窗口已累加次数 extern uint32_t loop1_CapSum; // 当前窗口累加和 extern uint32_t loop1_Value; // 一个测量窗口的原始 ΣXn extern uint32_t loop1_CAPVD; // IIR 滤波后的频率值 -extern uint32_t loop1_CAPVD_slow; // 释放判定慢滤波值 (方案A: 独立 IIR, τ≈142ms, 对齐 PD132T 释放手感) +extern uint32_t loop1_CAPVD_slow; // 释放判定慢滤波值 (方案A: 独立 IIR, 精确τ≈117ms, 对齐 PD132T 释放手感) extern uint32_t loop1_Origin; // 基线(无车时的参考频率) extern uint32_t loop1_ORG_SUM; // 基线跟踪累加和 extern uint16_t loop1_ORG_CNT; // 基线跟踪计数(窗口=100) diff --git a/utilities/at32f421_freertos_demo/inc/cmcng.h b/utilities/at32f421_freertos_demo/inc/cmcng.h index 25e6c24..8854a29 100644 --- a/utilities/at32f421_freertos_demo/inc/cmcng.h +++ b/utilities/at32f421_freertos_demo/inc/cmcng.h @@ -14,10 +14,10 @@ #define __CMCNG_H__ #define PRODUCT_MODEL "DLD154" -#define FIRMWARE_VER "4.03" +#define FIRMWARE_VER "4.04" #define HARDWARE_VER "3.00" #define FIRMWARE_VER_MAIN 4 -#define FIRMWARE_VER_SUB 3 +#define FIRMWARE_VER_SUB 4 #define HARDWARE_VER_MAIN 3 #define HARDWARE_VER_SUB 0 diff --git a/utilities/at32f421_freertos_demo/src/TaskLoop.c b/utilities/at32f421_freertos_demo/src/TaskLoop.c index c0546d2..927ac95 100644 --- a/utilities/at32f421_freertos_demo/src/TaskLoop.c +++ b/utilities/at32f421_freertos_demo/src/TaskLoop.c @@ -783,6 +783,12 @@ void vd1_task(void) loop1_entry_cnt = 0; loop1_freeze_cnt = 0; loop1_freeze_ref = 0; +#if USE_SLOW_RELEASE + /* V4.04: 进入瞬态假释放修正 — snap 慢滤波到当前快滤波值 + * 进入线(档3: 0.032%)恒深于离开线(0.021%), snap 后释放条件结构性为假, + * 消除"定在HR0/2保持即释放"窗口(2026-09-01 仿真+现场复核) */ + loop1_CAPVD_slow = loop1_CAPVD; +#endif if (!SET_SAFE) { loop1_LC_HOLD = 1;