From ae7cceba18800dd749076dbe42ce2845a4c5ce84 Mon Sep 17 00:00:00 2001 From: Jose Luis Oliveros Date: Tue, 22 Sep 2026 14:58:00 +0000 Subject: [PATCH] comm_b: penalise BDS 6,0 candidates whose IAS and Mach disagree at the DF20 altitude Implements the check left as a comment ("Should check IAS vs Mach at given altitude"). For DF20 replies the pressure altitude is in the message, so CAS can be computed from Mach through the ISA pressure ratio and compared with the reported IAS; a mismatch above 25 kt costs 12 points. DF21 replies (no altitude) are unaffected. Sanity values: M0.78 @ 35000 ft -> 264 kt; M0.45 @ 10000 ft -> 249 kt; M0.22 @ 3000 ft -> 138 kt. --- comm_b.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/comm_b.c b/comm_b.c index 0ec46e21..e4efcfcd 100644 --- a/comm_b.c +++ b/comm_b.c @@ -779,7 +779,24 @@ static int decodeBDS60(struct modesMessage *mm, bool store) { // small penalty for inconsistent data - // Should check IAS vs Mach at given altitude, but the maths is a little involved + // IAS vs Mach consistency at the pressure altitude carried by DF20 (ISA, CAS ~ IAS). + // A BDS 5,0 misclassified as 6,0 (or bit errors) fails this even when every + // field is individually within range. + if (ias_valid && mach_valid && mm->baro_alt_valid && mm->baro_alt_unit == UNIT_FEET + && mm->baro_alt > -1500 && mm->baro_alt < 60000) { + double h_m = mm->baro_alt * 0.3048; + double p_ratio; + if (h_m <= 11000.0) { + p_ratio = pow(1.0 - 2.25577e-5 * h_m, 5.25588); + } else { + p_ratio = 0.22336 * exp(-(h_m - 11000.0) / 6341.62); + } + double qc_p0 = p_ratio * (pow(1.0 + 0.2 * mach * mach, 3.5) - 1.0); + double cas = 661.47 * sqrt(5.0 * (pow(qc_p0 + 1.0, 2.0 / 7.0) - 1.0)); + if (fabs(cas - (double) ias) > 25.0) { + score -= 12; + } + } if (baro_rate_valid && inertial_rate_valid) { int delta = abs(baro_rate - inertial_rate);