Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions monitoring/monitorlib/geo.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from enum import Enum

import numpy as np
import pyproj
import s2sphere
import shapely.geometry
from implicitdict import ImplicitDict
Expand Down Expand Up @@ -696,6 +697,33 @@ def egm96_geoid_offset(p: s2sphere.LatLng) -> float:
return _egm96.ev(-lat, lng)


def egm2008_geoid_offset(p: s2sphere.LatLng) -> float:
"""Estimate the EGM2008 geoid height above the WGS84 ellipsoid.

Args:
p: Point where offset should be estimated.

Returns: Meters above WGS84 ellipsoid of the EGM2008 geoid at p.
"""

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).


Please ensure this comply with your policies, and avoid multiple downloads by mounting the directoy '/root/.local/share/proj/' to a docker volume.
""")

transformer = pyproj.Transformer.from_crs(
"EPSG:4979", # WGS 84 -- 3D
"EPSG:4326+3855", # WGS 84 (2D) + EGM2008 height (vertical)
always_xy=True,
)

_, _, ortho_height = transformer.transform(p.lng().degrees, p.lat().degrees, 0)

return -ortho_height


def center_of_mass(in_points: list[LatLng]) -> LatLng:
"""Compute the center of mass of a polygon defined by a list of points."""
if len(in_points) == 0:
Expand Down
1 change: 1 addition & 0 deletions monitoring/uss_qualifier/run_locally.sh
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ docker run ${docker_args} --name uss_qualifier \
-e PYTHONBUFFERED=1 \
-e AUTH_SPEC=${AUTH_SPEC} \
-e AUTH_SPEC_2=${AUTH_SPEC_2} \
-e PROJ_NETWORK \
${PRIVATE_REPOS_ENV_FLAG} \
-e MONITORING_GITHUB_ROOT=${MONITORING_GITHUB_ROOT:-} \
-v "$(pwd)/$OUTPUT_DIR:/app/$OUTPUT_DIR" \
Expand Down
31 changes: 25 additions & 6 deletions monitoring/uss_qualifier/scenarios/uspace/netrid/msl.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
)

from monitoring.monitorlib.fetch import Query, QueryType
from monitoring.monitorlib.geo import egm96_geoid_offset
from monitoring.monitorlib.geo import egm96_geoid_offset, egm2008_geoid_offset
from monitoring.uss_qualifier.configurations.configuration import ParticipantID
from monitoring.uss_qualifier.resources.netrid import NetRIDObserversResource
from monitoring.uss_qualifier.scenarios.astm.netrid.common.nominal_behavior import (
Expand Down Expand Up @@ -110,12 +110,31 @@ def _evaluate_msl_altitude(self, queries: list[Query]):
and flight.most_recent_position is not None
):
with self.check("MSL altitude is correct", participant_id) as check:
geoid_offset = egm96_geoid_offset(
s2sphere.LatLng.from_degrees(
flight.most_recent_position.lat,
flight.most_recent_position.lng,
if (
flight.most_recent_position.msl_alt.reference_datum
== AltitudeReference.EGM96
):
geoid_offset = egm96_geoid_offset(
s2sphere.LatLng.from_degrees(
flight.most_recent_position.lat,
flight.most_recent_position.lng,
)
)
)
elif (
flight.most_recent_position.msl_alt.reference_datum
== AltitudeReference.EGM2008
):
geoid_offset = egm2008_geoid_offset(
s2sphere.LatLng.from_degrees(
flight.most_recent_position.lat,
flight.most_recent_position.lng,
)
)
else:
raise Exception(
"Internal error: ACCEPTABLE_DATUMS of netrid/msl.py don't match the datum we can check"
)

expected_msl_alt = (
flight.most_recent_position.alt - geoid_offset
)
Expand Down
Loading