Skip to content

track: round the calculated wind speed instead of truncating - #156

Closed
joliverosh wants to merge 1 commit into
wiedehopf:devfrom
joliverosh:track-calc-wind-round-speed
Closed

joliverosh wants to merge 1 commit into
wiedehopf:devfrom
joliverosh:track-calc-wind-round-speed

Conversation

@joliverosh

Copy link
Copy Markdown
Contributor

mm->wind_speed is an int (BDS 4,4 reports whole knots), and calc_wind assigns the double result to it directly, so the speed is truncated toward zero. Every calculated wind in aircraft.json, the json port and traces is therefore biased low by 0.5 kt on average and up to 1 kt. Round with nearbyint instead; wind_direction is a float and is not affected.

End-to-end test with synthetic messages (DF17 position and velocity, DF20 BDS 5,0 and 6,0) through --net-ri-port: calculated wind 22.909 kt, published ws 22 before, 23 after. On a live feed at SKCL (18069 wind observations), ws recomputed from the raw TAS/GS/heading/ track fields minus the published ws averages +0.508 kt, with 80 % of the differences between 0 and +1 kt.

mm->wind_speed is an int (BDS 4,4 reports whole knots), and calc_wind
assigns the double result to it directly, so the speed is truncated
toward zero. Every calculated wind in aircraft.json, the json port and
traces is therefore biased low by 0.5 kt on average and up to 1 kt.
Round with nearbyint instead; wind_direction is a float and is not
affected.

End-to-end test with synthetic messages (DF17 position and velocity,
DF20 BDS 5,0 and 6,0) through --net-ri-port: calculated wind
22.909 kt, published ws 22 before, 23 after. On a live feed at SKCL
(18069 wind observations), ws recomputed from the raw TAS/GS/heading/
track fields minus the published ws averages +0.508 kt, with 80 % of
the differences between 0 and +1 kt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011BqHQDHRKNRuJHR4oQB55L
@wiedehopf

Copy link
Copy Markdown
Owner

not sure the calculated wind speed is that precise :)

yet better not to have that 0.5 bias even if the precision is only int

@joliverosh

Copy link
Copy Markdown
Contributor Author

Agreed — a single calculated wind is nowhere near 1 kt precise (heading error alone is ±1–2°, i.e. several kt at cruise speed). The point is that this is a bias, not noise, so it doesn't average out across aircraft.

Here it is on the live feed at SKCL, ws recomputed from the raw TAS/GS/heading/track fields minus the published ws, before and after installing the patch today:

  | n | mean | sd | < 0 | 0…+1 | > +1 -- | -- | -- | -- | -- | -- | -- truncating (current dev) | 18 409 | +0.507 kt | 0.47 | 9.8 % | 79.4 % | 10.8 % rounding (this PR) | 472 | +0.038 kt | 0.50 | 48.5 % | 49.4 % | 2.1 %

Histogram of the difference (0.25 kt bins, % of rows): truncating peaks at +0.25…+0.75 (22 / 21 / 18 %); rounding peaks at −0.25…+0.25 (24 / 17 / 24 %) and is symmetric. Same receiver, same aircraft mix, a few hours apart. Thanks for looking at it.

@wiedehopf wiedehopf closed this in 843d8e3 Sep 23, 2026
@wiedehopf

Copy link
Copy Markdown
Owner

looking at this, making mm->wind_speed a float seems more sensible.
the aircraft fields are already floats.

@wiedehopf

Copy link
Copy Markdown
Owner

i quickly glanced at the further conversions, they should all be rounding (i think)

the printf formatting should round correctly i believe?

if you look at this in so much detail you are probably gonna calculate the winds yourself possibly using stricter time intervals for calculating it.

@wiedehopf

Copy link
Copy Markdown
Owner

btw i'm happy the wind calculation seems to be correct :)

originally found this idea in mictronics readsb (which i forked), but it was in the webinterface.
at first i did the same calculation in tar1090 (noticed an issue with the formula and fixed it if i recall correctly)
of course without the data being from the same point in time, turning aircraft or intermittent data produced garbage values.

anyhow with the --devel flag you can calculate it independently.

one option if you want to improve your data further: don't calculate wind when the track_rate is larger than some value (aircraft in a turn)

it's too bad the aircraft doesn't transmit this data ... would be nice to just have it as a 10 second squitter (so xmit without interrogation)

this calculation also relies on the magnetic_heading sent by the aircraft (i don't think that's based on a magnetic compass but rather just calculated from the aircraft knowing its true heading but i don't know)
readsb calculates the true_heading using magnetic_heading and the world magnetic model.

@joliverosh

Copy link
Copy Markdown
Contributor Author

Thanks — the float is the better fix. Yes, that's what we do: the wind-triggered json port with the age fields lets the collector recompute the wind from the same line (heading at 0.1°, GS at 0.1 kt), and readsb's ws is now our cross-check rather than the product. We already reject roll ≥ 5°; we store track_rate too, so a turn filter on it is an easy addition — thanks for the suggestion.

Your point about magnetic_heading is the one that matters most for us. On airliners it's the IRS true heading minus the aircraft's own MagVar table, and readsb then adds WMM-2025 back: any difference between the two declinations becomes a heading error that is systematic per airframe. At our latitude secular variation is ~0.1–0.15°/yr, so an old table can be 1–1.5° off, i.e. 4–8 kt of crosswind at 450 kt. We'll try to estimate it per aircraft against radiosondes. Agreed it'd be nice if the aircraft just squittered the wind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants