From db52f923483f8391474feb86f4e067156f83655d Mon Sep 17 00:00:00 2001 From: wangfq Date: Tue, 14 Jul 2026 11:47:19 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=96=B0=E5=A2=9E=20variation=20?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5=E9=87=8F=E5=88=86=E6=9E=90=E6=8A=A5=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 分析 uart_report_packet_loop_acs 中 variation=|Origin-CAPVD| 的更新机制: - 三操作数节奏: CAPVD~10ms / Origin 5s阶跃 / 上报窗150/600ms采样 - Origin 基线状态机: 稳定期(win100~1s)/正常(win500~5s)/冻结/冻结超时(~10s)/有车冻结 - 波形特征: 无车漂移锯齿波、车辆驻留干净跟随、大干扰防污染冻结 - 风险: 采样混叠、2B截断回绕、锯齿谷误判空闲、稳定期切换拐点 --- vd960Loop/docs/variation-analysis.md | 147 +++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 vd960Loop/docs/variation-analysis.md diff --git a/vd960Loop/docs/variation-analysis.md b/vd960Loop/docs/variation-analysis.md new file mode 100644 index 0000000..30da30e --- /dev/null +++ b/vd960Loop/docs/variation-analysis.md @@ -0,0 +1,147 @@ +# variation 上报量分析报告 + +> 分析对象:`uart_report_packet_loop_acs()` 中上报的 **变化量 variation** +> 涉及文件:`src/main.c`(组包)、`src/TaskLoop.c`(基线/IIR 更新)、`inc/TaskLoop.h`(参数宏) +> 结论层次:物理层 → 信号层 → 数据层 → 上报调度层 + +--- + +## 0. 一句话结论 + +`variation = |loop_Origin − loop_CAPVD|`,是 **"慢阶跃基线"** 与 **"快速跟踪当前值"** 两个不同时间尺度量的瞬时差。 +它在 **每次组包时实时计算**,本身无独立状态;真正决定其波形形态的是三个错位的时钟: + +- `loop_CAPVD` 的 **≈10ms** 采样 +- `loop_Origin` 的 **5s 阶跃** 更新 +- 上报的 **150ms / 600ms** 采样窗 + +三者不同步 → 无车时 variation 天然呈 **锯齿波**。 + +--- + +## 1. 定义位置 + +`src/main.c` — `uart_report_packet_loop_acs()` 组包段: + +```c +// 变化量 (2B, LE) +uint32_t variation = (unit->loop_Origin > unit->loop_CAPVD) + ? (unit->loop_Origin - unit->loop_CAPVD) + : (unit->loop_CAPVD - unit->loop_Origin); +g_pkg_uart_report.pkg[i++] = (uint8_t)(variation & 0xFF); +g_pkg_uart_report.pkg[i++] = (uint8_t)((variation >> 8) & 0xFF); +``` + +- 取 `|Origin − CAPVD|`,无符号,无方向信息 +- 仅上报低 **2 字节**(≤ 65535),高位被截断 + +--- + +## 2. 三个操作数的更新节奏 + +| 量 | 物理含义 | 更新触发 | 真实周期 | 特性 | +|---|---|---|---|---| +| `loop_CAPVD` | IIR 后当前线圈值 | 每次 `loop_CAP_OK` → `vd1_task_per_channel()` | **≈10ms**(固定测量窗 `LPCNT×Xn≈131072` timer counts) | 快,τ≈32ms,斜率限幅 5% | +| `loop_Origin` | 基线 | `update_moving_average()` 窗口满才写 | **阶跃式**(见 §3) | 慢,平台期恒定不动 | +| `variation` | 上报的变化量 | 每次组包现算 | 被 **上报窗采样**:事件 150ms / 空闲 600ms | 瞬时差,2 字节 | + +> 关键点:`variation` 没有独立状态,它只是组包那一刻两值之差。 +> 它的"更新周期"实际是 **上报采样周期**(150/600ms);它的"波形形态"由 Origin 的阶跃周期决定。 + +上报间隔宏(`inc/TaskLoop.h`,50ms tick): + +```c +#define REPORT_IDLE_TICKS 12 // 空闲稳定: 12×50ms = 600ms +#define REPORT_EVENT_TICKS 3 // 事件/变化: 3×50ms = 150ms +``` + +上报调度还叠加了 **上电 3s 抑制**(`misc_counter < 60` 跳过,等基线稳定)。 + +--- + +## 3. loop_Origin 基线更新的状态机(核心) + +`update_moving_average()` 是 **累加到窗口满才写一次**,中途 Origin 岿然不动: + +```c +*p_sum += new_value; (*p_cnt)++; +if (*p_cnt >= window) { // 只有这里改写 Origin + *p_origin = *p_sum / window; + *p_cnt = 0; *p_sum = 0; +} +``` + +| 状态 | 判据 | window | 阶跃周期 @10ms | 对 variation 的影响 | +|---|---|---|---|---| +| **稳定期** | `!loop_stable`,`stable_cnt < 128` | 100 | **~1s** | 上电快速收敛,`CAPVD = Value` 直通 | +| **正常跟踪** | 无车 & `dev < dlt_ORG×4` | **500** | **~5s** | Origin 每 5s 阶跃一次,锯齿主因 | +| **冻结** | 无车 & `dev ≥ dlt_ORG×4` | — | `ORG_CNT/SUM` 清零,**不更新** | Origin 锁死,variation 保持大值 | +| **冻结超时** | 冻结持续 & 漂移 <±2% 达 1000 次 | — | **~10s 一次性抓取** | Origin 直接 = CAPVD,variation **突然归零** | +| **有车** | `loop_VD_FLAG == 1` | — | 不进基线分支 | Origin 全程冻结,variation 忠实跟随 CAPVD | + +相关参数宏(`inc/TaskLoop.h`): + +```c +#define STABLE_SAMPLES 128 // 稳定期样本数 +#define WINDOW_ORIGIN 500 // 基线跟踪窗口 (500×10ms = 5s) +#define FREEZE_TIMEOUT 1000 // 冻结超时 ~10s @10ms +#define FREEZE_STABILITY_RATE 2 // 稳定性窗口 ±2% +#define MAX_SLOPE_RATE 5 // 斜率限幅 5% +#define ENTRY_CONFIRM 3 // 进入确认次数 +``` + +--- + +## 4. variation 波形特征 + +### 场景 1 — 无车缓慢漂移(温漂 / 湿漂),最典型 + +``` +CAPVD ─╱╱╱╱╱ 持续缓慢漂移(每10ms微动) +Origin ───┐ ┌───┐ ┌── 每5s阶跃追一次 + └────────┘ └────────┘ +variation: ╱| ╱| ╱| ╱| ← 锯齿波! + 峰=5s漂移量, 谷≈0(基线刚追上) +``` + +- 5s 窗口内 Origin 恒定,CAPVD 漂 → variation 线性爬升 +- 窗口边界 Origin 阶跃到近 5s 均值 → variation **突然跌回 ~0** +- **锯齿幅度 ≈ 漂移速率 × 5s**;变频器干扰下漂移快,齿更高 + +### 场景 2 — 车辆进入 / 驻留(设计正确 ✅) + +- 车进入瞬间 `ORG_CNT/SUM` 清零 + `VD_FLAG=1`,Origin **完全冻结** +- variation 快速跟随 CAPVD 拉大 → 真实反映车辆信号强度,干净无锯齿 + +### 场景 3 — 大干扰但非车(半截车 / 邻道串扰 / 金属堆放) + +- `dev ≥ dlt_ORG×4` 触发冻结,variation 维持大值不被基线"吃掉" +- 偏差稳住 ±2% 达 10s 后,Origin 一次性重锁,variation 突降 → 防污染 + 慢速重学基线 + +--- + +## 5. 需警惕的问题(直击要害) + +1. **采样混叠**:用 600ms 上报窗去采一个 5s 阶跃量。后台若按单次 variation 做实时判断,会看到同一个齿被多次采到不同高度,叠加 600ms/5s 相位漂移 → 看似"忽大忽小"。 + → **后台不能拿单次 variation 当绝对阈值**,应看趋势或直接用 MCU 已判好的 `car_state`。 + +2. **2 字节截断**:`variation` 仅发 2B(≤65535)。CAPVD≈131072 量级,正常 Δf/f 才百分之几,一般到不了 65535;但 **冻结场景下偏差若超 65535 会回绕**。 + → 建议加饱和:`if (variation > 0xFFFF) variation = 0xFFFF;` + +3. **锯齿谷值≈0 误导"无车确认"**:若有逻辑用 `variation < 小值` 判"绝对空闲",会在每个 5s 边界被误触发。 + → 判空闲以 `car_state` / `loop_VD_FLAG` 为准,variation 仅作辅助幅度参考。 + +4. **稳定期 window=100 → 正常 500 的切换**:上电 1s 尺度基线,128 样本后切 5s 尺度。过渡期 variation 锯齿周期从 1s 突变到 5s,后台做周期特征分析要注意此拐点。 + +--- + +## 6. 待现场验证 + +- `loop_CAP_OK` 的 ~10ms 为 devlog 设计值。**实际周期取决于 TMR3 时钟与线圈频率**,建议现场用示波器量相邻两次 `CAP_OK` 间隔确认。 + +--- + +## 7. 后续可选改进方向 + +- 将 variation 改为上报 **斜率 / 趋势** 而非瞬时差,削掉锯齿混叠 +- 补 variation **饱和保护 + 随包上报当前状态(跟踪 / 冻结 / 有车)**,让后台区分锯齿谷与真空闲