Problem
When a ULog's first valid position sample occurs at cruising altitude (common with GPOS-only logs where EKF converges after takeoff), the viewer sets alt0 from that sample. All subsequent positions compute position.y = alt - alt0 ≈ 0, so the drone appears stuck at ground level for the entire flight.
The same root cause produces several related artifacts:
- Drones that descend below their initial altitude clamp to
Y=0 (line 349 in vehicle_update)
- Home position markers render below the ground plane when
home.alt is fractionally below min_alt
- Grid offset mode uses per-drone
alt0 while formation mode uses shared min_alt, causing altitude jumps when switching modes with P key
Proposal
Add an altitude pre-scan pass during ulog_replay_init() that determines the min and max AMSL altitude across the entire flight by scanning vehicle_global_position.alt (or LPOS-derived altitude). Store flight_alt_min and flight_alt_max on the replay context.
During origin setup in main.c, use flight_alt_min as the altitude datum instead of the first position sample or home altitude:
```c
vehicles[i].alt0 = ctx->flight_alt_min;
```
This guarantees:
position.y is always ≥ 0 for any point in the flight
- No drone renders underground regardless of position data tier
- Mode switching (P key) produces consistent altitude since the datum is flight-data-derived, not home-derived
- Home markers render at
home.alt - flight_alt_min + 0.02, always above ground
For multi-drone replay, min_alt across the fleet becomes min(flight_alt_min[i]) for all drones, which is already the intended behavior but currently computed from home altitude rather than actual flight data.
The pre-scan adds negligible init time since it piggybacks on the existing CUSUM/home resolution scan that already iterates all messages.
Problem
When a ULog's first valid position sample occurs at cruising altitude (common with GPOS-only logs where EKF converges after takeoff), the viewer sets
alt0from that sample. All subsequent positions computeposition.y = alt - alt0 ≈ 0, so the drone appears stuck at ground level for the entire flight.The same root cause produces several related artifacts:
Y=0(line 349 invehicle_update)home.altis fractionally belowmin_altalt0while formation mode uses sharedmin_alt, causing altitude jumps when switching modes with P keyProposal
Add an altitude pre-scan pass during
ulog_replay_init()that determines the min and max AMSL altitude across the entire flight by scanningvehicle_global_position.alt(or LPOS-derived altitude). Storeflight_alt_minandflight_alt_maxon the replay context.During origin setup in
main.c, useflight_alt_minas the altitude datum instead of the first position sample or home altitude:```c
vehicles[i].alt0 = ctx->flight_alt_min;
```
This guarantees:
position.yis always ≥ 0 for any point in the flighthome.alt - flight_alt_min + 0.02, always above groundFor multi-drone replay,
min_altacross the fleet becomesmin(flight_alt_min[i])for all drones, which is already the intended behavior but currently computed from home altitude rather than actual flight data.The pre-scan adds negligible init time since it piggybacks on the existing CUSUM/home resolution scan that already iterates all messages.