mirror of
https://github.com/alexhopeoconnor/firmware.git
synced 2026-10-21 10:42:35 +10:00
Compute GeoCoord's UTM/MGRS/OSGR/OLC lazily instead of eagerly (#10996)
GeoCoord's constructor unconditionally computed all five coordinate representations (DMS, UTM, MGRS, OSGR, OLC) via setCoords(), even though most callers only ever read one. The UTM conversion alone pulls in a chain of libm trig functions (atan, __kernel_tan, __ieee754_acos, __ieee754_pow, __kernel_rem_pio2/__ieee754_rem_pio2) that then have to be linked in regardless of whether anything is ever displayed. The only screen consumer (UIRenderer.cpp's GPS coordinate display) already dispatches on a single configured format and reads exactly one representation per call - never more than one. Compute DMS eagerly (cheap, most commonly needed) and defer UTM/MGRS/OSGR/OLC to first access via their own getters, tracked with per-representation mutable dirty flags, so a caller that never touches a given representation never pulls in its conversion code or the trig functions it needs. On stm32wl, GeoCoord's heavy constructor is reached only through NMEAWPL.cpp's NMEA/CalTopo serial export (GPS-gated, so wio-e5 only), which only ever reads the DMS getters - so this recovers 8,288 bytes flash there (of the 10,172-byte ceiling if the whole feature were cut) with the feature fully intact and zero behavior change on any platform. Updated test_geocoord_extreme_coords_no_oob (the existing regression test for a historical out-of-bounds crash in the UTM/MGRS conversion on extreme lat/lon) to explicitly call each representation's getter, since it previously relied on the constructor eagerly triggering all four conversions - which this change intentionally defers. Verified: full native test suite passes (586/586 test cases, including this one under ASan), and rak4631 (nRF52, screen-equipped, where the UTM/MGRS/OSGR/OLC getters are actually reachable) builds successfully. Assisted-by: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Andrew Yong <me@ndoo.sg> Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
co-authored by
Ben Meadors
parent
269b974e96
commit
dd509a8ecf
+38
-5
@@ -36,19 +36,52 @@ GeoCoord::GeoCoord(double lat, double lon, int32_t alt) : _altitude(alt)
|
||||
GeoCoord::setCoords();
|
||||
}
|
||||
|
||||
// Initialize all the coordinate systems
|
||||
// Initialize DMS eagerly (cheap, most commonly used); UTM/MGRS/OSGR/OLC are computed lazily on
|
||||
// first access via their getters (see ensure*() below), since most callers never touch them.
|
||||
void GeoCoord::setCoords()
|
||||
{
|
||||
double lat = _latitude * 1e-7;
|
||||
double lon = _longitude * 1e-7;
|
||||
GeoCoord::latLongToDMS(lat, lon, _dms);
|
||||
GeoCoord::latLongToUTM(lat, lon, _utm);
|
||||
GeoCoord::latLongToMGRS(lat, lon, _mgrs);
|
||||
GeoCoord::latLongToOSGR(lat, lon, _osgr);
|
||||
GeoCoord::latLongToOLC(lat, lon, _olc);
|
||||
_utmValid = false;
|
||||
_mgrsValid = false;
|
||||
_osgrValid = false;
|
||||
_olcValid = false;
|
||||
_dirty = false;
|
||||
}
|
||||
|
||||
void GeoCoord::ensureUTM() const
|
||||
{
|
||||
if (!_utmValid) {
|
||||
GeoCoord::latLongToUTM(_latitude * 1e-7, _longitude * 1e-7, _utm);
|
||||
_utmValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GeoCoord::ensureMGRS() const
|
||||
{
|
||||
if (!_mgrsValid) {
|
||||
GeoCoord::latLongToMGRS(_latitude * 1e-7, _longitude * 1e-7, _mgrs);
|
||||
_mgrsValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GeoCoord::ensureOSGR() const
|
||||
{
|
||||
if (!_osgrValid) {
|
||||
GeoCoord::latLongToOSGR(_latitude * 1e-7, _longitude * 1e-7, _osgr);
|
||||
_osgrValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GeoCoord::ensureOLC() const
|
||||
{
|
||||
if (!_olcValid) {
|
||||
GeoCoord::latLongToOLC(_latitude * 1e-7, _longitude * 1e-7, _olc);
|
||||
_olcValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt)
|
||||
{
|
||||
// If marked dirty or new coordinates
|
||||
|
||||
Reference in New Issue
Block a user