feat: 基线冻结超时 — 持续偏高30s后强制更新Origin

问题: 原点保护冻结基线后,若CAPVD因环境变化(温度、器件老化等)
稳定在新的高频值,Origin永远不会更新,导致永久误判有车。

方案:
- 新增 FREEZE_TIMEOUT=3000 (~30s @ 10ms/tick)
- CAPVD偏离时 loop1_freeze_cnt 逐帧递增
- 超时后强制 Origin = CAPVD(当前稳定值),视为新常态
- 中途若CAPVD回归正常范围,计数清零,继续正常跟踪
- 车辆进入时同步清零冻结计数
This commit is contained in:
wangfq
2026-06-29 10:24:53 +08:00
parent 55a6a2e99b
commit 269fa7f4cc
2 changed files with 21 additions and 4 deletions

View File

@@ -38,6 +38,7 @@
#define ALFA_FAST 128 // 快速 IIR α = 128/256 = 0.5 (@10ms → τ≈28ms, 用于检测)
#define MAX_SLOPE_RATE 5 // 斜率限幅: 单次最大变化 5% (物理限制, 拒绝 EMI 尖峰)
#define ENTRY_CONFIRM 3 // 进入确认: 连续 N 次低于阈值才判定有车
#define FREEZE_TIMEOUT 3000 // 基线冻结超时: ~30s @ 10ms/tick, 持续偏高后强制更新基线
/*===========================================================================
* 离开检测模式
@@ -103,6 +104,7 @@ extern uint8_t loop1_cnt_release; // 离开防抖计数
/* M4 优化: 快速 IIR + 进入确认 */
extern uint32_t loop1_CAPVD_fast; // 快速 IIR 值 (α=0.5, τ≈28ms, 用于检测)
extern uint8_t loop1_entry_cnt; // 进入确认计数
extern uint16_t loop1_freeze_cnt; // 基线冻结持续计数(超时后强制更新 Origin
#if USE_FLATNESS_EXIT
extern uint8_t g_exit_state; // 离开检测: 0=追踪斜率, 1=等待平坦
extern uint16_t g_max_slope; // 第一上升坡面最大 |f'|

View File

@@ -39,6 +39,7 @@ uint8_t Flt_Reg;
/* M4 优化: 快速 IIR + 进入确认 */
uint32_t loop1_CAPVD_fast;
uint8_t loop1_entry_cnt;
uint16_t loop1_freeze_cnt;
/*===========================================================================
* 全局状态变量 — 标志位
@@ -342,6 +343,7 @@ void INIT_VD(void)
/* M4 优化: 快速 IIR + 进入确认 */
loop1_CAPVD_fast = 0;
loop1_entry_cnt = 0;
loop1_freeze_cnt = 0;
#if USE_FLATNESS_EXIT
g_exit_state = 0;
g_max_slope = 0;
@@ -699,13 +701,25 @@ void vd1_task(void)
{
int32_t dev = (int32_t)loop1_CAPVD - (int32_t)loop1_Origin;
if (dev < (int32_t)(loop1_dlt_ORG * 4)) {
/* CAPVD 未显著高于基线 → 安全跟踪 */
/* CAPVD 未显著高于基线 → 安全跟踪,重置冻结计数 */
loop1_freeze_cnt = 0;
update_moving_average(&loop1_ORG_SUM, &loop1_ORG_CNT,
&loop1_Origin, loop1_CAPVD, 100);
} else {
/* CAPVD 异常偏高 → 冻结跟踪,重置累计 */
loop1_ORG_CNT = 0;
loop1_ORG_SUM = 0;
/* CAPVD 异常偏高 → 冻结跟踪 */
loop1_freeze_cnt++;
if (loop1_freeze_cnt >= FREEZE_TIMEOUT) {
/* 超时: CAPVD 持续偏高但稳定 → 可能是环境变化,强制更新基线 */
loop1_Origin = loop1_CAPVD;
loop1_freeze_cnt = 0;
loop1_ORG_CNT = 0;
loop1_ORG_SUM = 0;
PRINT("Baseline timeout update, new Origin:%d\\n", loop1_Origin);
} else {
/* 未超时: 保持冻结,重置累计(防止突然解冻时旧数据污染) */
loop1_ORG_CNT = 0;
loop1_ORG_SUM = 0;
}
}
}
@@ -722,6 +736,7 @@ void vd1_task(void)
loop1_VD_FLAG = 1;
loop1_FLAG_IN = 1;
loop1_entry_cnt = 0;
loop1_freeze_cnt = 0; // 入场时重置冻结计数
/* 有限存在计时(非安全复位模式下) */
if (!SET_SAFE) {