Skip to content

Conversation

@the-glu
Copy link
Contributor

@the-glu the-glu commented Dec 15, 2025

Add support for EGM2008, fixing #1288.

As EGM2008 data is quite big, we do use pyproj and its download feature to download on the fly required data.

Download is opt-in and explained in an error message with explanations if that not the case. I can also make it the default.

Manual testing:

Mock USS returning wrong reference datum:

diff --git a/monitoring/mock_uss/riddp/routes_observation.py b/monitoring/mock_uss/riddp/routes_observation.py
index 6f0bd974..d56b08e8 100644
--- a/monitoring/mock_uss/riddp/routes_observation.py
+++ b/monitoring/mock_uss/riddp/routes_observation.py
@@ -75,7 +75,7 @@ def _make_flight_observation(
 
     p = flight.most_recent_position
     msl_alt_m = p.alt - egm96_geoid_offset(s2sphere.LatLng.from_degrees(p.lat, p.lng))
-    msl_alt = MSLAltitude(meters=msl_alt_m, reference_datum=AltitudeReference.EGM96)
+    msl_alt = MSLAltitude(meters=msl_alt_m, reference_datum=AltitudeReference.EGM2008)
     current_state = observation_api.CurrentState(
         timestamp=p.time.isoformat(),
         timestamp_accuracy=flight.timestamp_accuracy,

->

2025-12-22 08:26:29.269 | WARNING  | monitoring.uss_qualifier.suites.suite:_print_failed_check:71 - New failed check:
  details: 'Altitude for flight d22a1cef-a3e0-437f-92b5-44c1453f4068 at 47.37046517716392,
    8.488080501861498 was reported as 501.65525225916707 meters above the WGS84 ellipsoid,
    and the EGM96 geoid is 47.794551505519706 meters above the WGS84 ellipsoid at this
    point, but the MSL altitude was reported as 454.36510049584 meters above AltitudeReference.EGM2008
    rather than the expected 453.8607007536474 meters
  
    Severity Severity.Medium upgraded to Critical because `stop_fast` flag set true
    in configuration'
  documentation_url: https://github.com/interuss/monitoring/blob/32797bc2d44378c650d3388325e63a7da7bc2e65/monitoring/uss_qualifier/scenarios/uspace/netrid/msl.md#msl-altitude-is-correct-check
  name: MSL altitude is correct
  participants:
  - uss1
  query_report_timestamps:
  - '2025-12-22T08:24:44.570198Z'
  requirements:
  - uspace.article8.MSLAltitude
  severity: Critical
  summary: Reported MSL altitude 454.4m does not match expected MSL altitude 453.9m
  timestamp: '2025-12-22T08:26:29.268479Z'
  
2025-12-22 08:26:29.269 | WARNING  | monitoring.uss_qualifier.suites.suite:_run_test_scenario:184 - FAILURE for "U-space MSL altitude" scenario
2025-12-22 08:26:32.375 | INFO     | monitoring.uss_qualifier.suites.suite:_run_test_suite:193 - Completed test suite U-Space network identification
2025-12-22 08:26:32.501 | INFO     | monitoring.uss_qualifier.suites.suite:_run_test_suite:193 - Completed test suite U-space required services
2025-12-22 08:26:32.503 | WARNING  | __main__:execute_test_run:137 - Final result: FAILURE
2025-12-22 08:26:40.000 | ERROR    | __main__:run_config:242 - Validation failed on test run report for configuration 'configurations.dev.uspace'

Mock USS returning EGM2008 altitudes:

diff --git a/monitoring/mock_uss/riddp/routes_observation.py b/monitoring/mock_uss/riddp/routes_observation.py
index 6f0bd974..75a20187 100644
--- a/monitoring/mock_uss/riddp/routes_observation.py
+++ b/monitoring/mock_uss/riddp/routes_observation.py
@@ -29,7 +29,7 @@ from monitoring.monitorlib import geo
 from monitoring.monitorlib.fetch import rid as fetch
 from monitoring.monitorlib.fetch.rid import Flight
 from monitoring.monitorlib.formatting import limit_resolution
-from monitoring.monitorlib.geo import egm96_geoid_offset
+from monitoring.monitorlib.geo import egm2008_geoid_offset
 from monitoring.monitorlib.mutate import rid as mutate
 from monitoring.monitorlib.rid import RIDVersion
 
@@ -74,8 +74,8 @@ def _make_flight_observation(
         paths.append(current_path)
 
     p = flight.most_recent_position
-    msl_alt_m = p.alt - egm96_geoid_offset(s2sphere.LatLng.from_degrees(p.lat, p.lng))
-    msl_alt = MSLAltitude(meters=msl_alt_m, reference_datum=AltitudeReference.EGM96)
+    msl_alt_m = p.alt - egm2008_geoid_offset(s2sphere.LatLng.from_degrees(p.lat, p.lng))
+    msl_alt = MSLAltitude(meters=msl_alt_m, reference_datum=AltitudeReference.EGM2008)
     current_state = observation_api.CurrentState(
         timestamp=p.time.isoformat(),
         timestamp_accuracy=flight.timestamp_accuracy,

->

2025-12-22 08:33:57.004 | INFO     | __main__:execute_test_run:135 - Final result: SUCCESS
2025-12-22 08:34:04.485 | INFO     | __main__:main:291 - ========== Completed uss_qualifier for configuration configurations.dev.uspace ==========


if not pyproj.network.is_network_enabled(): # pyright:ignore[reportAttributeAccessIssue]
raise Exception("""
To enable EGM2008 conversions, you must allow pyproj to download files to do the conversion. For that, please set PROJ_NETWORK=TRUE in your environment variables.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How large are those? Is it realistic to have them in the CI so that we can add unit tests covering this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If my understanding is correct, I think it's on the order of 150MB which technically we could have in the CI, but I would probably recommend against since it's a rare feature that would consume resources disproportionate to its importance. But, in the absence of CI involvement, we need some kind of indication for why we're confident a change is correct -- in this case, I'd expect some kind of statement like "I temporarily changed mock_uss to report EGM2008 altitudes and the netrid_v22a test configuration passed locally" in the PR description.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the files for the original implementations are in that order ( https://earth-info.nga.mil/index.php?dir=wgs84&action=wgs84 )

It does seems that pyproj's version is around 80M ( https://cdn.proj.org/ , search for EPSG:3855), but that still 10 times actual size of the monitoring's code folder.

For testing, I did a different approach (switched to EGM2008 as reference but still returning EGM98, to ensure it failed as altitudes should be different), but I will do a 'positive' run.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the description of the PR with manual tests results. Note that I did ran the uspace configuration, as the netrid_v22a is not running scenarios.uspace.netrid.msl.MSLAltitude. Is that expected?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, right -- yes, MSLAltitude is a special requirement for U-space and isn't an ASTM requirement, so running in the uspace scenario and not running in netrid_v22a is expected (with hindsight).

@BenjaminPelletier BenjaminPelletier merged commit bbdda85 into interuss:main Dec 22, 2025
21 checks passed
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.

3 participants