fix(V4B): V4.25 黄灯预判改锁存语义 — 触发后回摆保持常亮, 环境空闲稳定5s才灭

原(V4.25首个提交): 黄灯条件 wait_cnt>=5s, 回摆(wait清零)即灭 — 用户反馈应锁存:
一旦5s黄灯常亮, 高位回摆/目标靠近也保持常亮; 只有"新的没有变化的环境"
超过5s 确认恢复, 黄灯才灭。

改动:
- 新增 g_env_warn 预判锁存标志(只增不清): dev>+4dlt 高位累计满
  ENV_WARN_WAIT=500tick(~5s) → g_env_warn=1, 黄灯常亮
- 新增 g_env_recover_cnt 恢复确认: 环境回窗口内且 dev 未进进入线(>-dlt)
  连续 ENV_RECOVER_WAIT=500tick(~5s) → 解除锁存, 黄灯灭
  - 目标进确认区(dev<-dlt)/深压(dev<-4dlt) → 恢复计时清零
  - 高位重现 → 恢复计时清零, 黄灯保持
- abort/apply 均不清 g_env_warn (替换后也需恢复确认5s才灭)
- 黄灯模式4条件 = g_env_resync || g_env_warn
tests 5 场景: 回摆保持常亮→稳定5s灭→高位重现再锁存; 学习打断/放弃后锁存保持
docs: devlog V2.23 + spec V2.4 + 手册 V2.8 同步锁存语义
This commit is contained in:
wangfq
2026-09-02 19:03:49 +08:00
parent 7fd120fdf3
commit 47cb1d944e
6 changed files with 111 additions and 41 deletions
@@ -86,6 +86,11 @@ uint32_t g_env_prev = 0; // 上一窗口均值 (B 候选)
uint8_t g_env_settle = 0; // 连续稳定窗口计数 (窗内均值漂移 ≤0.1% 则+1)
uint16_t g_env_tick = 0; // 学习预算 (超时放弃防死锁)
/* V4.25+: 环境异常预判锁存 — 一旦触发黄灯常亮, 回摆/目标靠近不灭;
* 仅当环境回正常(空闲, dev 未进入线以下)连续 ENV_RECOVER_WAIT 才解除 */
uint8_t g_env_warn = 0; // 1=环境异常预判锁存 (黄灯常亮)
uint16_t g_env_recover_cnt = 0; // 恢复确认计数 (空闲持续 5s → 解除预判)
#if USE_FLATNESS_EXIT
uint8_t g_exit_state;
uint16_t g_max_slope;
@@ -322,10 +327,11 @@ void poll_yellow_led(void)
}
/*--- V4.25 模式4: 环境异常预判/重校准学习 → 黄灯常亮
* g_env_wait_cnt >= ENV_WARN_WAIT(~5s): 环境重大变化预判 (高位未回摆, 即将进入重学)
* g_env_resync == 1: 已进入重校准学习 (高位累计 60s 后自动开始, 学完原子替换 Origin 后灭)
* g_env_warn == 1: 环境重大变化预判锁存 (高位连续 ~5s 触发; 回摆/目标靠近保持,
* 环境回正常空闲连续 ~5s 才解除)
* g_env_resync == 1: 已进入重校准学习 (高位累计 60s 后自动开始, 学完原子替换 Origin)
* 优先级: 断开快闪 > 环境预判/学习常亮 > N短闪 > 灭 ---*/
if (g_env_resync || g_env_wait_cnt >= ENV_WARN_WAIT) {
if (g_env_resync || g_env_warn) {
LED_YELLOW_ON;
g_fault_tick = 0;
g_fault_phase = 0;
@@ -433,6 +439,8 @@ void INIT_VD(void)
g_env_prev = 0;
g_env_settle = 0;
g_env_tick = 0;
g_env_warn = 0; // V4.25+: 环境预判锁存复位
g_env_recover_cnt = 0;
/* M4 优化: 快速 IIR + 进入确认 */
loop1_entry_cnt = 0;
@@ -881,12 +889,26 @@ void vd1_task(void)
loop1_freeze_cnt = 0;
loop1_freeze_ref = 0; // V4.20: 清残留参考, 打印 FRZ 干净
g_env_wait_cnt = 0; // V4.24: 高位回摆/目标靠近 → 等待重来
env_resync_abort(); // V4.24: 学习中被打断 → 重算 (黄灯恢复)
env_resync_abort(); // V4.24: 学习中被打断 → 重算
/* V4.25: 恢复确认 — 环境回正常(dev 未进进入线以下)连续 5s → 解除预判锁存
* (预判一旦触发, 回摆/目标靠近都保持黄灯常亮; 只有稳定空闲才灭) */
if (dev > -(int32_t)loop1_dlt_ORG) {
if (g_env_warn) {
g_env_recover_cnt++;
if (g_env_recover_cnt >= ENV_RECOVER_WAIT) {
g_env_warn = 0;
g_env_recover_cnt = 0;
}
}
} else {
g_env_recover_cnt = 0; // 目标进入确认区 → 恢复计时重来
}
update_moving_average(&loop1_ORG_SUM, &loop1_ORG_CNT,
&loop1_Origin, loop1_CAPVD, WINDOW_ORIGIN);
} else if (dev < 0) {
g_env_wait_cnt = 0; // V4.24: 目标靠近(车方向) → 等待重来
env_resync_abort(); // V4.24: 学习中被打断 → 重算 (黄灯恢复)
env_resync_abort(); // V4.24: 学习中被打断 → 重算
g_env_recover_cnt = 0; // V4.25: 目标深压 → 恢复确认计时清零
/* 正variation (CAPVD低于Origin, 疑似车辆) → 冻结, 保留原超时兜底更新 */
if (loop1_freeze_cnt == 0) {
loop1_freeze_ref = loop1_CAPVD;
@@ -930,8 +952,13 @@ void vd1_task(void)
loop1_ORG_SUM = 0;
if (!g_env_resync) {
/*--- ① 等待确认: dev>+4dlt 高位连续累计 (回摆清零见窗口/dev<0分支) ---*/
/*--- ① 等待确认: dev>+4dlt 高位连续累计 (回摆清零见窗口/dev<0分支)
* V4.25: 累计满 5s(ENV_WARN_WAIT) → 预判锁存 g_env_warn=1 (黄灯常亮),
* 锁存后回摆/目标靠近不解除; 高位重现则恢复计时清零 ---*/
g_env_wait_cnt++;
if (g_env_wait_cnt >= ENV_WARN_WAIT)
g_env_warn = 1; // 预判锁存 (只增不清)
g_env_recover_cnt = 0; // 高位异常中 → 恢复确认失效
if (g_env_wait_cnt >= ENV_RESYNC_WAIT) {
g_env_resync = 1;
g_env_wait_cnt = 0;