Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[uss_qualifier/utm] Use active volumes for activated op intents; [mock_uss/scdsc] Enforce active volume for activated op intent; Fix #217 #237

Merged
merged 12 commits into from
Oct 18, 2023
Merged
14 changes: 14 additions & 0 deletions monitoring/mock_uss/scdsc/flight_planning.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from datetime import datetime
from typing import Optional, List, Callable

import arrow
from uas_standards.astm.f3548.v21 import api as f3548_v21
from uas_standards.astm.f3548.v21.constants import OiMaxVertices, OiMaxPlanHorizonDays
from uas_standards.interuss.automated_testing.scd.v1 import api as scd_api
Expand Down Expand Up @@ -68,6 +69,19 @@ def validate_request(req_body: scd_api.InjectFlightRequest, locality: Locality)
f"Operational intent specifies an off-nominal volume while being in {req_body.operational_intent.state} state"
)

# Validate intent is currently active if in Activated state
# I.e. at least one volume has start time in the past and end time in the future
if req_body.operational_intent.state == OperationalIntentState.Activated:
now = arrow.utcnow().datetime
active_volume = Volume4DCollection.from_interuss_scd_api(
req_body.operational_intent.volumes
+ req_body.operational_intent.off_nominal_volumes
).has_active_volume(now)
if not active_volume:
raise PlanningError(
f"Operational intent is activated but has no volume currently active (now: {now})"
)


def check_for_disallowed_conflicts(
req_body: scd_api.InjectFlightRequest,
Expand Down
6 changes: 6 additions & 0 deletions monitoring/monitorlib/geotemporal.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,3 +570,9 @@ def to_f3548v21(self) -> List[f3548v21.Volume4D]:

def to_interuss_scd_api(self) -> List[interuss_scd_api.Volume4D]:
return [v.to_interuss_scd_api() for v in self.volumes]

def has_active_volume(self, time_ref: datetime) -> bool:
return any(
vol.time_start.datetime <= time_ref <= vol.time_end.datetime
for vol in self.volumes
)
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ FlightIntentsResource that provides the following flight intents:
- `invalid_too_far_away`: reference time mutation: reference time pulled back so that it is like the operational intent is attempted to be planned more than OiMaxPlanHorizon = 30 days ahead of time
- `valid_conflict_tiny_overlap`: volumes mutation: has a volume that overlaps with `valid_op_intent` just above IntersectionMinimumPrecision = 1cm in a way that must result as a conflict

Because the scenario involves activation of intents, all activated intents must be active during the execution of the
test scenario, i.e. they must start before the reference time plus planning time duration. Additionally, their end time
must leave sufficient time for the execution of the test scenario. For the sake of simplicity, it is recommended to set
the start and end times of all the intents to the same range.

### tested_uss
FlightPlannerResource that will be tested for its validation of operational intents.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import arrow

from monitoring.monitorlib.geotemporal import Volume4DCollection
from monitoring.uss_qualifier.common_data_definitions import Severity
from uas_standards.astm.f3548.v21.api import OperationalIntentState
Expand Down Expand Up @@ -56,10 +58,10 @@ def __init__(
self.tested_uss = tested_uss.flight_planner
self.dss = dss.dss

flight_intents = flight_intents.get_flight_intents()
_flight_intents = flight_intents.get_flight_intents()

extents = []
for intent in flight_intents.values():
for intent in _flight_intents.values():
extents.extend(intent.request.operational_intent.volumes)
extents.extend(intent.request.operational_intent.off_nominal_volumes)
self._intents_extent = Volume4DCollection.from_interuss_scd_api(
Expand All @@ -73,12 +75,25 @@ def __init__(
self.invalid_too_far_away,
self.valid_conflict_tiny_overlap,
) = (
flight_intents["valid_flight"],
flight_intents["valid_activated"],
flight_intents["invalid_too_far_away"],
flight_intents["valid_conflict_tiny_overlap"],
_flight_intents["valid_flight"],
_flight_intents["valid_activated"],
_flight_intents["invalid_too_far_away"],
_flight_intents["valid_conflict_tiny_overlap"],
)

now = arrow.utcnow().datetime
for intent_name, intent in _flight_intents.items():
if (
intent.request.operational_intent.state
== OperationalIntentState.Activated
):
assert Volume4DCollection.from_interuss_scd_api(
intent.request.operational_intent.volumes
+ intent.request.operational_intent.off_nominal_volumes
).has_active_volume(
now
), f"at least one volume of activated intent {intent_name} must be active now (now is {now})"

assert (
self.valid_flight.request.operational_intent.state
== OperationalIntentState.Accepted
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,60 +21,65 @@ Otherwise, the FlightIntentsResource must provide the following flight intents:

<table>
<tr>
<th>Flight intent ID</th><!-- TODO: remove mention of time ranges -->
<th>Flight intent ID</th><
<th>Flight name</th>
<th>Priority</th>
<th>State</th><!-- TODO: Update with usage_state and uas_state when new flight planning API is adopted -->
<th>Must conflict with</th>
<th>Must not conflict with</th>
</tr>
<tr>
<td><code>flight_1_planned_time_range_A</code></td>
<td><code>flight_1_planned_vol_A</code></td>
<td rowspan="2">Flight 1</td>
<td rowspan="8">Any (but all the same)</td>
<td>Accepted</td>
<td rowspan="2">Flight 2</td>
<td rowspan="2">N/A</td>
</tr>
<tr>
<td><code>flight_1_activated_time_range_A</code></td>
<td><code>flight_1_activated_vol_A</code></td>
<td>Activated</td>
</tr>
<tr>
<td><code>flight_1_activated_time_range_A_extended</code></td>
<td><code>flight_1_activated_vol_A_extended</code></td>
<td>Flight 1m</td>
<td>Activated</td>
<td>Flight 2</td>
<td>N/A</td>
</tr>
<tr>
<td><code>flight_1_planned_time_range_B</code></td>
<td><code>flight_1_planned_vol_B</code></td>
<td rowspan="2">Flight 1c</td>
<td>Planned</td>
<td rowspan="2">N/A</td>
<td rowspan="2">Flight 2</td>
</tr>
<tr>
<td><code>flight_1_activated_time_range_B</code></td>
<td><code>flight_1_activated_vol_B</code></td>
<td>Activated</td>
</tr>
<tr>
<td><code>flight_2_equal_prio_planned_time_range_B</code></td>
<td><code>flight_2_equal_prio_planned_vol_B</code></td>
<td rowspan="3">Flight 2</td>
<td>Planned</td>
<td rowspan="3">Flight 1, Flight 1m</td>
<td rowspan="3">Flight 1c</td>
</tr>
<tr>
<td><code>flight_2_equal_prio_activated_time_range_B</code></td>
<td><code>flight_2_equal_prio_activated_vol_B</code></td>
<td>Activated</td>
</tr>
<tr>
<td><code>flight_2_equal_prio_nonconforming_time_range_A</code></td>
<td><code>flight_2_equal_prio_nonconforming_vol_A</code></td>
<td>Nonconforming</td>
</tr>
</table>

Because the scenario involves activation of intents, all activated intents must be active during the execution of the
test scenario, i.e. they must start before the reference time plus planning time duration. Additionally, their end time
must leave sufficient time for the execution of the test scenario. For the sake of simplicity, it is recommended to set
the start and end times of all the intents to the same range.

### tested_uss
FlightPlannerResource that is under test and will manage flight 1.

Expand Down
Loading
Loading