From 7fd120fdf3e29af334ec0a9a9692c33890a4f8dd Mon Sep 17 00:00:00 2001 From: wangfq Date: Wed, 2 Sep 2026 18:40:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(V4B):=20V4.25=20=E2=80=94=20=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E5=BC=82=E5=B8=B8=E9=BB=84=E7=81=AF=E9=A2=84=E5=88=A4?= =?UTF-8?q?:=20=E9=AB=98=E4=BD=8D=E6=8C=81=E7=BB=AD5s=E5=8D=B3=E5=B8=B8?= =?UTF-8?q?=E4=BA=AE(=E5=B0=86=E8=BF=9B=E5=85=A5=E9=87=8D=E5=AD=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景: V4.24 黄灯只在60s进入学习后才亮, 前60s操作员无可视反馈 改动: poll_yellow_led 模式4条件放宽 = g_env_resync || g_env_wait_cnt>=ENV_WARN_WAIT - ENV_WARN_WAIT=500tick(~5s) 放 TaskLoop.h 文件级(poll_yellow_led 可见) - dev>+4dlt 高位连续5s未回摆 → 黄灯预判常亮; 累计60s才真正学习(黄灯保持) - 预判≠学习: 回摆/目标靠近(wait清零) → 黄灯即灭, 不触发学习 tests/test_env_resync.c 扩展: 预判点亮时刻=500tick / 瞬态4000tick预判亮但不学 / 打断回摆后预判灭; 5场景ALL PASS + 语法0 error docs: devlog V2.23 + spec V2.4(ENV_WARN_WAIT行) + 产品手册 V2.8 同步 --- docs/devlog.md | 31 ++++++++++++++++++- docs/product-manual.md | 10 +++--- docs/technical-spec.md | 4 ++- tests/test_env_resync.c | 29 +++++++++++++---- .../at32f421_freertos_demo/inc/TaskLoop.h | 1 + utilities/at32f421_freertos_demo/inc/cmcng.h | 4 +-- .../at32f421_freertos_demo/src/TaskLoop.c | 7 +++-- 7 files changed, 69 insertions(+), 17 deletions(-) diff --git a/docs/devlog.md b/docs/devlog.md index 199b2ac..e77ab7c 100644 --- a/docs/devlog.md +++ b/docs/devlog.md @@ -4,6 +4,35 @@ --- +## 2026-09-02 — 环境异常黄灯预判:5s 常亮提示将进入重学(固件 V4.25) + +> **固件版本:V4.25**(cmcng.h:FIRMWARE_VER="4.25" + MAIN=4/SUB=25)。devlog 修订 V2.23。 + +### 背景 + +V4.24 环境重校准的黄灯常亮只在**进入学习后**(dev>+4dlt 高位累计满 60s)才点亮, +前 60s 操作员无任何可视反馈,不知道检测器是否已感知环境变化。 + +### 改动 + +- 黄灯模式4 条件放宽为两段(poll_yellow_led): + `g_env_resync || g_env_wait_cnt >= ENV_WARN_WAIT` +- 新增 `ENV_WARN_WAIT = 500 tick(~5 s)`(TaskLoop.h 文件级宏): + - 高位(dev>+4dlt)持续 **5 s** 未回摆 → 黄灯**预判常亮**(提示"环境已重大变化,将进入重校准学习") + - 累计满 **60 s** 才真正进入学习(学习期间黄灯保持常亮,学完替换 Origin 后灭) +- 预判 ≠ 学习:回摆/目标靠近(wait 清零)→ 黄灯立即灭,不触发学习 + +### 验证 + +- tests/test_env_resync.c 扩展:黄灯预判点亮时刻 = 500 tick;瞬态高位 4000 tick 预判亮但未学习;打断回摆后预判灭 +- 5 场景 ALL PASS;gcc `-fsyntax-only` 0 error + +### 待现场验证 + +A 拿走场景:约 5 s 后黄灯常亮 → 60 s 后自动重学(黄灯保持常亮数秒)→ 替换完成黄灯灭、检测高度恢复。 + +--- + ## 2026-09-02 — 环境重校准:现场永久环境变化自动恢复基线(固件 V4.24) > **固件版本:V4.24**(cmcng.h:FIRMWARE_VER="4.24" + MAIN=4/SUB=24)。devlog 修订 V2.22。 @@ -1034,7 +1063,7 @@ if (dev >= dlt_ORG × 4) { | 版本 | 时间 | 说明 | |------|------|------| -| V2.22 | 2026-09-02 | V4.24 环境重校准:dev>+4dlt 高位连续 60s 触发受控学习(黄灯常亮),连续空闲窗均值+判稳后原子替换 Origin,恢复金属板A拿走类永久环境变化;打断重算 + 30s 预算兜底 | +| V2.23 | 2026-09-02 | V4.25 环境异常黄灯预判:dev>+4dlt 高位连续 5s(ENV_WARN_WAIT=500tick)即黄灯常亮预判,60s 才真正学习;预判≠学习,回摆即灭 | | V2.20 | 2026-09-02 | V4.22 DEBUG 改编译器 -DDEBUG 控制(cmcng.h DEBUG_ENABLE 删除) | | V2.19 | 2026-09-02 | V4.20 负variation铁块锁死修复:基线跟踪双向对称保护(±4×dlt 对称窗口) | | V2.18 | 2026-09-02 | V4.20 Debug 串口打印重组:频率/采样/基准全量输出(DBG/EVT 前缀) | diff --git a/docs/product-manual.md b/docs/product-manual.md index 48f5413..9f65c1a 100644 --- a/docs/product-manual.md +++ b/docs/product-manual.md @@ -1,6 +1,6 @@ # DLD154V4B 产品手册 -> 单路线圈车辆检测器 | 型号: DLD154V4B | 版本: V2.7 +> 单路线圈车辆检测器 | 型号: DLD154V4B | 版本: V2.8 > 适用于停车场、收费站、交通卡口等场景的车辆到达/离开检测 --- @@ -185,11 +185,11 @@ DLD154V4B 是一款基于 ARM Cortex-M4 微控制器的**单通道环形线圈 | 状态 | 红灯 | 绿灯 | 黄灯 | 说明 | |------|------|------|------|------| -| 环境校准学习中 | 呼吸 | 灭(无车) | **常亮** | 检测到**永久环境变化**(如旁置金属板被移走使基准被学低):先高位冻结 60s 确认,再自动学习新基线并替换,恢复灵敏度 | +| 环境校准学习中 | 呼吸 | 灭(无车) | **常亮** | 检测到**永久环境变化**(如旁置金属板被移走使基准被学低):高位持续 **5 s** 黄灯预判常亮,累计 **60 s** 后自动学习新基线并替换,恢复灵敏度 | -- 线圈旁金属等目标在**上电时**在场会把空车基准学低;目标移走后检测高度会明显变低(V4.22 及以前需断电重上电或等基线慢跟恢复)。V4.24 起:高位持续 60s 判定永久变化 → 黄灯常亮数秒(学习中)→ 自动恢复,无需断电 -- **看到黄灯常亮表示正在学习新基线,请勿移动线圈附近的目标**(铁块静止 60s+ 也会被学入) -- 黄灯优先级:断开快闪 > 学习常亮 > N 短闪(断开史)> 灭 +- 线圈旁金属等目标在**上电时**在场会把空车基准学低;目标移走后检测高度会明显变低(V4.22 及以前需断电重上电或等基线慢跟恢复)。V4.24 起自动恢复;V4.25 起环境变化 **~5 s** 黄灯即常亮预判(提示"检测器已感知环境变化、即将进入重学") +- **黄灯常亮 = 环境异常预判/学习中**:请勿移动线圈附近的目标(铁块静止 60s+ 也会被学入);回摆(干扰消失)黄灯自动灭,不触发学习 +- 黄灯优先级:断开快闪 > 环境预判/学习常亮 > N 短闪(断开史)> 灭 - **快闪**:200ms 亮 / 200ms 灭 - **N 短闪**:N × (80ms 亮 + 200ms 灭),循环间隔 1.2s diff --git a/docs/technical-spec.md b/docs/technical-spec.md index bc4c064..4106bfe 100644 --- a/docs/technical-spec.md +++ b/docs/technical-spec.md @@ -1,6 +1,6 @@ # DLD154V4B 技术规格书 -> 单路线圈车辆检测器 | 固件版本: V4.24 | 文档版本: V2.3 +> 单路线圈车辆检测器 | 固件版本: V4.25 | 文档版本: V2.4 > 本文档面向工程开发、系统集成及故障深度分析 --- @@ -449,6 +449,7 @@ 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 | 500 tick | **~5 s** | 环境预判黄灯(V4.25):dev>+4×dlt 高位连续 5s 即黄灯常亮预判(将进入重学);预判≠学习,回摆即灭 | | ENV_RESYNC_WAIT | 6000 tick | **~60 s** | 环境重校准等待:dev>+4×dlt 高位连续 60s 判定永久环境变化(V4.24) | | ENV_LEARN_WINDOW | 200 tick | ~2 s | 环境学习窗口(基线 B 均值窗,学习期黄灯常亮) | | ENV_LEARN_MAX_TICKS | 3000 tick | **~30 s** | 学习预算:窗口不稳超时放弃,保留旧 Origin(防死锁) | @@ -757,3 +758,4 @@ DLD154V4B V1.4 起实现该专利的整数化版本,用于大车通行时的 | V2.1 | 2026-06-29 | 更新至 V2.6:单路 IIR ALFA_CAP1=79, WINDOW_ORIGIN=500, 两阶段基线 | | V2.2 | 2026-09-02 | 更新至 V4.23:上电稳定期判稳语义(基准漂移≤0.1%×2窗 + 5s兜底)、红灯呼吸周期≈2.6s、绿灯自检描述 | | V2.3 | 2026-09-02 | 更新至 V4.24:环境重校准(dev>+4dlt 高位连续 60s → 学习基线 B → 空闲原子替换 Origin,黄灯常亮指示;瞬态 60s 内不污染、30s 学习预算兜底) | +| V2.4 | 2026-09-02 | 更新至 V4.25:环境异常黄灯预判(ENV_WARN_WAIT=5s 常亮,预判≠学习,回摆即灭) | diff --git a/tests/test_env_resync.c b/tests/test_env_resync.c index 45fcd4e..77f5f53 100644 --- a/tests/test_env_resync.c +++ b/tests/test_env_resync.c @@ -21,6 +21,7 @@ #define STABLE_SETTLE_WINDOWS 2 // 连续 2 窗漂移达标 #define FREEZE_TIMEOUT 1000 // 打印饱和(dev>0 不再超时更新 Origin) #define ENV_RESYNC_WAIT 6000 // V4.24: dev>+4dlt 高位连续 60s → 判定永久环境变化 +#define ENV_WARN_WAIT 500 // V4.25: 高位连续 ~5s → 黄灯预判常亮 (TaskLoop.h) #define ENV_LEARN_WINDOW 200 // V4.24: 环境学习窗口 2s #define ENV_LEARN_MAX_TICKS 3000 // V4.24: 学习预算 30s, 超时放弃 @@ -54,6 +55,12 @@ static void env_reset(void) g_env_tick = 0; } +/* V4.25: 黄灯模式4 条件镜像 (TaskLoop.c poll_yellow_led) */ +static int env_warn_active(void) +{ + return g_env_resync || g_env_wait_cnt >= ENV_WARN_WAIT; +} + /* 与 TaskLoop.c env_resync_abort/apply 逐行一致 */ static void env_resync_abort(void) { @@ -155,11 +162,16 @@ static void test_permanent_change_recovers(void) t_set(128095UL, 128856UL, 48); int tick = 0; - for (; tick < 7000 && !ev_applied; tick++) + int warn_at = 0; + for (; tick < 7000 && !ev_applied; tick++) { sim_tick(); + if (!warn_at && env_warn_active()) + warn_at = tick + 1; /* 首次黄灯预判条件成立 (wait>=500) */ + } - printf("常量高位稳定: 学习启动=%d 替换=%d 替换tick=%d resync=%d\n", - ev_learn_start, ev_applied, tick, g_env_resync); + printf("常量高位稳定: 黄灯预判=%d 学习启动=%d 替换=%d 替换tick=%d resync=%d\n", + warn_at, ev_learn_start, ev_applied, tick, g_env_resync); + assert(warn_at == 500); /* V4.25: 高位 5s 即黄灯常亮预判 */ assert(ev_learn_start == 1); assert(ev_applied == 1); assert(tick == 6600); /* 6000 等待 + 3×200 窗 */ @@ -175,16 +187,20 @@ static void test_permanent_change_recovers(void) static void test_transient_never_learns(void) { - /* ② 瞬态高位短停 (铁块模拟): 40s(4000tick) 高位后回摆 → 不学习 */ + /* ② 瞬态高位短停 (铁块模拟): 40s(4000tick) 高位后回摆 → 不学习 + * 但 5s 后黄灯预判已亮 (wait>=500) — 预判亮 ≠ 进入学习 */ t_set(128095UL, 128856UL, 48); for (int i = 0; i < 4000; i++) sim_tick(); assert(ev_learn_start == 0); + assert(env_warn_active() == 1); /* 黄灯预判已亮 (wait=4000) */ + printf("瞬态高位短停: 4000tick 时黄灯预判亮=%d (未学习)\n", env_warn_active()); - /* 回摆进窗口 (CAPVD 回 Origin 附近), wait 清零 */ + /* 回摆进窗口 (CAPVD 回 Origin 附近), wait 清零 → 黄灯预判灭 */ sim_CAPVD = 128100UL; /* dev=+5 窗口内 */ sim_tick(); assert(g_env_wait_cnt == 0); + assert(env_warn_active() == 0); /* 回摆解除, 黄灯灭 */ /* 再次高位 59s(5900tick) — 仍不足 60s 连续 → 不学 */ sim_CAPVD = 128856UL; @@ -210,8 +226,9 @@ static void test_learn_interrupted_restarts(void) sim_tick(); /* 学习窗1 未完 */ sim_CAPVD = 128000UL; /* dev=-95 窗口内(B 目标) */ sim_tick(); - assert(g_env_resync == 0); /* 打断退出, 黄灯灭 */ + assert(g_env_resync == 0); /* 打断退出 */ assert(ev_abort == 1); + assert(env_warn_active() == 0); /* wait 清零, 黄灯预判灭 */ /* 目标离开, 高位重新 60s → 学习 3 窗 → 替换 */ sim_CAPVD = 128856UL; diff --git a/utilities/at32f421_freertos_demo/inc/TaskLoop.h b/utilities/at32f421_freertos_demo/inc/TaskLoop.h index a1676f1..ea3b5bb 100644 --- a/utilities/at32f421_freertos_demo/inc/TaskLoop.h +++ b/utilities/at32f421_freertos_demo/inc/TaskLoop.h @@ -46,6 +46,7 @@ #define ENTRY_CONFIRM 3 // 进入确认: 连续 N 次低于阈值才判定有车 #define FREEZE_TIMEOUT 1000 // 基线冻结超时: ~10s @ 10ms/tick, 持续偏高且稳定后强制更新基线 #define FREEZE_STABILITY_RATE 2 // 冻结稳定性窗口: 参考值的 ±2% (CAPVD 需在此范围内才累计超时) +#define ENV_WARN_WAIT 500 // 环境预判 (V4.25): dev>+4dlt 高位连续 ~5s 未回摆 → 黄灯常亮预判提示 /*=========================================================================== * 离开检测模式 diff --git a/utilities/at32f421_freertos_demo/inc/cmcng.h b/utilities/at32f421_freertos_demo/inc/cmcng.h index efb7726..b4e8cda 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.24" +#define FIRMWARE_VER "4.25" #define HARDWARE_VER "3.00" #define FIRMWARE_VER_MAIN 4 -#define FIRMWARE_VER_SUB 24 +#define FIRMWARE_VER_SUB 25 #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 3fe2796..3e5afa6 100644 --- a/utilities/at32f421_freertos_demo/src/TaskLoop.c +++ b/utilities/at32f421_freertos_demo/src/TaskLoop.c @@ -321,8 +321,11 @@ void poll_yellow_led(void) return; } - /*--- V4.24 模式4: 环境重校准学习中 → 黄灯常亮 (优先级: 断开快闪 > 学习常亮 > N短闪 > 灭) ---*/ - if (g_env_resync) { + /*--- V4.25 模式4: 环境异常预判/重校准学习 → 黄灯常亮 + * g_env_wait_cnt >= ENV_WARN_WAIT(~5s): 环境重大变化预判 (高位未回摆, 即将进入重学) + * g_env_resync == 1: 已进入重校准学习 (高位累计 60s 后自动开始, 学完原子替换 Origin 后灭) + * 优先级: 断开快闪 > 环境预判/学习常亮 > N短闪 > 灭 ---*/ + if (g_env_resync || g_env_wait_cnt >= ENV_WARN_WAIT) { LED_YELLOW_ON; g_fault_tick = 0; g_fault_phase = 0;