Skip to content

Commit

Permalink
Add check for astm.f3411.v22a.NET0470,Table1,10-11 current position
Browse files Browse the repository at this point in the history
  • Loading branch information
barroco committed Sep 14, 2023
1 parent 4c60556 commit 00e48f4
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 35 deletions.
13 changes: 5 additions & 8 deletions monitoring/mock_uss/riddp/routes_observation.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
from s2sphere import LatLng
from typing import Dict, List, Optional, Tuple
import arrow
import flask
from loguru import logger
import s2sphere
from uas_standards.astm.f3411.v19.api import ErrorResponse
from uas_standards.astm.f3411.v19.constants import Scope
from uas_standards.astm.f3411.v22a.api import RIDHeight
from uas_standards.astm.f3411.v22a.constants import MaxSpeed

from uas_standards.astm.f3411.v22a.constants import MinHeightResolution
from uas_standards.astm.f3411.v22a.constants import MaxSpeed, MinHeightResolution, MinTrackDirectionResolution
from monitoring.monitorlib import geo
from monitoring.monitorlib.fetch import rid as fetch
from monitoring.monitorlib.fetch.rid import Flight, FetchedISAs, Position
Expand Down Expand Up @@ -62,11 +58,12 @@ def _make_flight_observation(
current_state = observation_api.CurrentState(
timestamp=original_time.isoformat(),
operational_status=flight.operational_status,
track=flight.track,
track=_limit_resolution(flight.track, MinTrackDirectionResolution),
speed=_limit_resolution(flight.speed, MaxSpeed)
)
h = p.height if "height" in p else RIDHeight(distance=-1000)
h.distance = _limit_resolution(h.distance, MinHeightResolution)
h = p.get("height")
if h:
h.distance = _limit_resolution(h.distance, MinHeightResolution)
return observation_api.Flight(
id=flight.id,
most_recent_position=observation_api.Position(lat=p.lat, lng=p.lng, alt=p.alt, height=h),
Expand Down
6 changes: 4 additions & 2 deletions monitoring/monitorlib/fetch/rid.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,19 @@ class Position(ImplicitDict):
time: datetime.datetime
"""Timestamp for the position."""

height: Optional[RIDHeight]

@staticmethod
def from_v19_rid_aircraft_position(
p: v19.api.RIDAircraftPosition, t: v19.api.StringBasedDateTime
) -> Position:
return Position(lat=p.lat, lng=p.lng, alt=p.alt, time=t.datetime)
return Position(lat=p.lat, lng=p.lng, alt=p.alt, time=t.datetime, height=None)

@staticmethod
def from_v22a_rid_aircraft_position(
p: v22a.api.RIDAircraftPosition, t: v22a.api.StringBasedDateTime
) -> Position:
return Position(lat=p.lat, lng=p.lng, alt=p.alt, time=t.datetime)
return Position(lat=p.lat, lng=p.lng, alt=p.alt, time=t.datetime, height=p.get("height"))


class Flight(ImplicitDict):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

from uas_standards.astm.f3411.v22a.constants import SpecialSpeed, MaxSpeed, MinSpeedResolution, SpecialTrackDirection, MinTrackDirection, MaxTrackDirection, MinTrackDirectionResolution

from interfaces.uas_standards.src.uas_standards.astm.f3411.v22a.constants import MinHeightResolution
from interfaces.uas_standards.src.uas_standards.astm.f3411.v22a.constants import MinHeightResolution, \
MinPositionResolution
from monitoring.monitorlib.fetch.rid import (
FetchedFlights,
FlightDetails,
Expand Down Expand Up @@ -67,19 +68,26 @@ def evaluate_sp_flights(
requested_area, f, participants
)

if self._rid_version == RIDVersion.f3411_22a:
for f in observed_flights.flights:
# Evaluate on all flights regardless of where they came from
self._evaluate_operational_status(
f.v22a_value.get("current_state", {}).get("operational_status"),
participants,
)
for f in observed_flights.flights:
# Evaluate on all flights regardless of where they came from
self._evaluate_operational_status(
f.raw.get("current_state", {}).get("operational_status"),
f.operational_status,
participants,
)

def evaluate_dp_flight(
self,
observed_flight: Flight,
participants: List[str],
):
current_state = observed_flight.current_state
self._evaluate_speed(current_state.speed, participants)
self._evaluate_track(current_state.track, participants)
self._evaluate_timestamp(current_state.timestamp, participants)
self._evaluate_operational_status(current_state.operational_status, participants)
self._evaluate_position(observed_flight.most_recent_position, participants)
self._evaluate_height(observed_flight.most_recent_position.get("height"), participants)

def _evaluate_recent_position_time(
self, p: Position, query_time: datetime.datetime, check: PendingCheck
):
Expand Down Expand Up @@ -275,7 +283,7 @@ def _evaluate_plain_uas_id(self, value: str, participants: List[str]):
# TODO: Add specific session id format check
# TODO: Add a check to validate at least one format is correct

def evaluate_timestamp(self, timestamp: str, participants: List[str]):
def _evaluate_timestamp(self, timestamp: str, participants: List[str]):
with self._test_scenario.check(
"Timestamp consistency with Common Dictionary", participants
) as check:
Expand Down Expand Up @@ -318,11 +326,11 @@ def _evaluate_operator_id(self, value: Optional[str], participants: List[str]):
message=f"Unsupported version {self._rid_version}: skipping Operator ID evaluation",
)

def evaluate_speed(self, speed: float, participants: List[str]):
def _evaluate_speed(self, speed: float, participants: List[str]):
with self._test_scenario.check(
"Speed consistency with Common Dictionary", participants
) as check:
if not (0 < speed <= MaxSpeed or round(speed) == SpecialSpeed):
if not (0 <= speed <= MaxSpeed or round(speed) == SpecialSpeed):
check.record_failed(
f"Invalid speed: {speed}",
details=f"The speed shall be greater than 0 and less than {MaxSpeed}. The Special Value {SpecialSpeed} is allowed.",
Expand All @@ -336,7 +344,7 @@ def evaluate_speed(self, speed: float, participants: List[str]):
severity=Severity.Medium,
)

def evaluate_track(self, track: float, participants: List[str]):
def _evaluate_track(self, track: float, participants: List[str]):
with self._test_scenario.check(
"Track Direction consistency with Common Dictionary", participants
) as check:
Expand All @@ -354,7 +362,32 @@ def evaluate_track(self, track: float, participants: List[str]):
severity=Severity.Medium,
)

def evaluate_height(self, height: Optional[RIDHeight], participants: List[str]):
def _evaluate_position(
self, position: Position, participants: List[str]
):
with self._test_scenario.check(
"Current Position consistency with Common Dictionary", participants
) as check:
lat = position.lat
try:
lat = validate_lat(lat)
except ValueError:
check.record_failed(
"Current Position contains an invalid latitude",
details=f"Invalid latitude: {lat}",
severity=Severity.Medium,
)
lng = position.lng
try:
lng = validate_lng(lng)
except ValueError:
check.record_failed(
"Current Position contains an invalid longitude",
details=f"Invalid longitude: {lng}",
severity=Severity.Medium,
)

def _evaluate_height(self, height: Optional[RIDHeight], participants: List[str]):
if height:
with self._test_scenario.check(
"Height consistency with Common Dictionary", participants
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def step_under_test(self: UnitTestScenario):
rid_version=RIDVersion.f3411_22a,
)

evaluator.evaluate_timestamp(value, [])
evaluator._evaluate_timestamp(value, [])

unit_test_scenario = UnitTestScenario(step_under_test).execute_unit_test()
assert unit_test_scenario.get_report().successful == outcome
Expand All @@ -226,7 +226,7 @@ def step_under_test(self: UnitTestScenario):
rid_version=RIDVersion.f3411_22a,
)

evaluator.evaluate_speed(value, [])
evaluator._evaluate_speed(value, [])

unit_test_scenario = UnitTestScenario(step_under_test).execute_unit_test()
assert unit_test_scenario.get_report().successful == outcome
Expand All @@ -245,7 +245,7 @@ def step_under_test(self: UnitTestScenario):
rid_version=RIDVersion.f3411_22a,
)

evaluator.evaluate_track(value, [])
evaluator._evaluate_track(value, [])

unit_test_scenario = UnitTestScenario(step_under_test).execute_unit_test()
assert unit_test_scenario.get_report().successful == outcome
Expand All @@ -266,7 +266,7 @@ def step_under_test(self: UnitTestScenario):
rid_version=RIDVersion.f3411_22a,
)

evaluator.evaluate_height(value, [])
evaluator._evaluate_height(value, [])


unit_test_scenario = UnitTestScenario(step_under_test).execute_unit_test()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,6 @@ def _evaluate_observation(
verified_sps,
)

if observation:
flights: List[Flight] = observation.get("flights", [])
[self._common_dictionary_evaluator.evaluate_timestamp(f.current_state.timestamp, participants=[observer.participant_id]) for f in flights]

def _evaluate_normal_observation(
self,
observer: RIDSystemObserver,
Expand Down Expand Up @@ -385,9 +381,8 @@ def _evaluate_normal_observation(
Severity.Medium,
details=f"{mapping.injected_flight.uss_participant_id}'s flight with injection ID {mapping.injected_flight.flight.injection_id} in test {mapping.injected_flight.test_id} had telemetry index {mapping.telemetry_index} at {injected_telemetry.timestamp} with lat={injected_telemetry.position.lat}, lng={injected_telemetry.position.lng}, alt={injected_telemetry.position.alt}, but {observer.participant_id} observed lat={observed_position.lat}, lng={observed_position.lng}, alt={observed_position.alt} at {query.request.initiated_at}",
)
observed_speed = mapping.observed_flight.current_state.speed
self._common_dictionary_evaluator.evaluate_speed(observed_speed, [observer.participant_id])

self._common_dictionary_evaluator.evaluate_dp_flight(mapping.observed_flight, [observer.participant_id])
# Check that flights using telemetry are not using extrapolated position data
for mapping in mapping_by_injection_id.values():
injected_telemetry = mapping.injected_flight.flight.telemetry[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@ This check validates that the display area of a cluster, measured and provided i

**[astm.f3411.v22a.NET0470](../../../../requirements/astm/f3411/v22a.md)** requires that Net-RID Display Provider shall (NET0470) provide access to required and optional fields to Remote ID Display Applications according to the Common Dictionary. This check validates that the Operator ID, if present, is valid. (**[astm.f3411.v22a.NET0470,Table1,9](../../../../requirements/astm/f3411/v22a.md)**)

#### Current Position consistency with Common Dictionary check

**[astm.f3411.v22a.NET0470](../../../../requirements/astm/f3411/v22a.md)** requires that Net-RID Display Provider shall provide access to required and optional fields to Remote ID Display Applications according to the Common Dictionary. This check validates that the Current Position provided is valid. (**[astm.f3411.v22a.NET0470,Table1,10](../../../../requirements/astm/f3411/v22a.md)** and **[astm.f3411.v22a.NET0470,Table1,11](../../../../requirements/astm/f3411/v22a.md)**). If the observed Current Position do not contain valid latitude and longitude, this check will fail.
TODO: If the resolution is greater than 7 number digits, this check will fail.

#### Height consistency with Common Dictionary check

**[astm.f3411.v22a.NET0470](../../../../requirements/astm/f3411/v22a.md)** requires that Net-RID Display Provider shall provide access to required and optional fields to Remote ID Display Applications according to the Common Dictionary. This check validates that the Track Direction (**[astm.f3411.v22a.NET0470,Table1,14](../../../../requirements/astm/f3411/v22a.md)**) is valid. If the observed Height resolution is less than 1 meter, this check will fail.
Expand All @@ -226,7 +231,7 @@ This check validates that the display area of a cluster, measured and provided i

#### Speed consistency with Common Dictionary check

**[astm.f3411.v22a.NET0470](../../../../requirements/astm/f3411/v22a.md)** requires that Net-RID Display Provider shall provide access to required and optional fields to Remote ID Display Applications according to the Common Dictionary. This check validates that the Speed (**[astm.f3411.v22a.NET0470,Table1,20](../../../../requirements/astm/f3411/v22a.md)**) is valid. If the observed Speed is greater than 254.25 and different than 255, this check will fail. If the Speed resolution is less than 0.25 m/s, this check will fail.
**[astm.f3411.v22a.NET0470](../../../../requirements/astm/f3411/v22a.md)** requires that Net-RID Display Provider shall provide access to required and optional fields to Remote ID Display Applications according to the Common Dictionary. This check validates that the Speed (**[astm.f3411.v22a.NET0470,Table1,20](../../../../requirements/astm/f3411/v22a.md)**) is valid. If the observed Speed is negative or greater than 254.25 or equals 255, this check will fail. If the Speed resolution is less than 0.25 m/s, this check will fail.

#### Operator Location consistency with Common Dictionary check

Expand Down

0 comments on commit 00e48f4

Please sign in to comment.