对比路线(与V4.04方案A A/B): 释放走快滤波(无慢滤波状态, 消除悬停风险),
手感对齐改由调深释放表 {80,42,27,18}(原始{60,32,21,14}加深30%)承担。
⚠关键认知(仿真+单测双确认): 释放方向是CAPVD向Origin恢复,
dlt增大(调深)→释放线降低→释放更早(与'调深=更严格'直觉相反)。
仿真预测: 深信号(≥0.2%)原始表更接近PD132T; 浅信号(0.1%)加深表更接近。
单测: tests/test_planb_release.c 新增(滞回为正✓/加深表释放≤原始表✓/释放时刻合理✓)
test_release_slow_filter.c(方案A)仍通过, 两方案可回归
文档: devlog V2.14 + technical-spec §4.3.3 方案B段
90 lines
3.0 KiB
C
90 lines
3.0 KiB
C
/*
|
|
* test_planb_release.c — 方案B (快滤波 + 调深释放阈值表) 单测
|
|
*
|
|
* 验证 (V4.05, USE_SLOW_RELEASE=0, USE_PLANB_TABLE=1):
|
|
* 1. ReleaseTable_B 各档 < SensTable(进入表) → 滞回为正, 无结构假释放
|
|
* 2. 同快滤波下, 加深表(ReleaseTable_B)释放早于原始表(SensTable_1)
|
|
* (物理方向: 释放线低 → CAPVD 恢复更早碰到 → 释放更早)
|
|
* 3. 慢速抬板场景: 方案B 释放时刻合理, 无 NaN
|
|
*
|
|
* 编译: gcc -o /tmp/test_planb test_planb_release.c && /tmp/test_planb
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <assert.h>
|
|
|
|
#define ALFA_FAST 79 /* 主滤波 @10ms, τ≈22ms */
|
|
#define TICK_MS 10
|
|
#define ORIGIN 100000UL
|
|
|
|
/* 与 TaskLoop.h 方案B 配置保持一致 */
|
|
static const uint16_t SensTable[4] = {300, 60, 32, 21}; /* 进入表 */
|
|
static const uint16_t SensTable_1[4] = { 60, 32, 21, 14}; /* 原始离开表 */
|
|
static const uint16_t ReleaseTable_B[4] = { 80, 42, 27, 18}; /* 方案B 加深表 */
|
|
|
|
static uint32_t iir(uint32_t v, uint32_t flt, int alfa)
|
|
{
|
|
return flt + (uint32_t)(((int32_t)v - (int32_t)flt) * alfa >> 8);
|
|
}
|
|
|
|
/* 快滤波释放仿真: 板信号 dev0 匀速恢复, 返回释放时刻 ms (0=未释放) */
|
|
static int sim_release_ms(uint32_t dev0, uint32_t leave_l, int T_ms)
|
|
{
|
|
uint32_t flt = ORIGIN - dev0;
|
|
int cnt = 0, n = T_ms / TICK_MS, i;
|
|
for (i = 1; i <= n; i++) {
|
|
uint32_t true_v = ORIGIN - dev0 * (n - i) / n;
|
|
flt = iir(true_v, flt, ALFA_FAST);
|
|
if (flt > ORIGIN - leave_l) {
|
|
if (++cnt >= 3) return i * TICK_MS;
|
|
} else {
|
|
cnt = 0;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void test_hysteresis_positive(void)
|
|
{
|
|
int s;
|
|
for (s = 0; s < 4; s++) {
|
|
assert(ReleaseTable_B[s] < SensTable[s]);
|
|
assert(SensTable_1[s] < SensTable[s]);
|
|
}
|
|
printf("[OK] 滞回为正: ReleaseTable_B/SensTable_1 各档均 < 进入表\n");
|
|
}
|
|
|
|
static void test_deep_table_earlier(void)
|
|
{
|
|
int s, T_ms;
|
|
for (s = 0; s < 4; s++) {
|
|
for (T_ms = 2000; T_ms <= 5000; T_ms += 1000) {
|
|
int t_orig = sim_release_ms(400, SensTable_1[s], T_ms);
|
|
int t_deep = sim_release_ms(400, ReleaseTable_B[s], T_ms);
|
|
assert(t_orig > 0 && t_deep > 0);
|
|
/* 加深表释放不晚于原始表 (同快滤波, 线低 → 早碰) */
|
|
assert(t_deep <= t_orig);
|
|
printf("[OK] SENS=%d T=%dms: 原始表@%dms, 加深表@%dms (加深≤原始 ✓)\n",
|
|
s, T_ms, t_orig, t_deep);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void test_release_reasonable(void)
|
|
{
|
|
/* 慢速抬板 3s: 各档都必须能释放, 且加深表 SENS=3 释放时刻在 2~3s 内 */
|
|
int t = sim_release_ms(200, ReleaseTable_B[3], 3000);
|
|
assert(t > 0 && t <= 3000);
|
|
printf("[OK] SENS=3 加深表 3s 抬板释放@%dms (合理范围)\n", t);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
printf("=== 方案B (快滤波+调深释放表) 单测 ===\n");
|
|
test_hysteresis_positive();
|
|
test_deep_table_earlier();
|
|
test_release_reasonable();
|
|
printf("\n全部通过 ✓\n");
|
|
return 0;
|
|
}
|