feat: add altitude-based air density to ballistics model and test coverage - #169
Open
Kayd-Craig wants to merge 7 commits into
Open
feat: add altitude-based air density to ballistics model and test coverage#169Kayd-Craig wants to merge 7 commits into
Kayd-Craig wants to merge 7 commits into
Conversation
- log_connection: device/port/baud, optional firmware and radc_available - log_accepted_reading: entry content and stats increment - log_shot: optional fields (angle_source, club_angle_deg, club_path_deg, spin_axis_deg, pipeline_ms) included/omitted correctly - log_camera_data: full entry and None angles - log_config_change: default and custom source - log_sim_send: full entry and None values fallback - log_sim_status: connected/retrying states - log_sim_player: entry content - log_iq_reading: full entry, cfar flag - log_iq_blocks: block count, empty list - log_trigger_event: accepted/rejected, stats tracking - Properties: session_id and raw_path before/after start - init_session_logger: instance creation, global logger registration
Consolidate new tests into tests/test_session_logger.py rather than keeping them in a separate file.
Cover previously untested trigger paths without hardware: - TriggerStrategy base: drain_diagnostics, _append_diagnostic fields - ManualTrigger: request_trigger, reset, wait_for_trigger fire/timeout - PollingTrigger: defaults, activity detection, timeout, None capture, exceptions - ThresholdTrigger: defaults, reset, threshold detection, inbound rejection, timeout - SpeedTriggeredCapture: defaults, reset, last_trigger_speed property - SoundTrigger._clock_sync_last_read_host_time: host_after, host_mid, edge cases - SoundTrigger._clock_sync_age_s: age calculation, missing host time - SoundTrigger._clock_sync_quality: all valid/invalid branches - SoundTrigger._clock_sync_summary_for_log: non-dict, summary fields - SoundTrigger.wait_for_trigger: timeout, parse failure, false trigger rejection
Add air_density_at_altitude() using the ISA tropospheric formula, valid from sea level to ~11 km (covers all realistic golf venues). At Denver (1609m) density is ~85% of sea level; at high-altitude courses like Leadville (3094m) it drops to ~74%, adding meaningful carry distance that the previous sea-level constant missed. Add optional altitude_m parameter to simulate() that overrides air_density when provided. Existing call sites are unaffected — the parameter defaults to None and behaviour is unchanged. Add 11 tests covering: - ISA density at sea level, Denver, Leadville, negative altitude - altitude_m increases carry vs sea level - altitude_m overrides explicit air_density argument - altitude_m=None leaves air_density param untouched
Users can now set altitude in the Debug Panel tuning section with a m/ft toggle. The value is always stored internally in metres and sent to the server, but displays and accepts input in whichever unit the user selects. Conversion is handled entirely in the UI. - radar_config: add altitude_m field (default 0 = sea level) - set_radar_config: handle altitude_m updates from UI - simulate(): pass altitude_m from radar_config - RadarConfig type: add altitude_m field - useDebugStore: initialise altitude_m to 0 - DebugPanel: add AltitudeControl with m/ft toggle (0-4500m / 0-14764ft)
Member
|
How are users setting these new changes to the ballistic model? Edit: nvm, saw UI slider there |
Member
|
Couple CI failures, can you fix? then good to merge |
Author
|
CI fixes pushed — ESLint pre-commit hook working directory corrected. |
This was referenced Aug 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds altitude-aware air density to the ballistics model so carry calculations
are accurate at elevation, and expands test coverage across two undertested
modules. Users can set their altitude in the Debug Panel tuning section with
a m/ft toggle.
Why was this required?
The ballistics model hardcoded sea-level air density (1.225 kg/m³) for all
carry calculations. At Denver (1609m) air density is ~85% of sea level; at
high-altitude courses like Leadville, CO (3094m) it drops to ~74%, producing
meaningfully wrong carry estimates for players at elevation.
The session_logger and rolling_buffer/trigger modules had significant untested
paths that reduced confidence in regressions going undetected.
Automated tests
101 new tests across three files:
tests/test_session_logger.py — 47 new tests covering previously untested methods:
log_connection, log_accepted_reading, log_shot optional fields, log_camera_data,
log_config_change, log_sim_send, log_sim_status, log_sim_player, log_iq_reading,
log_iq_blocks, log_trigger_event, properties (session_id, raw_path),
init_session_logger.
tests/test_trigger_strategies.py — 51 new tests covering TriggerStrategy base
(drain_diagnostics, _append_diagnostic), ManualTrigger, PollingTrigger,
ThresholdTrigger, SpeedTriggeredCapture, SoundTrigger clock sync helpers,
and SoundTrigger.wait_for_trigger edge paths.
tests/test_ballistics.py — 11 new tests covering air_density_at_altitude()
(sea level, Denver, Leadville, negative altitude clamped) and simulate()
with altitude_m parameter.
Manual (human) testing
Tested in mock mode:
receives metres
vs sea level for same shot inputs
Note: ESLint pre-commit hook failed locally due to environment issue
(hook running from home directory instead of ui/).
npm run lintandnpm run format:checkfrom ui/ both pass cleanly.Checklist
uv run pytest tests/ -v)uv run pylint src/openflight/ --fail-under=9)uv run ruff check src/openflight/)cd ui && npm run build)cd ui && npm run lint)