Skip to content

Commit

Permalink
Add time validation for in-use flight plans
Browse files Browse the repository at this point in the history
  • Loading branch information
BenjaminPelletier committed Dec 8, 2023
1 parent e876850 commit 0a4dfef
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ che_conflicting_flights:
file:
path: file://./test_data/che/flight_intents/conflicting_flights.yaml
# Note that this hash_sha512 field can be safely deleted if the content changes
hash_sha512: a8e9e2130359a9b3eebfa9611344919e19a2210438eebe4212fff4faa7f54d82be8d12f92449e7f5741a1991b172a8e4ba8089834285f4232f96cc37420e9c59
hash_sha512: 26ee66a5065e555512f8b1e354334678dfe1614c6fbba4898a1541e6306341620e96de8b48e4095c7b03ab6fd58d0aeeee9e69cf367e1b7346e0c5f287460792

che_invalid_flight_intents:
$content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,34 +39,36 @@ def validate_flight_intent_templates(
templates: Dict[FlightIntentID, FlightInfoTemplate],
expected_intents: List[ExpectedFlightIntent],
) -> None:
now = arrow.utcnow().datetime
now = Time(arrow.utcnow().datetime)
times = {
TimeDuringTest.StartOfTestRun: Time(now),
TimeDuringTest.StartOfScenario: Time(now),
TimeDuringTest.TimeOfEvaluation: Time(now),
TimeDuringTest.StartOfTestRun: now,
TimeDuringTest.StartOfScenario: now,
TimeDuringTest.TimeOfEvaluation: now,
}
flight_intents = {k: v.resolve(times) for k, v in templates.items()}
validate_flight_intents(flight_intents, expected_intents)
validate_flight_intents(flight_intents, expected_intents, now)

later = now + MAX_TEST_RUN_DURATION
later = Time(now.datetime + MAX_TEST_RUN_DURATION)
times = {
TimeDuringTest.StartOfTestRun: Time(now),
TimeDuringTest.StartOfScenario: Time(later),
TimeDuringTest.TimeOfEvaluation: Time(later),
TimeDuringTest.StartOfTestRun: now,
TimeDuringTest.StartOfScenario: later,
TimeDuringTest.TimeOfEvaluation: later,
}
flight_intents = {k: v.resolve(times) for k, v in templates.items()}
validate_flight_intents(flight_intents, expected_intents)
validate_flight_intents(flight_intents, expected_intents, later)


def validate_flight_intents(
intents: Dict[FlightIntentID, FlightInfo],
expected_intents: List[ExpectedFlightIntent],
now: Time,
) -> None:
"""Validate that `intents` contains all intents meeting all the criteria in `expected_intents`.
Args:
intents: Flight intents we actually have.
expected_intents: Criteria that our flight intents are expected to meet.
now: Current time, for validation that in-use intents include this time.
Raises:
* ValueError when a validation criterion is not met.
Expand All @@ -80,6 +82,34 @@ def validate_flight_intents(
for expected_intent in expected_intents:
intent = intents[expected_intent.intent_id]

# Ensure in-use intent includes now
if intent.basic_information.usage_state == AirspaceUsageState.InUse:
start_time = intent.basic_information.area.time_start
if start_time is None:
raise ValueError(
f"At least one volume in `{expected_intent.intent_id}` is missing a start time"
)
if now.datetime < start_time.datetime:
raise ValueError(
f"When evaluated at {now.datetime.isoformat()}, `{expected_intent.intent_id}`'s start time {start_time.datetime.isoformat()} is in the future even though the intent is indicated as InUse"
)
end_time = intent.basic_information.area.time_end
if end_time is None:
raise ValueError(
f"At least one volume in `{expected_intent.intent_id}` is missing an end time"
)
if now.datetime > end_time.datetime:
raise ValueError(
f"When evaluated at {now.datetime.isoformat()}, `{expected_intent.intent_id}`'s end time {end_time.datetime.isoformat()} is in the past even though the intent is indicated as InUse"
)

# Ensure not-in-use intent does not indicate an off-nominal UAS
if intent.basic_information.usage_state != AirspaceUsageState.InUse:
if intent.basic_information.uas_state != UasState.Nominal:
raise ValueError(
f"`{expected_intent.intent_id}` indicates the intent is not in use ({intent.basic_information.usage_state}), but the UAS state is specified as off-nominal ({intent.basic_information.uas_state})"
)

def named_intents(
name: FlightIntentName,
exclude: ExpectedFlightIntent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ intents:
start_time:
offset_from:
starting_from:
time_during_test: StartOfTestRun
time_during_test: TimeOfEvaluation
offset: -1s
end_time:
offset_from:
starting_from:
time_during_test: StartOfTestRun
time_during_test: TimeOfEvaluation
offset: 8m

astm_f3548_21:
Expand Down Expand Up @@ -131,12 +131,12 @@ intents:
start_time:
offset_from:
starting_from:
time_during_test: StartOfTestRun
time_during_test: TimeOfEvaluation
offset: -1s
end_time:
offset_from:
starting_from:
time_during_test: StartOfTestRun
time_during_test: TimeOfEvaluation
offset: 8m

astm_f3548_21:
Expand Down

0 comments on commit 0a4dfef

Please sign in to comment.