飞控为了扛住风,
不得不暴露自己。
悬停时若有风来袭,飞控必须倾斜机体、改变推力才能保持原位——这些被迫做出的姿态与推力调整,就是风留在遥测数据里的指纹。在遥测完整、机型参数已标定且飞行处于适用包络时,系统可不依赖专用机载风速计,把这枚指纹反解回风速与风向。
valid=false 和明确原因,不臆造数值。rawWind* 也永远保留、不被覆盖。它带来的不是一个孤立风速,而是一条任务证据链
总览:两条主链,一次汇合
同一段遥测,走两条完全独立的计算主链——悬停窗口模式只在飞机"站定不动"时给出一个结果;连续飞行模式不挑窗口,对整段飞行逐点递推。两条链禁止互相嵌套,最后才在"是否有同时间实测"这一个判断点上汇合。
水平风:倾角 + 阻力法
悬停时飞控用倾斜机体来抵消风阻。倾角本身不是风速——它只对应一个"补偿加速度";要把这个加速度换算成风,必须先假设一个阻力模型,把加速度反解成相对空气速度 Va,再用地速减去它,才是风。
小角度姿态反演(M1)
适用于稳定悬停、|roll|<20°、|pitch|<20°。机体水平补偿加速度按小角度近似给出,再经 yaw 旋转到 NED:
20° 以内:拖动下面的滑块,看那条"对边"在角度变大时如何越窜越快。复合阻力反解
机体系上同时叠加"动量阻力线性项"(旋翼改变来流方向)与"钝体二次阻力"(机体迎风面):
q = (−mcoef + √(mcoef² + 4·k·|a_drag|)) / (2·k) Va = −sign(a_drag) · q
mcoef·Va(旋翼把气流"拨"歪产生的阻力,线性)。车开得快了,阻力会长得比车速快得多——这是 k·Va·|Va|(机身正面硬顶风,二次方)。两种效应同时发生,公式里就把它们加在一起;再"倒着算"回去(那个根号)就能从测到的阻力反推出风速。拖动下面的滑块,看两根力条谁先冲上去、谁后来居上。momentumDragCoeff=0 时严格退化为传统二次反演;但线性项在非零低空速下相对量级更重要,不能仅凭"悬停"就假定它可以忽略——悬停窗口与连续模式必须共用同一套标定系数。窗口聚合
窗口内逐样本求 (w_n, w_e),取北/东分量各自的中位数而非平均,抵抗 tan() 在姿态尖峰处被放大形成的异常样本,再换算合速与气象风向——风向本身绝不做算术平均。
| 样本筛选门槛(§3.2,节选) | 阈值 |
|---|---|
| 水平地速 | groundSpeed < 0.5 m/s |
| 俯仰 / 横滚角 | |roll| < 20°,|pitch| < 20°(小角度近似成立的前提) |
| 连续窗口 | ≥ 30 s 且样本数 ≥ 100 |
| 相对高度 | > 10 m(避开地效;可配置下调,但强制打 low_altitude_ground_effect_risk) |
不满足门槛 → 直接返回 valid=false + 明确的 invalidReason(如 unstable_flight_state),绝不臆造一个风速。
垂直风:推力平衡法
上升/下降气流在悬停中几乎不改变姿态,而是改变推力——飞控要靠增减推力来维持高度。所以垂直风不能沿用倾角法,必须用"推力相对基线的偏离"反推。
垂直力平衡(NED,down 为正)
引入推力基线 T0(无风稳定悬停下 Tz 的稳健中心值)是关键一步——它把质量误差、推力系数误差、电池电压漂移等"常值偏置"一次性吸收掉,反演只关心相对基线的推力偏离。
物理自洽性校验(§5.6)
| 场景 | 推理 | 结果 |
|---|---|---|
| 无风悬停 | Tz ≈ T0 | W_up ≈ 0(无风) |
| 上升气流 | 控制器降推力,Tz < T0 | W_up > 0(上升风) |
| 下降气流 | 控制器增推力,Tz > T0 | W_up < 0(下降风) |
| 仅水平来风 | 升力压低推力,但 a_lift 项抵消 | W_up ≈ 0(不误判) |
a_lift = lift_coeff·Va_h² 直接复用水平风管线算出的相对空速来抵消这个串扰。TASK_CALIBRATED(当次任务操作者确认的稳定基准段,优先)→ PROFILE_CALIBRATED(同机型档案标定值)→ THEORETICAL(缺省 m·g,打标记,不作为正式绝对垂直风)。kz 是上下方向共用、指数固定为 2 的工程简化,没有显式建模桨盘轴向入流、上升/下降非对称或涡环状态——所有有效垂直结果都固定携带 vertical_symmetric_quadratic_model_simplification 标记:公式自洽,不代表垂直气动机理已完整。同时间实测辅助修正(可选)
如果同一次任务里恰好有一台三维风传感器的同时间实测数据,系统会尝试用它做一次稳健的常量偏差修正——但绝不会用实测值替换姿态反演本身,也绝不会因为修正而"提高"原有置信度。
| 条件 | correctionMode | 最终结果 |
|---|---|---|
| 同任务同时间实测匹配充分 | SENSOR_ASSISTED_BIAS | 姿态反演 + 稳健常量偏差 |
| 没有实测 / 时间对不上 / 匹配不足 | ATTITUDE_ONLY | 纯姿态反演,绝不硬修正 |
请求显式指定 OFF | ATTITUDE_ONLY | 用于独立盲测对照 |
rawWind*(修正前原始值)、匹配数、偏差大小与传感器编号——用同一批实测算出的偏差再去验证同一批数据,属于同窗校准,不是独立精度验证。评估泛化能力时必须换一批未参与修正的数据做盲测。置信度评分与有效性门控
窗口结果的置信度从 1.0 起步,按触发条件逐项扣分,最终截断到 [0, 1]。拖动下面的开关,感受几种典型问题如何叠加拉低质量分。
这只是"未校准的工程质量指数"
扣分权重尚未用独立真值航次校准过,所以每个窗口都固定携带 confidence_heuristic_uncalibrated 标记——前端应该显示"质量分",不能解释成"75% 准确率"。
| confidence | 含义 |
|---|---|
≥ 0.75 | 内部质量条件较好,仍须结合质量标记判断 |
[0.60, 0.75) | 内部参考级 |
< 0.60 | 默认门槛下结果无效,固定 invalidReason=low_confidence |
连续估计:M3 比力模型 + M4 EKF
悬停窗口只能给"站定不动"时的一个结果。要覆盖前飞、加减速、转弯的整段飞行,系统改用一个只估计风、不联合估计阻力系数的扩展卡尔曼滤波器——阻力参数离线标定固定,在线只追踪 wN, wE 两个状态。
预测 — 更新循环
默认初始化 P0 = 25·I、过程噪声 q_w = 0.02 (m/s)²/s;S 不可逆或观测非有限时跳过该次更新、保留预测状态,绝不用零增益伪装成一次成功观测。
机动包络 → 观测噪声倍率
超出验证包络的样本不会被删除,而是用更大的观测噪声"弱参与"更新:
| 触发条件 | 倍率 |
|---|---|
| 正常 | ×1 |
| 加速度分量缺失 / 垂速 > 1.0 m/s | ×4 |
|roll|>35° 或 |pitch|>35° 或角速度 > 30°/s | ×25(上限,多条件同时触发不相乘) |
时间间隔与断档处理
| Δt | 处理 |
|---|---|
≤ 0 | 重复/乱序点,丢弃并计数 |
0 ~ 2 s | 正常预测 + 更新 |
2 ~ 10 s | 保留状态,按实际 dt 膨胀协方差 |
> 10 s | 保留风估计,重置协方差 P=P0 |
连续质量分怎么来
P 是 EKF 对北向风和东向风的不确定性,trace(P) 把两个方向的不确定程度汇总。P 越大,分数越低。整段分数取后半段逐点分数的中位数,避免初始收敛阶段占据主导。
有曲线,为什么还是无效
0.517 < 0.600 → valid=false → invalidReason=low_confidence。这表示本次估计的内部不确定性未达默认发布门槛,不是 CSV 无效,也不是 51.7% 准确。曲线和修正前平均风速 12.3284 m/s 可保留用于诊断;正式平均风速和风向字段应置空,防止将诊断数字误当作可用结论。
适用边界与模型成熟度地图
算法能力成熟度、当前部署是否具备该能力、以及本次结果是否有效,是三件不同的事,绝不用一个混合枚举同时表达:capabilityMaturity(模型成熟度)、available(当前部署是否具备)、valid(本次结果是否可用)。
capabilityMaturity=EXPERIMENTAL, available=false。