You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add a feature-engineering step that computes the four deviation metrics #215
Is your feature request related to a problem? Please describe.
Deviation is the client's performance metric, and nothing computes it. inference/ goes straight from raw telemetry to rule-based event labels.
Describe the solution you'd like
A feature-engineering step that produces altitude_deviation, heading_deviation, vertical_speed_deviation and velocity_deviation per row, then aggregates them per pilot and per flight (mean absolute deviation, standard deviation, time outside tolerance, or whatever the clustering step needs).
Additional context heading_deviation cannot be plain subtraction, since heading wraps at 360. Use the wrapped form in docs/telemetry_schema.md section 5, and note that the formula assumes floored modulo, so Python is fine but a port to Rust or C++ is not. The doc also points out that label_generator.py's _calculate_heading_change disagrees with it at exactly 180 degrees, so both should call one shared helper.
Deviations differ in scale (ft, deg, kt), so normalizing before clustering matters. This can be built and tested against synthetic targets before #213 lands.
Naming: use glossary terms. New columns are airspeed_deviation and target_airspeed. The CSV column stays velocity and is mapped at the loading boundary. Update docs/telemetry_schema.md §4a and §5 to match.
Layout: a small shared module for the wrapped angular difference, used by both features.py and label_generator.py. features.py holds pure DataFrame-in/DataFrame-out functions (row deviations, then per-flight and per-pilot aggregates). A thin CLI reads and writes CSVs.
Heading helper range: [-180, 180), as in the schema doc. This changes label_generator.py at exactly 180 degrees: _calculate_heading_change returns +180 today (read as a right turn at line 141) and would return -180 (a left turn at line 137). This is a one-sample, float-exact case. Note it in the PR.
Aggregates per metric: mean absolute deviation and standard deviation of signed deviation. Also emit mean signed deviation (bias), but leave it out of the default clustering set. No time-outside-tolerance until the client supplies thresholds.
Roll-up: aggregate each flight first, then average the flight features per pilot, so every flight counts equally. Keep the per-flight table as an output.
Missing targets: deviation is NaN where the target is NaN. Aggregates skip those rows and record rows-used per flight. A flight with zero valid rows raises an error, so no pilot silently gets all-NaN features.
Tests: add pytest as a dev dependency in inference/. Cover the angle helper (wrap at 360, exactly 180) and the aggregates (NaN targets, an empty flight), using synthetic targets.
@jmacd867#219 adds pilot_id and flight_id to the logged CSV, and they pass through label_generator into labeled_flight_data.csv. That is the #211 half of your input schema. Targets still wait on #213.
Activity
jmacd867 commentedon Oct 3, 2026
airspeed_deviationandtarget_airspeed. The CSV column staysvelocityand is mapped at the loading boundary. Updatedocs/telemetry_schema.md§4a and §5 to match.pilot_id,flight_id, the four actuals and fourtarget_*columns, one row per sample. Targets may be constant or vary within a flight. A missing column raises an error that names it. Until Record pilot_id and flight_id in the logged CSV #211 and Capture designated (target) values for altitude, heading, vertical speed and airspeed #213 land, only synthetic data can supply this.features.pyandlabel_generator.py.features.pyholds pure DataFrame-in/DataFrame-out functions (row deviations, then per-flight and per-pilot aggregates). A thin CLI reads and writes CSVs.label_generator.pyat exactly 180 degrees:_calculate_heading_changereturns +180 today (read as a right turn at line 141) and would return -180 (a left turn at line 137). This is a one-sample, float-exact case. Note it in the PR.inference/. Cover the angle helper (wrap at 360, exactly 180) and the aggregates (NaN targets, an empty flight), using synthetic targets.Phlabry commentedon Oct 5, 2026
@jmacd867 #219 adds
pilot_idandflight_idto the logged CSV, and they pass throughlabel_generatorintolabeled_flight_data.csv. That is the #211 half of your input schema. Targets still wait on #213.Add deviation features for pilot clustering (oss-slu#215)
Closes oss-slu#215