fix(V4B): 负variation铁块锁死修复 — 基线跟踪双向对称保护 (V4.20)
现场: 特殊铁块(磁导率主导)靠近 → variation负 → Origin被污染 → 离开时假进入 → 锁死不释放
根因: 基线跟踪单边保护(只挡dev>+4×dlt), 负偏差(CAPVD>Origin)照常更新Origin
FREEZE_TIMEOUT=10s后直接跳污染值更彻底
修复:
1. 偏差窗口对称 [-4×dlt, +4×dlt] — 负偏差也冻结基线
2. 负偏差只冻结、永不超时更新Origin(铁块停留多久不污染)
3. 正偏差保留FREEZE_TIMEOUT兜底(车辆长时间信号不丢)
4. 新增 EVT|neg_var_freeze 事件打印
单测: tests/test_neg_variation.c 6项全过(决策/超时/场景仿真)
文档: devlog V2.19
This commit is contained in:
@@ -764,15 +764,23 @@ void vd1_task(void)
|
||||
*================================================================*/
|
||||
|
||||
/*--- 基线跟踪(仿 TLD-110:有车时冻结)
|
||||
* 额外保护: CAPVD 异常上升时暂停跟踪 → 冻结超时 + 稳定性检查 ---*/
|
||||
* V4.20 修复: 双向对称保护 — 负偏差(负variation)也冻结基线
|
||||
* 原单边保护只挡 dev>+4×dlt, 负variation铁块(磁导率主导, CAPVD>Origin)
|
||||
* 会把 Origin 污染抬高 → 铁块离开时假进入 → 释放线抬高 → 锁死不释放
|
||||
* 修复: ① 偏差窗口对称 [-4×dlt, +4×dlt]
|
||||
* ② 负偏差(dev>0, CAPVD高于Origin) 只冻结, 永不超时更新 Origin
|
||||
*---*/
|
||||
loop1_dlt_ORG = ((uint32_t)loop1_Origin * SensTable[loop1_SensLevel]) >> 16;
|
||||
{
|
||||
int32_t dev = (int32_t)loop1_CAPVD - (int32_t)loop1_Origin;
|
||||
if (dev < (int32_t)(loop1_dlt_ORG * 4)) {
|
||||
int32_t freeze_band = (int32_t)(loop1_dlt_ORG * 4);
|
||||
if (dev < freeze_band && dev > -freeze_band) {
|
||||
/* 对称窗口内 → 正常基线跟踪 */
|
||||
loop1_freeze_cnt = 0;
|
||||
update_moving_average(&loop1_ORG_SUM, &loop1_ORG_CNT,
|
||||
&loop1_Origin, loop1_CAPVD, WINDOW_ORIGIN);
|
||||
} else {
|
||||
} else if (dev < 0) {
|
||||
/* 正variation (CAPVD低于Origin, 疑似车辆) → 冻结, 保留原超时兜底更新 */
|
||||
if (loop1_freeze_cnt == 0) {
|
||||
loop1_freeze_ref = loop1_CAPVD;
|
||||
} else {
|
||||
@@ -795,6 +803,19 @@ void vd1_task(void)
|
||||
loop1_ORG_CNT = 0;
|
||||
loop1_ORG_SUM = 0;
|
||||
}
|
||||
} else {
|
||||
/* 负variation (CAPVD高于Origin, 特殊铁块磁导率主导/异常高) → 只冻结, 永不更新 Origin
|
||||
* 防 Origin 污染锁死; 权衡: 长时间负温漂基线不跟随(安全方向, 检测仍正常) */
|
||||
if (loop1_freeze_cnt == 0) {
|
||||
loop1_freeze_ref = loop1_CAPVD;
|
||||
PRINT("EVT|neg_var_freeze CAPVD:%d Origin:%d dev:%d dlt:%d f:%dkHz\n",
|
||||
loop1_CAPVD, loop1_Origin, (int)dev, loop1_dlt_ORG,
|
||||
calc_freq_khz(loop1_CAPVD, loop1_LPCNT));
|
||||
}
|
||||
loop1_freeze_cnt++;
|
||||
if (loop1_freeze_cnt > FREEZE_TIMEOUT) loop1_freeze_cnt = FREEZE_TIMEOUT; // 饱和, 不更新
|
||||
loop1_ORG_CNT = 0;
|
||||
loop1_ORG_SUM = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user