feat(V4B): 方案B现场调校定稿 V4.06 — 进入加深+释放调浅双表, 全档等比

现场实测: SENS=3 进入21→25 + 释放14→12 接近PD132T最高灵敏手感(用户调校)
- 关键认知: 释放方向是CAPVD向Origin恢复, 释放线调浅(dlt小)→更晚释放
  (V4.05加深方向失败已记录, 现场实测确认调小有效)
- 全档等比: 进入×25/21 {300,60,32,21}→{357,71,38,25}
          释放×12/14 {60,32,21,14}→{51,27,18,12}
- 滞回 66%→47%, 触发更严+释放更晚, 行为等效PD132T(表值不再一致)
- 废弃 ReleaseTable_B 独立表(方向错误, 并入 SensTable_1 调校)

单测: test_planb_release.c 更新(滞回正/表值/调浅释放≥原始4档×4速/释放时刻) ✓
      test_release_slow_filter.c(方案A)仍通过
文档: devlog V2.15 + technical-spec §4.3.3 V4.06段
⚠ SENS=0 进入300→357变化大, 现场低档漏检可单独回调
This commit is contained in:
wangfq
2026-09-01 14:38:52 +08:00
parent 9f132c1e16
commit 778664067e
6 changed files with 95 additions and 44 deletions
+40
View File
@@ -4,6 +4,46 @@
--- ---
## 2026-09-01 — 方案B 现场调校定稿:进入加深 + 释放调浅(固件 V4.06)
> **固件版本:V4.06**cmcng.hFIRMWARE_VER="4.06" + MAIN=4/SUB=6)。devlog 修订 V2.15。
> **状态:方案B 定稿候选**——SENS=3 现场实测接近 PD132T,等比推全档。
### 现场调校过程(用户金属板测试)
1. V4.05 加深表 {80,42,27,18}:释放比 PD132T 更早 → 加深方向失败
2. V4.05 原始表 {60,32,21,14}:也早于 PD132T → 快滤波+原始表不够
3. **用户改 SENS=3:进入 21→25、释放 14→12 → 接近 PD132T 最高灵敏手感**
- 关键:**进入加深(触发更严)+ 释放调浅(释放更晚)** 组合有效
- 滞回 66%→47%(释放线更接近进入线,释放更严格)
### V4.06 灵敏度表(等比 ×25/21 进入、×12/14 释放)
| SENS | 进入原表 | 进入新表 | 释放原表 | 释放新表 | 滞回 |
|------|---------|---------|---------|---------|------|
| 0 | 300 | **357** | 60 | **51** | 14% |
| 1 | 60 | **71** | 32 | **27** | 38% |
| 2 | 32 | **38** | 21 | **18** | 47% |
| 3 | 21 | **25** | 14 | **12** | 48% |
- 物理含义:进入加深(误触发更少)+ 释放调浅(释放更晚,等效 PD132T 手感)
- ⚠ 与 PD132T 表值不再一致(行为等效);SENS=0 进入 300→357 变化大,现场低档漏检可单独回调
- 代码:`USE_PLANB_TABLE=1` 时双表生效(TaskLoop.c),`=0` 切回原始 PD132T 对齐表
- 废弃:V4.05 的 `ReleaseTable_B` 独立表已删除(方向错误,并入 SensTable_1 调校)
### 单测
- `tests/test_planb_release.c` 更新:滞回正 ✓ / V4.06 表值 ✓ / 调浅释放≥原始(4档×4速)✓ / 释放时刻 ✓
- `tests/test_release_slow_filter.c`(方案A)仍通过
### 待现场
- 全档实测(尤其 SENS=0 进入 357 是否漏检大车)
- HR0/2 定住 1~2s:预期稳定(快滤波无悬停状态)
- 方案AV4.04)对比数据补测
---
## 2026-09-01 — 方案B 实验:快滤波释放 + 调深释放阈值表(固件 V4.05) ## 2026-09-01 — 方案B 实验:快滤波释放 + 调深释放阈值表(固件 V4.05)
> **固件版本:V4.05**cmcng.hFIRMWARE_VER="4.05" + MAIN=4/SUB=5)。devlog 修订 V2.14。 > **固件版本:V4.05**cmcng.hFIRMWARE_VER="4.05" + MAIN=4/SUB=5)。devlog 修订 V2.14。
+2
View File
@@ -280,6 +280,8 @@ if ((Origin - dlt_ORG) < CAPVD) { // CAPVD 回升至距基线不
> **⚠ V4.052026-09-01)方案B 实验(USE_SLOW_RELEASE=0 + USE_PLANB_TABLE=1**:对比路线——释放走**快滤波**(无慢滤波状态),手感对齐改由**调深释放阈值表** `ReleaseTable_B={80,42,27,18}`(原始 `{60,32,21,14}` 加深 ~30%)承担。⚠ **关键认知:释放方向是 CAPVD 向 Origin 恢复,dlt 增大(调深)→ 释放线降低 → 释放更早**(与"调深=更严格"直觉相反,仿真+单测双确认)。仿真预测:深信号(≥0.2%)加深表比 PD132T 早 3~6 counts,原始表更接近;浅信号(~0.1%)加深表更接近(差 ~1.3 counts)。HR0/2 假释放结构性免疫(无悬停状态)。现场 A/B 对比后定稿,`USE_SLOW_RELEASE`/`USE_PLANB_TABLE` 两宏二选一保留。 > **⚠ V4.052026-09-01)方案B 实验(USE_SLOW_RELEASE=0 + USE_PLANB_TABLE=1**:对比路线——释放走**快滤波**(无慢滤波状态),手感对齐改由**调深释放阈值表** `ReleaseTable_B={80,42,27,18}`(原始 `{60,32,21,14}` 加深 ~30%)承担。⚠ **关键认知:释放方向是 CAPVD 向 Origin 恢复,dlt 增大(调深)→ 释放线降低 → 释放更早**(与"调深=更严格"直觉相反,仿真+单测双确认)。仿真预测:深信号(≥0.2%)加深表比 PD132T 早 3~6 counts,原始表更接近;浅信号(~0.1%)加深表更接近(差 ~1.3 counts)。HR0/2 假释放结构性免疫(无悬停状态)。现场 A/B 对比后定稿,`USE_SLOW_RELEASE`/`USE_PLANB_TABLE` 两宏二选一保留。
> **⚠ V4.062026-09-01)方案B 现场调校定稿(USE_SLOW_RELEASE=0 + USE_PLANB_TABLE=1**:现场实测——加深表失败(释放更早);**用户改 SENS=3 进入 21→25、释放 14→12 → 接近 PD132T 最高灵敏手感**。关键:**进入加深(触发更严)+ 释放调浅(释放更晚)**组合,滞回 66%→47%。全档等比(×25/21 进入、×12/14 释放):进入 `{357,71,38,25}`、释放 `{51,27,18,12}`。⚠ 与 PD132T 表值不再一致(行为等效);SENS=0 进入 300→357 变化大,现场低档漏检可单独回调。废弃 `ReleaseTable_B`(方向错误,并入 SensTable_1 调校)。
##### 模式 2:平坦性判定 (USE_FLATNESS_EXIT=1) — ⚠ 默认禁用(#if 0,代码保留) ##### 模式 2:平坦性判定 (USE_FLATNESS_EXIT=1) — ⚠ 默认禁用(#if 0,代码保留)
基于专利 **CN200910309382**(中山大学),解决大车通行时频率多峰导致的多次误触发。 基于专利 **CN200910309382**(中山大学),解决大车通行时频率多峰导致的多次误触发。
+36 -25
View File
@@ -1,11 +1,11 @@
/* /*
* test_planb_release.c — 方案B (快滤波 + 调深释放阈值表) 单测 * test_planb_release.c — 方案B (快滤波 + 灵敏度表现场调校) 单测
* *
* 验证 (V4.05, USE_SLOW_RELEASE=0, USE_PLANB_TABLE=1): * 验证 (V4.06, USE_SLOW_RELEASE=0, USE_PLANB_TABLE=1):
* 1. ReleaseTable_B 各档 < SensTable(进入表) → 滞回为正, 无结构假释放 * 1. 调校表各档滞回为正: SensTable_1(释放) < SensTable(进入)
* 2. 同快滤波下, 加深表(ReleaseTable_B)释放早于原始表(SensTable_1) * 2. SENS=3 调校值: 进入 25 / 释放 12 (现场实测接近 PD132T 最高灵敏手感)
* (物理方向: 释放线低 → CAPVD 恢复更早碰到 → 释放更早) * 3. 调浅释放(12) 比原始(14) 释放更
* 3. 慢速抬板场景: 方案B 释放时刻合理, 无 NaN * 4. 全档释放时刻合理
* *
* 编译: gcc -o /tmp/test_planb test_planb_release.c && /tmp/test_planb * 编译: gcc -o /tmp/test_planb test_planb_release.c && /tmp/test_planb
*/ */
@@ -17,10 +17,10 @@
#define TICK_MS 10 #define TICK_MS 10
#define ORIGIN 100000UL #define ORIGIN 100000UL
/* 与 TaskLoop.h 方案B 配置保持一致 */ /* 方案B V4.06 调校表 (与 TaskLoop.c 一致) */
static const uint16_t SensTable[4] = {300, 60, 32, 21}; /* 进入 */ static const uint16_t SensTable[4] = {357, 71, 38, 25}; /* 进入: 原{300,60,32,21} ×1.190 */
static const uint16_t SensTable_1[4] = { 60, 32, 21, 14}; /* 原始离开表 */ static const uint16_t SensTable_1[4] = { 51, 27, 18, 12}; /* 释放: 原{60,32,21,14} ×0.857 */
static const uint16_t ReleaseTable_B[4] = { 80, 42, 27, 18}; /* 方案B 加深表 */ static const uint16_t SensTable_1_old[4] = { 60, 32, 21, 14}; /* 原始表(对比用) */
static uint32_t iir(uint32_t v, uint32_t flt, int alfa) static uint32_t iir(uint32_t v, uint32_t flt, int alfa)
{ {
@@ -48,41 +48,52 @@ static void test_hysteresis_positive(void)
{ {
int s; int s;
for (s = 0; s < 4; s++) { for (s = 0; s < 4; s++) {
assert(ReleaseTable_B[s] < SensTable[s]);
assert(SensTable_1[s] < SensTable[s]); assert(SensTable_1[s] < SensTable[s]);
} }
printf("[OK] 滞回为正: ReleaseTable_B/SensTable_1 各档均 < 进入表\n"); printf("[OK] 滞回为正: 四档释放表均 < 进入表\n");
} }
static void test_deep_table_earlier(void) static void test_v406_tuned_values(void)
{
/* SENS=3: 进入 25 / 释放 12 (用户现场实测) */
assert(SensTable[3] == 25);
assert(SensTable_1[3] == 12);
/* 其他档等比: ×25/21 与 ×12/14 */
assert(SensTable[2] == 38 && SensTable[1] == 71 && SensTable[0] == 357);
assert(SensTable_1[2] == 18 && SensTable_1[1] == 27 && SensTable_1[0] == 51);
printf("[OK] V4.06 调校表值正确: 进入{357,71,38,25} 释放{51,27,18,12}\n");
}
static void test_tuned_later_than_old(void)
{ {
int s, T_ms; int s, T_ms;
for (s = 0; s < 4; s++) { for (s = 0; s < 4; s++) {
for (T_ms = 2000; T_ms <= 5000; T_ms += 1000) { for (T_ms = 2000; T_ms <= 5000; T_ms += 1000) {
int t_orig = sim_release_ms(400, SensTable_1[s], T_ms); int t_old = sim_release_ms(400, SensTable_1_old[s], T_ms);
int t_deep = sim_release_ms(400, ReleaseTable_B[s], T_ms); int t_new = sim_release_ms(400, SensTable_1[s], T_ms);
assert(t_orig > 0 && t_deep > 0); assert(t_old > 0 && t_new > 0);
/* 加深表释放不晚于原始表 (同快滤波, 线低 → 早碰) */ /* 调浅释放表 → 释放线更高 → 更晚释放 */
assert(t_deep <= t_orig); assert(t_new >= t_old);
printf("[OK] SENS=%d T=%dms: 原始@%dms, 加深表@%dms (加深≤原始 ✓)\n", printf("[OK] SENS=%d T=%dms: 原始@%dms, 调校@%dms (调校≥原始 ✓)\n",
s, T_ms, t_orig, t_deep); s, T_ms, t_old, t_new);
} }
} }
} }
static void test_release_reasonable(void) static void test_release_reasonable(void)
{ {
/* 慢速抬板 3s: 各档都必须能释放, 且加深表 SENS=3 释放时刻在 2~3s 内 */ /* SENS=3 调校表 3s 抬板(400cnt): 必须能释放 */
int t = sim_release_ms(200, ReleaseTable_B[3], 3000); int t = sim_release_ms(400, SensTable_1[3], 3000);
assert(t > 0 && t <= 3000); assert(t > 0 && t <= 3000);
printf("[OK] SENS=3 加深表 3s 抬板释放@%dms (合理范围)\n", t); printf("[OK] SENS=3 调校表 3s 抬板释放@%dms (合理范围)\n", t);
} }
int main(void) int main(void)
{ {
printf("=== 方案B (快滤波+调深释放表) 单测 ===\n"); printf("=== 方案B (快滤波+灵敏度表现场调校 V4.06) 单测 ===\n");
test_hysteresis_positive(); test_hysteresis_positive();
test_deep_table_earlier(); test_v406_tuned_values();
test_tuned_later_than_old();
test_release_reasonable(); test_release_reasonable();
printf("\n全部通过 ✓\n"); printf("\n全部通过 ✓\n");
return 0; return 0;
@@ -37,13 +37,11 @@
#define ALFA_CAP1 79 // IIR α = 79/256 ≈ 0.31 (@10ms → τ≈32ms) #define ALFA_CAP1 79 // IIR α = 79/256 ≈ 0.31 (@10ms → τ≈32ms)
#define RELEASE_ALFA 21 // 释放慢滤波 α = 21/256 ≈ 0.082 (@10ms → 精确τ≈117ms, V4.04: 对齐 PD132T α79@43.7ms 精确τ≈118ms; 原18→精确τ137ms偏慢) #define RELEASE_ALFA 21 // 释放慢滤波 α = 21/256 ≈ 0.082 (@10ms → 精确τ≈117ms, V4.04: 对齐 PD132T α79@43.7ms 精确τ≈118ms; 原18→精确τ137ms偏慢)
#define USE_SLOW_RELEASE 0 // 方案A总开关: 1=释放走慢滤波(对齐PD132T) 0=原快滤波释放 #define USE_SLOW_RELEASE 0 // 方案A总开关: 1=释放走慢滤波(对齐PD132T) 0=原快滤波释放
#define USE_PLANB_TABLE 1 // 方案B: 快滤波释放 + 调深释放阈值表 (2026-09-01 实验, V4.05) #define USE_PLANB_TABLE 1 // 方案B (V4.06): 快滤波释放 + 灵敏度表现场调校
// 1=释放判定用 ReleaseTable_B(加深30%, 各档滞回仍为正) // 1=进入加深/释放调浅双表(见 TaskLoop.c, SENS=3: 25/12 现场实测接近PD132T)
// 0=释放判定用 SensTable_1(原始PD132T对齐表) // 0=原始PD132T对齐表 {300,60,32,21}/{60,32,21,14}
// ⚠仿真预测: 加深释放线低→CAPVD恢复更早碰到→释放更早(与直觉相反) // 历史: V4.05 曾用 ReleaseTable_B 加深释放表(实验失败, 方向反)
// 深信号(≥0.2%)下原始表更接近PD132T; 浅信号(0.1%)下加深表更接近 // V4.06 改为 SENS=3 进入21→25+释放14→12, 等比推全档
// 现场实测对比后定稿, 后续二选一保留
#define RELEASE_TABLE_B { 80, 42, 27, 18} // 方案B 释放表 (V2.11 原始表 {60,32,21,14} 加深~30%)
#define MAX_SLOPE_RATE 5 // 斜率限幅: 单次最大变化 5% (物理限制, 拒绝 EMI 尖峰) #define MAX_SLOPE_RATE 5 // 斜率限幅: 单次最大变化 5% (物理限制, 拒绝 EMI 尖峰)
#define ENTRY_CONFIRM 3 // 进入确认: 连续 N 次低于阈值才判定有车 #define ENTRY_CONFIRM 3 // 进入确认: 连续 N 次低于阈值才判定有车
#define FREEZE_TIMEOUT 1000 // 基线冻结超时: ~10s @ 10ms/tick, 持续偏高且稳定后强制更新基线 #define FREEZE_TIMEOUT 1000 // 基线冻结超时: ~10s @ 10ms/tick, 持续偏高且稳定后强制更新基线
@@ -81,9 +79,6 @@
*===========================================================================*/ *===========================================================================*/
extern const uint16_t SensTable[4]; extern const uint16_t SensTable[4];
extern const uint16_t SensTable_1[4]; extern const uint16_t SensTable_1[4];
#if USE_PLANB_TABLE
extern const uint16_t ReleaseTable_B[4]; // 方案B: 调深释放表 (V4.05 实验)
#endif
/*=========================================================================== /*===========================================================================
* 全局状态变量 — 捕获 & 测量 * 全局状态变量 — 捕获 & 测量
+2 -2
View File
@@ -14,10 +14,10 @@
#define __CMCNG_H__ #define __CMCNG_H__
#define PRODUCT_MODEL "DLD154" #define PRODUCT_MODEL "DLD154"
#define FIRMWARE_VER "4.05" #define FIRMWARE_VER "4.06"
#define HARDWARE_VER "3.00" #define HARDWARE_VER "3.00"
#define FIRMWARE_VER_MAIN 4 #define FIRMWARE_VER_MAIN 4
#define FIRMWARE_VER_SUB 5 #define FIRMWARE_VER_SUB 6
#define HARDWARE_VER_MAIN 3 #define HARDWARE_VER_MAIN 3
#define HARDWARE_VER_SUB 0 #define HARDWARE_VER_SUB 0
@@ -13,10 +13,17 @@
* 离开阈值(滞回)= Origin × SensTable_1[SENS] / 65536 * 离开阈值(滞回)= Origin × SensTable_1[SENS] / 65536
* SENS: 0=低灵敏, 3=高灵敏 * SENS: 0=低灵敏, 3=高灵敏
*===========================================================================*/ *===========================================================================*/
#if USE_PLANB_TABLE
/* 方案B (V4.06): 现场实测调校 — SENS=3 进入 21→25、释放 14→12 接近 PD132T 最高灵敏手感
* 其他三档按等比 (进入 ×25/21=1.190, 释放 ×12/14=0.857) 推算:
* {300,60,32,21}→{357,71,38,25} {60,32,21,14}→{51,27,18,12}
* 物理: 进入加深(触发更严) + 释放调浅(释放更晚), 滞回 66%→47%
* ⚠ 与 PD132T 表值不再一致(行为等效); SENS=0 进入 300→357 变化大, 现场低档漏检可单独回调 */
const uint16_t SensTable[4] = {357, 71, 38, 25}; // 方案B: 进入调深 (V4.06 现场调校)
const uint16_t SensTable_1[4] = { 51, 27, 18, 12}; // 方案B: 释放调浅 (V4.06 现场调校)
#else
const uint16_t SensTable[4] = {300, 60, 32, 21}; // V2.11: 全档与 PD132T SensTable 完全一致 (0.458%/0.092%/0.049%/0.032% df/f) const uint16_t SensTable[4] = {300, 60, 32, 21}; // V2.11: 全档与 PD132T SensTable 完全一致 (0.458%/0.092%/0.049%/0.032% df/f)
const uint16_t SensTable_1[4] = { 60, 32, 21, 14}; // V2.11: 离开分档与 PD132T 完全一致 (SENUP 标贴OFF=SET_ASB=1=出厂默认) const uint16_t SensTable_1[4] = { 60, 32, 21, 14}; // V2.11: 离开分档与 PD132T 完全一致 (SENUP 标贴OFF=SET_ASB=1=出厂默认)
#if USE_PLANB_TABLE
const uint16_t ReleaseTable_B[4] = RELEASE_TABLE_B; // 方案B: 调深释放表 (V4.05 实验, 见 TaskLoop.h 注释)
#endif #endif
/*=========================================================================== /*===========================================================================
@@ -884,11 +891,7 @@ void vd1_task(void)
/*================================================================ /*================================================================
* 有车状态 — 简单 cnt_release 防抖离开 * 有车状态 — 简单 cnt_release 防抖离开
*================================================================*/ *================================================================*/
#if USE_PLANB_TABLE loop1_dlt_ORG = ((uint32_t)loop1_Origin * SensTable_1[loop1_SensLevel]) >> 16; // 方案B(V4.06): 调浅释放表已并入 SensTable_1
loop1_dlt_ORG = ((uint32_t)loop1_Origin * ReleaseTable_B[loop1_SensLevel]) >> 16; // 方案B: 调深释放表(V4.05)
#else
loop1_dlt_ORG = ((uint32_t)loop1_Origin * SensTable_1[loop1_SensLevel]) >> 16;
#endif
#if USE_SLOW_RELEASE #if USE_SLOW_RELEASE
if ((loop1_Origin - loop1_dlt_ORG) < loop1_CAPVD_slow) { // 方案A: 用慢滤波值对齐 PD132T 释放手感 if ((loop1_Origin - loop1_dlt_ORG) < loop1_CAPVD_slow) { // 方案A: 用慢滤波值对齐 PD132T 释放手感