/* * test_neg_variation.c — 负variation铁块场景回归单测 (V4.20) * * 背景: 特殊铁块(磁导率主导)靠近线圈 → CAPVD 高于 Origin(频率降) * 原单边基线保护 → Origin 被污染 → 铁块离开时假进入 → 释放线抬高 → 锁死不释放 * 修复: 双向对称保护 — 负偏差(dev>0) 只冻结, 永不超时更新 Origin * * 验证: * 1. 小偏差(±4×dlt内) → 正常基线更新 * 2. 正variation(dev<0, 疑似车) → 冻结 + 超时兜底更新(保留) * 3. 负variation(dev>0, 铁块) → 冻结 + 超时也绝不更新 Origin ← 核心修复 * 4. 场景仿真: 铁块靠近(负var) → 离开 → 修复前假进入+锁定 / 修复后无输出 *===========================================================================*/ #include #include #include #include #define ORIGIN 131072UL #define DLT_ORG 38 /* SENS=3 进入 counts (表值25@100000 ≈ 38@131072) */ #define FREEZE_BAND (DLT_ORG * 4) /* 对称窗口 ±152 */ #define FREEZE_TIMEOUT 1000 /* 基线决策 — 与 TaskLoop.c 同逻辑 (简化版, 只测决策方向) */ typedef enum { DEC_UPDATE = 0, DEC_FREEZE_POS, DEC_FREEZE_NEG } dec_t; static dec_t baseline_decide(int32_t capvd, int32_t origin, uint32_t *freeze_cnt) { int32_t dev = capvd - origin; int32_t band = FREEZE_BAND; if (dev < band && dev > -band) { *freeze_cnt = 0; return DEC_UPDATE; } else if (dev < 0) { (*freeze_cnt)++; return DEC_FREEZE_POS; } else { if (*freeze_cnt == 0) { /* 首中记录 */ } (*freeze_cnt)++; if (*freeze_cnt > FREEZE_TIMEOUT) *freeze_cnt = FREEZE_TIMEOUT; return DEC_FREEZE_NEG; } } int main(void) { uint32_t freeze_cnt = 0; printf("=== 负variation铁块场景回归单测 (V4.20) ===\n"); /* 1. 小偏差 → 正常更新 */ assert(baseline_decide(ORIGIN + 10, ORIGIN, &freeze_cnt) == DEC_UPDATE); assert(baseline_decide(ORIGIN - 10, ORIGIN, &freeze_cnt) == DEC_UPDATE); assert(baseline_decide(ORIGIN - 100, ORIGIN, &freeze_cnt) == DEC_UPDATE); printf("[OK] 小偏差(±%d内) → 正常基线更新\n", FREEZE_BAND); /* 2. 正variation (CAPVD低于Origin, 疑似车) → 冻结 */ freeze_cnt = 0; assert(baseline_decide(ORIGIN - 300, ORIGIN, &freeze_cnt) == DEC_FREEZE_POS); assert(freeze_cnt == 1); printf("[OK] 正variation(CAPVDOrigin, 铁块) → 冻结计数\n"); /* 4. 核心修复: 负variation超时(铁块停留>10s) → Origin 绝不更新 */ freeze_cnt = 0; for (int i = 0; i < FREEZE_TIMEOUT + 100; i++) { assert(baseline_decide(ORIGIN + 500, ORIGIN, &freeze_cnt) == DEC_FREEZE_NEG); } assert(freeze_cnt == FREEZE_TIMEOUT); /* 饱和不更新 */ printf("[OK] 负variation停留超时(%d tick) → Origin 保持 %lu (核心修复: 不污染)\n", FREEZE_TIMEOUT + 100, ORIGIN); /* 5. 正variation超时 → 兜底更新仍保留 (模拟 FREEZE_TIMEOUT 后 Origin=CAPVD) */ freeze_cnt = 0; int updated = 0; for (int i = 0; i < FREEZE_TIMEOUT + 50; i++) { if (baseline_decide(ORIGIN - 300, ORIGIN, &freeze_cnt) == DEC_FREEZE_POS) { if (freeze_cnt >= FREEZE_TIMEOUT) { updated = 1; break; } } } assert(updated == 1); printf("[OK] 正variation停留超时 → 兜底更新仍保留 (车辆长时间信号不丢)\n"); /* 6. 完整场景: 铁块靠近→停留→离开 (修复后: 不假进入, 无锁定) */ { int32_t origin = (int32_t)ORIGIN; int32_t capvd = (int32_t)ORIGIN; int fake_entry = 0; uint32_t fcnt = 0; /* 铁块靠近: CAPVD 升 +500 (负variation) */ capvd = ORIGIN + 500; for (int i = 0; i < 50; i++) { /* 5s */ dec_t d = baseline_decide(capvd, origin, &fcnt); assert(d == DEC_FREEZE_NEG); } assert(origin == (int32_t)ORIGIN); /* Origin 未被污染 */ /* 铁块离开: CAPVD 回落正常 */ capvd = ORIGIN; for (int i = 0; i < 50; i++) { dec_t d = baseline_decide(capvd, origin, &fcnt); (void)d; } /* 修复后: Origin 正常 → 无假进入 (CAPVD 不低于进入线 Origin-38) */ if (capvd < origin - DLT_ORG) fake_entry = 1; assert(fake_entry == 0); printf("[OK] 场景仿真: 铁块靠近→停留→离开, Origin 未污染, 无假进入, 无锁定\n"); } printf("\n全部通过 ✓\n"); return 0; }