From 7983bfd72d1f28218c14dc3abe6c0e2ffa0b33b3 Mon Sep 17 00:00:00 2001 From: wangfq Date: Thu, 3 Sep 2026 16:16:37 +0800 Subject: [PATCH] =?UTF-8?q?feat(V4B):=20V4.31=20=E2=80=94=20=E6=95=85?= =?UTF-8?q?=E9=9A=9C=E8=A1=A5=E5=81=BF=E6=97=B6=E5=BA=8F=E5=86=8D=E8=B0=83?= =?UTF-8?q?:=20=E9=A2=84=E5=88=A42s=20+=20=E8=A1=A5=E5=81=BF7s=20(?= =?UTF-8?q?=E6=80=BB=E6=81=A2=E5=A4=8D=20~15s)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit V4.30 基础上现场手感再收紧: ENV_WARN_WAIT 300→200(2s); ENV_RESYNC_WAIT 800→700(7s); 恢复确认 200(2s) 不变 时序: 2s 黄灯预判锁存 → 7s 进入学习 → 6s 学完原子替换 → 2s 确认灭 test_env_resync.c 同步 → 5 场景 ALL PASS (warn@200, applied@1300, 灭@1500) 文档: devlog V2.29 / spec V2.10 / design doc v0.8 --- docs/coil-range-alarm-design.md | 1 + docs/devlog.md | 28 +++++++++++++++ docs/technical-spec.md | 11 +++--- tests/test_env_resync.c | 36 +++++++++---------- .../at32f421_freertos_demo/inc/TaskLoop.h | 4 +-- utilities/at32f421_freertos_demo/inc/cmcng.h | 4 +-- .../at32f421_freertos_demo/src/TaskLoop.c | 4 +-- 7 files changed, 59 insertions(+), 29 deletions(-) diff --git a/docs/coil-range-alarm-design.md b/docs/coil-range-alarm-design.md index 3abf158..c567202 100644 --- a/docs/coil-range-alarm-design.md +++ b/docs/coil-range-alarm-design.md @@ -14,6 +14,7 @@ | v0.5 | 2026-09-03 | **L 估算标定(V4.28)**:五组 LCR 实测反推振荡回路等效谐振电容 C_eff=41.3~45.5nF(均值 43),与名义 66nF 明显不符 → 固件改标定值 COIL_CAL_C_NF=43(L_uH=2.533e7/(f²×C_eff));COIL_DEF_C_NF 保留为名义口径。残差 ±6% 内,待多线圈/标定电感进一步收口 | | v0.6 | 2026-09-03 | **硬件修复后定稿(V4.29)**:拨码三极管 5.1K→0Ω → 低频档并联全导通,C_eff=68.1~68.9(均值 68.4)≈名义 66。v0.5 的 43 为 5.1K 旧板带病特性(开关未饱和),**作废**;COIL_CAL_C_NF 43→68,残差 ≤1.5%。33nF 档标定 34(旧板数据)待 0Ω 板复测 | | v0.7 | 2026-09-03 | **故障补偿时序(V4.30)**:预判 3s(ENV_WARN_WAIT 300)→ 补偿 8s(ENV_RESYNC_WAIT 800)→ 学习 3×2s → 替换后空闲 2s 恢复确认(ENV_RECOVER_WAIT 200)黄灯灭;总恢复 ~16s | +| v0.8 | 2026-09-03 | **故障补偿时序再调(V4.31)**:预判 2s(ENV_WARN_WAIT 200)→ 补偿 7s(ENV_RESYNC_WAIT 700)→ 学习 3×2s → 替换后空闲 2s 恢复确认黄灯灭;总恢复 ~15s | ## 1. 背景 diff --git a/docs/devlog.md b/docs/devlog.md index 8859039..649f4f2 100644 --- a/docs/devlog.md +++ b/docs/devlog.md @@ -4,6 +4,33 @@ --- +## 2026-09-03 — 故障补偿时序再调:预判2s + 补偿7s(固件 V4.31) + +> **固件版本:V4.31**(cmcng.h:FIRMWARE_VER="4.31" + MAIN=4/SUB=31)。devlog 修订 V2.29。 + +### 拍板规格(2026-09-03,V4.30 基础上现场手感再收紧) + +1. **黄灯预判 3s → 2s**(ENV_WARN_WAIT 300→200):高位持续 2s 黄灯预判锁存常亮 +2. **故障补偿 8s → 7s**(ENV_RESYNC_WAIT 800→700):累计 7s 高位进入基线学习 +3. 恢复确认保持 **2s**(ENV_RECOVER_WAIT 200 不变) + +时序:2s 黄灯亮 → 7s 触发学习 → 6s(3×200tick)学完替换 → 2s 确认灭;总恢复 **~15s** + +### 验证(test_env_resync.c 同步,5 场景 ALL PASS) + +| 场景 | 期望 | 实测 | +|------|------|------| +| 永久变化 | warn@200 / applied@~1300 / 替换后 200tick 灭 | warn_at=200 ✓ applied_at=1300 ✓ 灭 ✓ | +| 瞬态 6s(<7s) | 锁存不学, 空闲 2s 灭 | ✓ | +| 学习期压线 | 搁置不退出 → 学完替换 | ✓ (applied_at=1301) | +| 不稳学习 | 预算放弃, 不污染 | abort ✓ Origin 不变 ✓ | +| 替换后稳态 | 无重复学习 | ✓ | + +### 待现场验证 + +- A 拿走:~2s 黄灯亮 → ~13s 基线切 B → ~15s 黄灯灭 +- 补偿触发提前到 7s:持续 7~10s 强磁干扰会触发学习(原 10s/8s 边界继续提前)——黄灯 2s 预警先亮 + ## 2026-09-03 — 故障补偿时序调整:预判3s + 补偿8s + 恢复2s(固件 V4.30) > **固件版本:V4.30**(cmcng.h:FIRMWARE_VER="4.30" + MAIN=4/SUB=30)。devlog 修订 V2.28。 @@ -1263,6 +1290,7 @@ if (dev >= dlt_ORG × 4) { | 版本 | 时间 | 说明 | |------|------|------| +| V2.29 | 2026-09-03 | V4.31 故障补偿时序再调: 预判2s(200)/补偿7s(700)/恢复2s, 总 ~15s | | V2.28 | 2026-09-03 | V4.30 故障补偿时序: 预判3s(300)/补偿8s(800)/恢复2s(200), 总 ~16s | | V2.27 | 2026-09-03 | V4.29 硬件修复(拨码三极管5.1K→0Ω)后 C_eff=68.1~68.9nF≈名义66, COIL_CAL_C_NF 43→68 (旧43为5.1K带病特性作废) | | V2.26 | 2026-09-03 | V4.28 电感量估算引入标定 COIL_CAL_C_NF=43(名义 66nF vs 实测 C_eff≈43,5 组反推 41.3~45.5nF);残差 ±6% | diff --git a/docs/technical-spec.md b/docs/technical-spec.md index 10f6e5b..365dae7 100644 --- a/docs/technical-spec.md +++ b/docs/technical-spec.md @@ -1,6 +1,6 @@ # DLD154V4B 技术规格书 -> 单路线圈车辆检测器 | 固件版本: V4.30 | 文档版本: V2.9 +> 单路线圈车辆检测器 | 固件版本: V4.31 | 文档版本: V2.10 > 本文档面向工程开发、系统集成及故障深度分析 --- @@ -365,7 +365,7 @@ if (!VD_FLAG) { | 4× 冻结阈值 | 防止异常 CAPVD 上升污染基线(V1.5) | | 5% 斜率限幅 | 过滤 EMI/闪电尖峰,保护 IIR(V2.0) | | 冻结超时 + 稳定性检查 | 防止永久冻结死锁(V2.3~2.5) | -| 环境重校准(V4.24/26/30) | dev>+4×dlt 高位连续 8s(ENV_RESYNC_WAIT,V4.26 60s→10s,V4.30→8s)→ 判定永久环境变化 → 学习基线 B(空闲窗均值+判稳,黄灯常亮)→ 原子替换 Origin;铁块类瞬态 8s 内仍只冻结不污染 | +| 环境重校准(V4.24/26/30/31) | dev>+4×dlt 高位连续 7s(ENV_RESYNC_WAIT,V4.26 60s→10s,V4.30→8s,V4.31→7s)→ 判定永久环境变化 → 学习基线 B(空闲窗均值+判稳,黄灯常亮)→ 原子替换 Origin;铁块类瞬态 7s 内仍只冻结不污染 | #### 4.4.3 基线更新速率(两阶段) @@ -450,9 +450,9 @@ if (dev < dlt_ORG * 4) { | STABLE_SETTLE_WINDOWS | 2 | ~2 s | 连续窗口漂移达标数 | | STABLE_MAX_SAMPLES | 500 tick | **~5 s** | 自检硬兜底上限(超时强制判稳) | | FREEZE_TIMEOUT | 1000 | **~10 s** | 基线冻结超时(连续稳定后更新 Origin) | -| ENV_WARN_WAIT | 300 tick | **~3 s** | 环境预判锁存(V4.30):dev>+4×dlt 高位连续 3s → 黄灯常亮预判(锁存) | -| ENV_RECOVER_WAIT | 200 tick | ~2 s | 恢复确认(V4.30):新基线替换后 环境空闲连续 2s 才解除预判锁存、黄灯灭(回摆/目标靠近保持常亮) | -| ENV_RESYNC_WAIT | 800 tick | **~8 s** | 环境重校准等待:dev>+4×dlt 高位连续 8s 判定永久环境变化(V4.30 拍板:60s→10s→8s) | +| ENV_WARN_WAIT | 200 tick | **~2 s** | 环境预判锁存(V4.31):dev>+4×dlt 高位连续 2s → 黄灯常亮预判(锁存) | +| ENV_RECOVER_WAIT | 200 tick | ~2 s | 恢复确认(V4.31):新基线替换后 环境空闲连续 2s 才解除预判锁存、黄灯灭(回摆/目标靠近保持常亮) | +| ENV_RESYNC_WAIT | 700 tick | **~7 s** | 环境重校准等待:dev>+4×dlt 高位连续 7s 判定永久环境变化(V4.31 拍板:60s→10s→8s→7s) | | ENV_LEARN_WINDOW | 200 tick | ~2 s | 环境学习窗口(基线 B 均值窗,学习期黄灯常亮) | | ENV_LEARN_MAX_TICKS | 3000 tick | **~30 s** | 学习预算:窗口不稳超时放弃,保留旧 Origin(防死锁) | | COIL_F_OK_MIN_KHZ | 20 kHz | — | 线圈频率合理窗下界(V4.26):默认低频档口径,f<20kHz → L偏大告警 | @@ -775,3 +775,4 @@ DLD154V4B V1.4 起实现该专利的整数化版本,用于大车通行时的 | V2.7 | 2026-09-03 | 更新至 V4.28:L 估算引入标定等效谐振电容 COIL_CAL_C_NF=43(名义 66nF 与实测 C_eff≈43 不符;5 组实测 41.3~45.5nF) | | V2.8 | 2026-09-03 | 更新至 V4.29:硬件修复(拨码三极管 5.1K→0Ω)使低频档并联全导通,C_eff 43→68.4≈名义66;COIL_CAL_C_NF 43→68 | | V2.9 | 2026-09-03 | 更新至 V4.30:故障补偿时序 预判 5s→3s(300)/补偿 10s→8s(800)/恢复确认 5s→2s(200),总恢复 ~16s | +| V2.10 | 2026-09-03 | 更新至 V4.31:预判 3s→2s(200)/补偿 8s→7s(700),总恢复 ~16s→~15s | diff --git a/tests/test_env_resync.c b/tests/test_env_resync.c index 186b140..e58f0d6 100644 --- a/tests/test_env_resync.c +++ b/tests/test_env_resync.c @@ -1,13 +1,13 @@ /* - * test_env_resync.c — 环境重校准(受控基线更新) gcc 隔离单测 (DLD154V4B V4.30) + * test_env_resync.c — 环境重校准(受控基线更新) gcc 隔离单测 (DLD154V4B V4.31) * - * 镜像 = TaskLoop.c vd1_task() 无车段 dev>0 分支 (V4.24/25/26/30), 逻辑与固件一致: + * 镜像 = TaskLoop.c vd1_task() 无车段 dev>0 分支 (V4.24/25/26/30/31), 逻辑与固件一致: * - 高位 dev>+4dlt: 等待确认(g_env_wait_cnt) → 满 ENV_WARN_WAIT 预判锁存 g_env_warn * - 满 ENV_RESYNC_WAIT → 进入学习 g_env_resync(高位段才计数; 压线/回摆=搁置) * - 学习: 200 样本/窗, 窗均值漂移 ≤0.1% 连续 2 窗 → env_resync_apply 原子替换 * - 预算 ENV_LEARN_MAX_TICKS 超时 → abort 不污染 * - 非高位空闲 dev>-dlt 连续 ENV_RECOVER_WAIT → 清 g_env_warn (黄灯灭) - * V4.30 拍板: 预判 3s + 补偿 8s + 替换后空闲 2s 灭 + * V4.31 拍板: 预判 2s + 补偿 7s + 替换后空闲 2s 灭 * 镜像宏与固件一致(改 ENV_* 时同步此处!) */ #include @@ -17,9 +17,9 @@ #include /* ===== 镜像固件宏 (TaskLoop.c/TaskLoop.h 同步) ===== */ -#define ENV_WARN_WAIT 300 /* V4.30: 预判 3s */ +#define ENV_WARN_WAIT 200 /* V4.31: 预判 2s */ #define ENV_RECOVER_WAIT 200 /* V4.30: 替换后空闲 2s 恢复确认 */ -#define ENV_RESYNC_WAIT 800 /* V4.30: 补偿(学习等待) 8s */ +#define ENV_RESYNC_WAIT 700 /* V4.31: 补偿(学习等待) 7s */ #define ENV_LEARN_WINDOW 200 #define ENV_LEARN_MAX_TICKS 3000 #define STABLE_ORIGIN_PPT 1 @@ -164,7 +164,7 @@ static void reset_all(void) sim_tick_cnt = 0; } -/* ===== 场景 1: 永久变化 (A 拿走) — 3s 预判 → 8s 触发 → 3窗学完 ~14s 替换 → +2s 灭 ===== */ +/* ===== 场景 1: 永久变化 (A 拿走) — 2s 预判 → 7s 触发 → 3窗学完 ~13s 替换 → +2s 灭 ===== */ static void test_permanent_change_recovers(void) { int tick, warn_at = 0; @@ -179,9 +179,9 @@ static void test_permanent_change_recovers(void) if (sim_applied_cnt) break; } - printf("1. 永久变化: warn_at=%d learn_start=%d applied_at=%d Origin=%u (期望 300 / 1 / ~1400 / 128856)\n", + printf("1. 永久变化: warn_at=%d learn_start=%d applied_at=%d Origin=%u (期望 200 / 1 / ~1300 / 128856)\n", warn_at, sim_learn_start_cnt, (int)sim_tick_cnt, sim_Origin); - assert(warn_at == 300); + assert(warn_at == 200); assert(sim_learn_start_cnt == 1); assert(sim_applied_cnt == 1); assert(sim_Origin == 128856UL); @@ -204,11 +204,11 @@ static void test_transient_keeps_warn(void) int loop; reset_all(); - for (loop = 0; loop < 700; loop++) { /* 7s 高位 */ + for (loop = 0; loop < 600; loop++) { /* 6s 高位 */ sim_CAPVD = 128856UL; sim_tick(); } - printf("2. 瞬态 7s 高位: warn=%d learn=%d (期望 1 / 0)\n", g_env_warn, sim_learn_start_cnt); + printf("2. 瞬态 6s 高位: warn=%d learn=%d (期望 1 / 0)\n", g_env_warn, sim_learn_start_cnt); assert(env_warn_active() == 1); assert(sim_learn_start_cnt == 0); @@ -226,14 +226,14 @@ static void test_transient_keeps_warn(void) assert(g_env_warn == 0); assert(sim_learn_start_cnt == 0); - for (loop = 0; loop < 700; loop++) { /* 再 7s 高位 → 重新锁存, 仍不学 */ + for (loop = 0; loop < 600; loop++) { /* 再 6s 高位 → 重新锁存, 仍不学 */ sim_CAPVD = 128856UL; sim_tick(); } - printf(" 二次 7s 高位: warn=%d learn=%d (期望 1 / 0)\n", g_env_warn, sim_learn_start_cnt); + printf(" 二次 6s 高位: warn=%d learn=%d (期望 1 / 0)\n", g_env_warn, sim_learn_start_cnt); assert(g_env_warn == 1); assert(sim_learn_start_cnt == 0); - printf("2. 瞬态高位(<8s)不学, 锁存保持, 恢复确认后灭 OK\n"); + printf("2. 瞬态高位(<7s)不学, 锁存保持, 恢复确认后灭 OK\n"); } /* ===== 场景 3: 学习期目标压线 = 搁置(不退出) → 走后再学完 → 替换 ===== */ @@ -243,7 +243,7 @@ static void test_interrupted_learn_recomputes(void) int applied_at = 0; reset_all(); - for (loop = 0; loop < 800; loop++) { /* 8s → 学习开始 */ + for (loop = 0; loop < 700; loop++) { /* 7s → 学习开始 */ sim_CAPVD = 128856UL; sim_tick(); } @@ -287,7 +287,7 @@ static void test_unstable_learn_gives_up(void) int i; reset_all(); - for (loop = 0; loop < 800; loop++) { + for (loop = 0; loop < 700; loop++) { sim_CAPVD = 128856UL; sim_tick(); } @@ -314,7 +314,7 @@ static void test_no_repeat_learn(void) int loop; reset_all(); - for (loop = 0; loop < 800; loop++) { + for (loop = 0; loop < 700; loop++) { sim_CAPVD = 128856UL; sim_tick(); } @@ -343,12 +343,12 @@ static void test_no_repeat_learn(void) int main(void) { - printf("test_env_resync (V4.30: 预判3s/补偿8s/恢复2s)\n"); + printf("test_env_resync (V4.31: 预判2s/补偿7s/恢复2s)\n"); test_permanent_change_recovers(); test_transient_keeps_warn(); test_interrupted_learn_recomputes(); test_unstable_learn_gives_up(); test_no_repeat_learn(); - printf("ALL PASS (ENV_WARN 300 / RESYNC 800 / RECOVER 200)\n"); + printf("ALL PASS (ENV_WARN 200 / RESYNC 700 / RECOVER 200)\n"); return 0; } diff --git a/utilities/at32f421_freertos_demo/inc/TaskLoop.h b/utilities/at32f421_freertos_demo/inc/TaskLoop.h index 23ae914..e6e4b90 100644 --- a/utilities/at32f421_freertos_demo/inc/TaskLoop.h +++ b/utilities/at32f421_freertos_demo/inc/TaskLoop.h @@ -46,8 +46,8 @@ #define ENTRY_CONFIRM 3 // 进入确认: 连续 N 次低于阈值才判定有车 #define FREEZE_TIMEOUT 1000 // 基线冻结超时: ~10s @ 10ms/tick, 持续偏高且稳定后强制更新基线 #define FREEZE_STABILITY_RATE 2 // 冻结稳定性窗口: 参考值的 ±2% (CAPVD 需在此范围内才累计超时) -#define ENV_WARN_WAIT 300 // 环境预判 (V4.30): dev>+4dlt 高位连续 ~3s → 黄灯预判锁存(回摆保持) -#define ENV_RECOVER_WAIT 200 // 恢复确认 (V4.30): 新基线替换后 环境空闲连续 ~2s 才解除预判, 黄灯灭 +#define ENV_WARN_WAIT 200 // 环境预判 (V4.31): dev>+4dlt 高位连续 ~2s → 黄灯预判锁存(回摆保持) +#define ENV_RECOVER_WAIT 200 // 恢复确认 (V4.31): 新基线替换后 环境空闲连续 ~2s 才解除预判, 黄灯灭 #define COIL_F_OK_MIN_KHZ 20 // 线圈频率合理窗 (V4.26): 默认低频档口径, <20kHz → L偏大 #define COIL_F_OK_MAX_KHZ 120 // 线圈频率合理窗 (V4.26): >120kHz → L偏小 #define COIL_CAL_C_NF 68 // 标定等效谐振电容 nF (V4.29): 0Ω板 低频档(66nF名义)实测 C_eff=68.1~68.9 (均值68.4) diff --git a/utilities/at32f421_freertos_demo/inc/cmcng.h b/utilities/at32f421_freertos_demo/inc/cmcng.h index 9bc84bb..f8ccf5c 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.30" +#define FIRMWARE_VER "4.31" #define HARDWARE_VER "3.00" #define FIRMWARE_VER_MAIN 4 -#define FIRMWARE_VER_SUB 30 +#define FIRMWARE_VER_SUB 31 #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 f4286a9..00d9dc7 100644 --- a/utilities/at32f421_freertos_demo/src/TaskLoop.c +++ b/utilities/at32f421_freertos_demo/src/TaskLoop.c @@ -875,7 +875,7 @@ void vd1_task(void) #define STABLE_ORIGIN_PPT 1 // 基准稳定判据: 窗口均值漂移 ≤ Origin×1/1000 (0.1%) #define STABLE_SETTLE_WINDOWS 2 // 连续 2 个窗口(每窗100样本≈1s)漂移达标 → 判稳 #define STABLE_MAX_SAMPLES 500 // 硬兜底: 5s 未判稳强制结束自检(防绿灯无限闪) -#define ENV_RESYNC_WAIT 800 // V4.30: dev>+4dlt 高位连续 8s → 判定永久环境变化 (拍板: 预判3s + 补偿8s + 恢复2s) +#define ENV_RESYNC_WAIT 700 // V4.31: dev>+4dlt 高位连续 7s → 判定永久环境变化 (拍板: 预判2s + 补偿7s + 恢复2s) #define ENV_LEARN_WINDOW 200 // V4.24: 环境学习窗口 2s (200×10ms) #define ENV_LEARN_MAX_TICKS 3000 // V4.24: 学习预算 30s, 超时放弃 (防黄灯常亮死锁) @@ -1018,7 +1018,7 @@ void vd1_task(void) } else { /* 负variation (CAPVD高于Origin, 特殊铁块磁导率主导/异常高) * V4.24 两段式: - * ① 前 10s(ENV_RESYNC_WAIT): 只冻结, 不更新 Origin + * ① 前 7s(ENV_RESYNC_WAIT): 只冻结, 不更新 Origin * (36321a1 双向保护原语义: 防铁块污染 Origin → 离开假进入锁死) * ② 高位连续 ≥60s 未回摆 → 判定"永久环境变化"(如金属板A拿走、基准被学低) * → 进入受控重校准: 连续空闲窗口均值 B + settle 判稳 → 空闲原子替换 Origin