From 446619b72f6e56fa91fa73fbd1327f974e2a0174 Mon Sep 17 00:00:00 2001 From: Benjamin Pelletier Date: Tue, 21 Feb 2023 09:08:35 -0800 Subject: [PATCH] Update to v0.1.0 of the InterUSS RID injection API (#8) --- interfaces/interuss/automated_testing | 2 +- .../automated_testing/rid/v1/injection.py | 391 +++++++++++++++++- tools/openapi_conversion/generate_apis.sh | 3 +- 3 files changed, 386 insertions(+), 10 deletions(-) diff --git a/interfaces/interuss/automated_testing b/interfaces/interuss/automated_testing index fa3a5f5..8c83e27 160000 --- a/interfaces/interuss/automated_testing +++ b/interfaces/interuss/automated_testing @@ -1 +1 @@ -Subproject commit fa3a5f544161c408f50255630a23b670c74a67d1 +Subproject commit 8c83e2735c762f6fee8d6ca62ee1c1c0d479512c diff --git a/src/uas_standards/interuss/automated_testing/rid/v1/injection.py b/src/uas_standards/interuss/automated_testing/rid/v1/injection.py index 2f340e2..4575622 100644 --- a/src/uas_standards/interuss/automated_testing/rid/v1/injection.py +++ b/src/uas_standards/interuss/automated_testing/rid/v1/injection.py @@ -1,18 +1,398 @@ -"""Data types and operations from Remote ID Test Data Injection 0.0.1 OpenAPI""" +"""Data types and operations from Remote ID Test Data Injection 0.1.0 OpenAPI""" # This file is autogenerated; do not modify manually! from __future__ import annotations from enum import Enum -from typing import Dict, List +from typing import Dict, List, Optional from uas_standards import Operation -from implicitdict import ImplicitDict +from implicitdict import ImplicitDict, StringBasedDateTime -from uas_standards.astm.f3411.v19.api import RIDFlightDetails +RIDFlightID = str +"""ID, unique to a remote ID service provider, which identifies a particular flight for which the remote ID service provider is providing remote ID services. + +The following characters are not allowed: \\0 \\t \\r \\n # % / : ? @ [ \\ ] +""" + + +class RIDAuthData(ImplicitDict): + """Additional authentication data.""" + + format: Optional[int] = 0 + """Format of additional authentication data. + + 0: None + 1: UAS ID Signature + 2: Operator ID Signature + 3: Message Set Signature + 4: Authentication Provided by Network Remote ID + 5: Specific Method + 6-9: Reserved for Spec + 10-15: Available for Private Use + """ + + data: Optional[str] = "" + """Authentication data in form specified by `format`.""" + + +class HorizontalAccuracy(str, Enum): + """This is the NACp enumeration from ADS-B, plus 1m for a more complete range for UAs. + + `HAUnknown`: Unknown horizontal accuracy + + `HA10NMPlus`: > 10NM (18.52km) + + `HA10NM`: < 10NM (18.52km) + + `HA4NM`: < 4NM (7.408km) + + `HA2NM`: < 2NM (3.704km) + + `HA1NM`: < 1NM (1852m) + + `HA05NM`: < 0.5NM (926m) + + `HA03NM`: < 0.3NM (555.6m) + + `HA01NM`: < 0.1NM (185.2m) + + `HA005NM`: < 0.05NM (92.6m) + + `HA30m`: < 30m + + `HA10m`: < 10m + + `HA3m`: < 3m + + `HA1m`: < 1m + """ + + HAUnknown = "HAUnknown" + HA10NMPlus = "HA10NMPlus" + HA10NM = "HA10NM" + HA4NM = "HA4NM" + HA2NM = "HA2NM" + HA1NM = "HA1NM" + HA05NM = "HA05NM" + HA03NM = "HA03NM" + HA01NM = "HA01NM" + HA005NM = "HA005NM" + HA30m = "HA30m" + HA10m = "HA10m" + HA3m = "HA3m" + HA1m = "HA1m" + + +class VerticalAccuracy(str, Enum): + """This is the GVA enumeration from ADS-B, plus some finer values for UAs. + + `VAUnknown`: Unknown vertical accuracy + + `VA150mPlus`: > 150m + + `VA150m`: < 150m + + `VA45m`: < 45m + + `VA25m`: < 25m + + `VA10m`: < 10m + + `VA3m`: < 3m + + `VA1m`: < 1m + """ + + VAUnknown = "VAUnknown" + VA150mPlus = "VA150mPlus" + VA150m = "VA150m" + VA45m = "VA45m" + VA25m = "VA25m" + VA10m = "VA10m" + VA3m = "VA3m" + VA1m = "VA1m" + + +class SpeedAccuracy(str, Enum): + """This is the same enumeration scale and values from ADS-B NACv. + + `SAUnknown`: Unknown speed accuracy + + `SA10mpsPlus`: > 10 m/s + + `SA10mps`: < 10 m/s + + `SA3mps`: < 3 m/s + + `SA1mps`: < 1 m/s + + `SA03mps`: < 0.3 m/s + """ + + SAUnknown = "SAUnknown" + SA10mpsPlus = "SA10mpsPlus" + SA10mps = "SA10mps" + SA3mps = "SA3mps" + SA1mps = "SA1mps" + SA03mps = "SA03mps" + + +class RIDHeightReference(str, Enum): + """The reference datum above which the height is reported.""" + + TakeoffLocation = "TakeoffLocation" + GroundLevel = "GroundLevel" + + +class RIDHeight(ImplicitDict): + """A relative altitude for the purposes of remote ID.""" + + distance: float + """Distance above reference datum. This value is provided in meters and must have a minimum resolution of 1 meter.""" + + reference: RIDHeightReference + """The reference datum above which the height is reported.""" + + +Latitude = float +"""Degrees of latitude north of the equator, with reference to the WGS84 ellipsoid.""" + + +Longitude = float +"""Degrees of longitude east of the Prime Meridian, with reference to the WGS84 ellipsoid.""" + + +class LatLngPoint(ImplicitDict): + """Point on the earth's surface.""" + + lng: Longitude + + lat: Latitude + + +Altitude = float +"""An altitude, in meters, above the WGS84 ellipsoid.""" + + +class RIDOperationalStatus(str, Enum): + """Indicates operational status of associated aircraft.""" + + Undeclared = "Undeclared" + Ground = "Ground" + Airborne = "Airborne" + Emergency = "Emergency" + RemoteIDSystemFailure = "RemoteIDSystemFailure" + + +class RIDAircraftType(str, Enum): + """Type of aircraft for the purposes of remote ID. + + `VTOL` is a fixed wing aircraft that can take off vertically. `Helicopter` includes multirotor. + """ + + NotDeclared = "NotDeclared" + Aeroplane = "Aeroplane" + Helicopter = "Helicopter" + Gyroplane = "Gyroplane" + VTOL = "VTOL" + Ornithopter = "Ornithopter" + Glider = "Glider" + Kite = "Kite" + FreeBalloon = "FreeBalloon" + CaptiveBalloon = "CaptiveBalloon" + Airship = "Airship" + FreeFallOrParachute = "FreeFallOrParachute" + Rocket = "Rocket" + TetheredPoweredAircraft = "TetheredPoweredAircraft" + GroundObstacle = "GroundObstacle" + Other = "Other" + HybridLift = "HybridLift" + + +class UAClassificationEUCategory(str, Enum): + EUCategoryUndefined = "EUCategoryUndefined" + Open = "Open" + Specific = "Specific" + Certified = "Certified" + + +class UAClassificationEUClass(str, Enum): + EUClassUndefined = "EUClassUndefined" + Class0 = "Class0" + Class1 = "Class1" + Class2 = "Class2" + Class3 = "Class3" + Class4 = "Class4" + Class5 = "Class5" + Class6 = "Class6" + + +UAClassificationEU = dict +"""Expected keys: +* category +* class +""" + + + +class OperatorAltitudeAltitude_type(str, Enum): + """Source of data for the altitude field.""" + + Takeoff = "Takeoff" + Dynamic = "Dynamic" + Fixed = "Fixed" + + +class OperatorAltitude(ImplicitDict): + """Altitude associated with the Remote Pilot""" + + altitude: Optional[float] + """Provides the Operator Altitude based on WGS-84 height above ellipsoid (HAE) (See Geodetic Altitude). This value is provided in meters and must have a minimum resolution of 1 m.""" + + altitude_type: Optional[OperatorAltitudeAltitude_type] + """Source of data for the altitude field.""" + + +SpecificSessionID = str +"""A unique 20 byte ID intended to identify a specific flight (session) while providing a +greater level of privacy to the operator. The first byte is the registered unique Specific Session ID +Type maintained by a registrar (see Annex A5), and the remaining 19 bytes is the Session ID per the +Specific Session ID Type specification. + +Initial scheme registry entries include: + +0 – reserved +1 – Internet Engineering Task Force (IETF) Drone Remote Identification Protocol (DRIP) entity ID +2 – IEEE 1609.2 HashedID8 + +Expressed as a hexadecimal string of the underlying data bytes. A recipient should ignore any dashes in this value. If fewer than 20 bytes are specified, the remaining bytes at the end are assumed to have value 0. +""" + + +class UASID(ImplicitDict): + """Identification of the UAS performing this flight. At least one field of this object must be specified.""" + + serial_number: Optional[str] = "" + """This is expressed in the CTA-2063-A Serial Number format.""" + + registration_id: Optional[str] = "" + """If a CAA provides a method of registering UAS, this number is provided by the CAA or its authorized representative. Format is ., ASCII encoded, only uppercase letters (A-Z), dot (.), and digits (0-9) are allowed. Example is valid for the US.""" + + utm_id: Optional[str] = "" + """A UTM-provided universally unique ID traceable to a non-obfuscated ID that acts as a "session id" to protect exposure of operationally sensitive information.""" + + specific_session_id: Optional[SpecificSessionID] + + +class RIDAircraftPosition(ImplicitDict): + """Position of an aircraft as reported for remote ID purposes.""" + + lat: Latitude + + lng: Longitude + + alt: float + """Geodetic altitude (NOT altitude above launch, altitude above ground, or EGM96): aircraft distance above the WGS84 ellipsoid as measured along a line that passes through the aircraft and is normal to the surface of the WGS84 ellipsoid. This value is provided in meters and must have a minimum resolution of 1 meter.""" + + accuracy_h: Optional[HorizontalAccuracy] + """Horizontal error that is likely to be present in this reported position. Required when `extrapolated` field is true and always in the entry for the current state.""" + + accuracy_v: Optional[VerticalAccuracy] + """Vertical error that is likely to be present in this reported position. Required when `extrapolated` field is true and always in the entry for the current state.""" + + extrapolated: Optional[bool] + """True if this position was generated primarily by computation rather than primarily from a direct instrument measurement. Assumed false if not specified.""" + + pressure_altitude: Optional[float] + """The uncorrected altitude (based on reference standard 29.92 inHg, 1013.25 mb) provides a reference for algorithms that utilize "altitude deltas" between aircraft. This value is provided in meters and must have a minimum resolution of 1 meter.""" + + +class RIDFlightDetails(ImplicitDict): + """Details about a flight reported by a remote ID service provider. At least one of the registration or serial fields must be filled if required by CAA.""" + + id: str + """ID for this flight, matching argument in request.""" + + operator_id: Optional[str] + """CAA-issued registration/license ID for the remote pilot or operator. """ + + operator_location: Optional[LatLngPoint] + """Location of party controlling the aircraft.""" + + operation_description: Optional[str] + """Free-text field that enables the operator to describe the purpose of a flight, if so desired.""" + + auth_data: Optional[RIDAuthData] + + serial_number: Optional[str] + """Can be specified when no registration ID exists and required by law in a region. This is expressed in the ANSI/CTA-2063-A Physical Serial Number format.""" + + registration_number: Optional[str] + """If a CAA provides a method of registering UAS, this number is provided by the CAA or its authorized representative. Required when required by law in a region.""" + + uas_id: Optional[UASID] + + operator_altitude: Optional[OperatorAltitude] + + eu_classification: Optional[UAClassificationEU] + """When this field is specified, the Classification Type is "European Union". If no other classification field is specified, the Classification Type is "Undeclared".""" + + +class RIDRecentAircraftPosition(ImplicitDict): + time: StringBasedDateTime + """Time at which this position applied. RFC 3339 format, per OpenAPI specification.""" + + position: RIDAircraftPosition + + +class RIDAircraftState(ImplicitDict): + """State of an aircraft for the purposes of remote ID.""" + + timestamp: StringBasedDateTime + """Time at which this state was valid. This may be the time coming from the source, such as a GPS, or the time when the system computes the values using an algorithm such as an Extended Kalman Filter (EKF). Timestamp must be expressed with a minimum resolution of 1/10th of a second. RFC 3339 format, per OpenAPI specification.""" + + timestamp_accuracy: float + """Declaration of timestamp accuracy, which is the largest difference between Timestamp and true time of applicability for any of the following fields: Latitude, Longitude, Geodetic Altitude, Pressure Altitude of Position, Height. to determine time of applicability of the location data provided. Expressed in seconds, precise to 1/10ths of seconds. The accuracy reflects the 95% uncertainty bound value for the timestamp.""" + + operational_status: Optional[RIDOperationalStatus] + + position: RIDAircraftPosition + + track: float + """Direction of flight expressed as a "True North-based" ground track angle. This value is provided in degrees East of North with a minimum resolution of 1 degree.""" + + speed: float + """Ground speed of flight in meters per second.""" + + speed_accuracy: SpeedAccuracy + """Accuracy of horizontal ground speed.""" + + vertical_speed: float + """Speed up (vertically) WGS84-HAE, m/s.""" + + height: Optional[RIDHeight] + + group_radius: Optional[float] + """Farthest horizontal distance from reported group location at which an aircraft in the group may be located (meters). This value contains the "Operating Area Radius" data from the common data dictionary when group operation area is specified by point-radius.""" + + group_ceiling: Optional[float] + """Maximum altitude (meters WGS84-HAE) of Group Operation. This value contains the "Operating Area Ceiling" data from the common data dictionary when group operation area is specified by point-radius.""" + + group_floor: Optional[float] + """Minimum altitude (meters WGS84-HAE) of Group Operation. If not specified, ground level shall be assumed. This value contains the "Operating Area Floor" data from the common data dictionary when group operation area is specified by point-radius.""" + + group_count: Optional[int] + """When operating a group (or formation or swarm), number of aircraft in group. This value contains the "Operating Area Count" data from the common data dictionary when group operation area is specified by point-radius.""" + + group_time_start: Optional[StringBasedDateTime] + """Time at which a group operation starts. This value contains the "Operation Area Start" data from the common data dictionary when group operation area is specified by point-radius.""" + + group_time_end: Optional[StringBasedDateTime] + """Time at which a group operation starts. This value contains the "Operation Area End" data from the common data dictionary when group operation area is specified by point-radius.""" class TestFlightDetails(ImplicitDict): @@ -25,9 +405,6 @@ class TestFlightDetails(ImplicitDict): """The details of the flight. Follows the RIDFlightDetails schema from the ASTM remote ID standard.""" -from uas_standards.astm.f3411.v19.api import RIDAircraftState - - class TestFlight(ImplicitDict): """The set of data to be injected into a Service Provider system under test for a single flight.""" diff --git a/tools/openapi_conversion/generate_apis.sh b/tools/openapi_conversion/generate_apis.sh index 1f6928e..a9d635f 100755 --- a/tools/openapi_conversion/generate_apis.sh +++ b/tools/openapi_conversion/generate_apis.sh @@ -45,8 +45,7 @@ docker container run -it \ -v "$(pwd)/../..:/resources" \ openapi-python-converter \ --api /resources/interfaces/interuss/automated_testing/rid/v1/injection.yaml \ - --python_output /resources/src/uas_standards/interuss/automated_testing/rid/v1/injection.py \ - --default_package uas_standards.astm.f3411.v19.api + --python_output /resources/src/uas_standards/interuss/automated_testing/rid/v1/injection.py echo "RID observation automated testing" docker container run -it \