feat(V4B): V4.25 — 环境异常黄灯预判: 高位持续5s即常亮(将进入重学)

背景: 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 同步
This commit is contained in:
wangfq
2026-09-02 18:40:39 +08:00
parent 672f143e99
commit 7fd120fdf3
7 changed files with 69 additions and 17 deletions
+30 -1
View File
@@ -4,6 +4,35 @@
---
## 2026-09-02 — 环境异常黄灯预判:5s 常亮提示将进入重学(固件 V4.25)
> **固件版本:V4.25**cmcng.hFIRMWARE_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 PASSgcc `-fsyntax-only` 0 error
### 待现场验证
A 拿走场景:约 5 s 后黄灯常亮 → 60 s 后自动重学(黄灯保持常亮数秒)→ 替换完成黄灯灭、检测高度恢复。
---
## 2026-09-02 — 环境重校准:现场永久环境变化自动恢复基线(固件 V4.24)
> **固件版本:V4.24**cmcng.hFIRMWARE_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 高位连续 5sENV_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 前缀) |
+5 -5
View File
@@ -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
+3 -1
View File
@@ -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 常亮,预判≠学习,回摆即灭) |
+23 -6
View File
@@ -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;
@@ -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 未回摆 → 黄灯常亮预判提示
/*===========================================================================
*
+2 -2
View File
@@ -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
@@ -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;