Commit 1b804987 authored by Trishna Saeharaseelan's avatar Trishna Saeharaseelan
Browse files

refactor: docs and schemas

parent 4ba55ad5
This commit is part of merge request !2. Comments created here will be created in the context of that merge request.
# Message Formats (DRAFT) # Overview
Consists of all messages transferred into and out of the Communications Backbone. Message type schemas will be developed once reviewing each platform's data and statuses defined by each partner. This project repository is a collaborative workspace. It consists of all messages transferred into and out of the Communications Backbone. Message type schemas will be developed once reviewing each vehicle's data and statuses defined by each partner.
**[Reference Slides](https://planetocean15.sharepoint.com/sites/IUKSoAR/Shared%20Documents/Forms/AllItems.aspx?id=%2Fsites%2FIUKSoAR%2FShared%20Documents%2FTechnical%2FTechnical%20meetings%2FDiscussions%E2%80%94%20Backbone%20Message%20Formats%2Epdf&viewid=1d649f5f%2Dd30e%2D482f%2Dbd77%2D9316a0023bf9&parent=%2Fsites%2FIUKSoAR%2FShared%20Documents%2FTechnical%2FTechnical%20meetings)**
## Message Types # Guidelines on Collaborating in this Workspace
| Type | Summary of File | Human-Readable |
|--------------------------- | ------------------------------------------------------------------------------------------------ | ----------------|
| `autonomy_configuration` |  Autonomy Engine's Configuration file (sent by each C2 if there are any changes) | Yes | ### Quick Links
| `autonomy_mission_plan` |  Mission plan generated by Autonomy Engine per platform | Yes | 1. Schema Fields Definitions
| `mission_plan` |  Encoded/serialized platform-specific mission plan **(shared filepath)** | No | 2. JSON Schema Examples
| `platform_status` |  Encoded/serialized platform-specific platform status **(shared filepath)** | No | 3. To view schema docs via Swagger UI, run the command below and go to `http://127.0.0.1:5000/soardocs`
| `platform_status` | Decoded/de-serialized generic platform status | Yes | ```
| `observation` |  Encoded/serialized observation data from platform for Autonomy Engine **(shared filepath)** | No | python3 docs/generate_swagger.py
| `observation` |  Decoded/de-serialized observation data from platform for Autonomy Engine | Yes | ```
*Disclaimer: These are *not* endpoints. Purely for schema representation.
# Message Types
* Each message below will be treated as the `payload` that are wrapped in a `full_message_format` that includes a `message_header`.
| Type | Summary of File | Serialized/Compiled in Vehicle-Specific Format? |
| --------------------------| ---------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `planning_configuration` | Autonomy Engine's Configuration file (if c2 needs to update its respective vehicle directly) | No |
| `mission_plan` | Mission plan generated by Autonomy Engine per vehicle | No |
| `encoded_mission_plan` | Encoded/serialized vehicle-specific mission plan | Yes |
| `encoded_vehicle_status` | Encoded/serialized vehicle-specific vehicle status | Yes |
| `vehicle_status` | Decoded/de-serialized generic vehicle status | No |
| `encoded_observation` | Encoded/serialized observation data from vehicle for Autonomy Engine | Yes |
| `observation` | Decoded/de-serialized observation data from vehicle for Autonomy Engine | No |
| `acknowledgement` | Decoded/de-serialized acknowledgement message from the Hydrosurv Adapater | No |
-----------------------------------
## Breakdown of Message Sources & Types ## Breakdown of Message Sources & Types
### 1/ Autonomy Engine ### 1/ Autonomy Engine
#### Transmit #### Transmit
* mission plan _(sent per platform)_ * mission plan _(sent per vehicle??)_
* TBD: * TBD:
* Will emergency commands be sent via the autonomy engine (from the GUI) or directly to the C2s? * Will emergency commands be sent via the autonomy engine (from the GUI) or directly to the C2s?
...@@ -27,7 +49,7 @@ Consists of all messages transferred into and out of the Communications Backbone ...@@ -27,7 +49,7 @@ Consists of all messages transferred into and out of the Communications Backbone
* decoded ecosub status message * decoded ecosub status message
* decoded reav status message * decoded reav status message
* decoded autosub-hover status message * decoded autosub-hover status message
* decoded ecosub observation data _(from squad 1 platforms)_ * decoded ecosub observation data _(from squad 1 vehicles)_
---------------------------------- ----------------------------------
...@@ -35,7 +57,7 @@ Consists of all messages transferred into and out of the Communications Backbone ...@@ -35,7 +57,7 @@ Consists of all messages transferred into and out of the Communications Backbone
#### Transmit #### Transmit
* compiled ecosub mission plan * compiled ecosub mission plan
* decoded ecosub status message * decoded ecosub status message
* configuration file * autonomy configuration file
* decoded ecosub observation data * decoded ecosub observation data
...@@ -50,7 +72,7 @@ Consists of all messages transferred into and out of the Communications Backbone ...@@ -50,7 +72,7 @@ Consists of all messages transferred into and out of the Communications Backbone
#### Transmit #### Transmit
* compiled autosub-hover mission plan * compiled autosub-hover mission plan
* decoded autosub-hover status message * decoded autosub-hover status message
* configuration file * autonomy configuration file
#### Receive #### Receive
...@@ -78,8 +100,8 @@ Consists of all messages transferred into and out of the Communications Backbone ...@@ -78,8 +100,8 @@ Consists of all messages transferred into and out of the Communications Backbone
* encoded autosub status message * encoded autosub status message
* encoded ecosub observation data * encoded ecosub observation data
* TBD: * TBD:
* are there acknowledgment messages from platforms? * are there acknowledgment messages from vehicles?
* how are we receiving beacon messages per platform? * how are we receiving beacon messages per vehicle?
#### Receive #### Receive
* compiled ecosub mission plan * compiled ecosub mission plan
...@@ -88,3 +110,39 @@ Consists of all messages transferred into and out of the Communications Backbone ...@@ -88,3 +110,39 @@ Consists of all messages transferred into and out of the Communications Backbone
* compiled ecosub emergency command * compiled ecosub emergency command
* compiled reav emergency command * compiled reav emergency command
* compiled autosub emergency command * compiled autosub emergency command
------------------------------------
## Message Data Flow Summary
| Partner | Message Type | Source | Destination | Via Comms Backbone? | Contains Serialized Vehicle-Specific File? | Comment |
| --------------- | ---------------------- | ----------------- | ---------------------- | ------------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------- |
| Autonomy Engine | vehicle status | C2’s | Autonomy Engine | Yes | No | |
| Autonomy Engine | Hydrosurv/Ecosub/Ah1 |
| Autonomy Engine | mission plan | Autonomy Engine | C2’s | Yes | No | |
| Autonomy Engine | Hydrosurv/Ecosub/Ah1 |
| Autonomy Engine | autonomy configuration | GUI | ALL | Yes | No | Common file sent to all partners – to store |
| Autonomy Engine | autonomy configuration | C2’s | Autonomy Engine | Yes | No | IF REQUIRED ONLY, UPDATE STORED FILE. |
| Autonomy Engine | Hydrosurv/Ecosub/Ah1 |
| Hydrosurv | vehicle status | Hydrosurv C2 | Autonomy Engine | Yes | No | |
| Hydrosurv | mission plan | Autonomy Engine | Hydrosurv C2 | Yes | No | |
| Hydrosurv | mission plan | Hydrosurv C2 | Reav-60 | No | Yes | |
| Hydrosurv | autonomy configuration | GUI | Hydrosurv C2 (ALL) | Yes | No | Common file sent to all partners – to store |
| Hydrosurv | autonomy configuration | Hydrosurv C2 | GUI | Yes | No | IF REQUIRED ONLY, UPDATE STORED FILE. |
| Hydrosurv | acknowledgment | Hydrosurv C2 | Comms Backbone (Audit) | Yes | No | When hydrosurv adapter has (a) Received, (b) Sent Plan to Reav, and (c) Executed by Reav |
| Planet Ocean | vehicle status | Ecosub | Hydrosurv Adapter | No | Yes | |
| Planet Ocean | vehicle status | Hydrosurv Adapter | Ecosub C2 | Yes | Yes | |
| Planet Ocean | vehicle status | Ecosub C2 | Autonomy Engine | Yes | No | |
| Planet Ocean | mission plan | Autonomy Engine | Ecosub C2 | Yes | No | |
| Planet Ocean | mission plan | Ecosub C2 | Hydrosurv Adapter | Yes | Yes | |
| Planet Ocean | mission plan | Hydrosurv Adapter | Ecosub | No | Yes | Via Hermes + Router |
| Planet Ocean | autonomy configuration | GUI | Ecosub C2 (ALL) | Yes | No | Common file sent to all partners – to store |
| Planet Ocean | autonomy configuration | Hydrosurv C2 | GUI | Yes | No | IF REQUIRED ONLY, UPDATE STORED FILE. |
| Planet Ocean | observation | Ecosub | Hydrosurv Adapter | No | Yes | Via Hermes + Router |
| Planet Ocean | observation | Hydrosurv Adapter | Ecosub C2 | Yes | Yes | |
| Planet Ocean | observation | Ecosub C2 | Autonomy Engine | Yes | No | |
| Planet Ocean | vehicle status | AH1 | Hydrosurv Adapter | No | Yes | Via Hermes + Router |
| NOC | vehicle status | Hydrosurv Adapter | NOC C2 | Yes | Yes | |
| NOC | vehicle status | NOC C2 | Autonomy Engine | Yes | No | |
| NOC | mission plan | Autonomy Engine | NOC C2 | Yes | No | |
| NOC | mission plan | NOC C2 | Hydrosurv Adapter | Yes | Yes | |
| NOC | mission plan | Hydrosurv Adapter | AH1 | No | Yes | Via Hermes + Router |
| NOC | autonomy configuration | GUI | NOC C2 (ALL) | Yes | No | Common file sent to all partners – to store |
| NOC | autonomy configuration | Hydrosurv C2 | GUI | Yes | No | IF REQUIRED ONLY, UPDATE STORED FILE. |
\ No newline at end of file
from flask_restx import Api, fields from flask_restx import Api
from flask import Flask from flask import Flask
import os # import os
__all__ = [ __all__ = [
"docs", "docs",
"formats", "formats",
# "parsers",
] ]
app = Flask(__name__) app = Flask(__name__)
api = Api(app) api = Api(app)
from . import api
import os import os
......
This diff is collapsed.
//**************************************************************** //****************************************************************
// File: config.json (THIS FILE WILL BE IN JSON FORMAT, NOT JSONC) // File: config.json (THIS FILE WILL BE IN JSON FORMAT, NOT JSONC)
// Description: This file is configured by the respective // Description: This file is configured by the respective
// platform's C2 if a platform is no longer active or change // vehicle's C2 if a vehicle is no longer active or change
// a configured value. // a configured value.
// //
// Notes: All comments in this document will be stripped out // Notes: All comments in this document will be stripped out
...@@ -24,24 +24,24 @@ ...@@ -24,24 +24,24 @@
} }
}, },
"survey_team": { "survey_team": {
"no_of_platforms": 3, // int "no_of_vehicles": 3, // int
"platforms": [ "vehicles": [
{ {
"id": 1, // int "id": 1, // int
"platform": "ecosub", // str "vehicle": "ecosub", // str
"platform_serial": "eco101", // str "vehicle_serial": "eco101", // str
"active": true // bool "active": true // bool
}, },
{ {
"id": 2, "id": 2,
"platform": "ecosub", // str "vehicle": "ecosub", // str
"platform_serial": "eco-102", // str "vehicle_serial": "eco-102", // str
"active": true // bool "active": true // bool
}, },
{ {
"id": 3, // int "id": 3, // int
"platform": "ecosub", // str "vehicle": "ecosub", // str
"platform_serial": "ecosub3", // str "vehicle_serial": "ecosub3", // str
"active": true // bool "active": true // bool
} }
], ],
...@@ -51,12 +51,12 @@ ...@@ -51,12 +51,12 @@
}, },
"detail_team": { "detail_team": {
"execute_stage": true, // bool "execute_stage": true, // bool
"no_of_platforms": 1, // int "no_of_vehicles": 1, // int
"platforms": [ "vehicles": [
{ {
"id": 1, // int "id": 1, // int
"platform": "autosub-hover", // str "vehicle": "autosub-hover", // str
"platform_serial": "ah1", // str "vehicle_serial": "ah1", // str
"active": true // bool "active": true // bool
} }
], ],
......
...@@ -10,14 +10,14 @@ __all__ = [ ...@@ -10,14 +10,14 @@ __all__ = [
] ]
message_types = [ message_types = [
"platform_status", "vehicle_status",
"mission_plan_ecosub", "mission_plan_ecosub",
"mission_plan_reav", "mission_plan_reav",
"mission_plan_autosub", "mission_plan_autosub",
] # TODO: Add full range of message types once scoped out ] # TODO: Add full range of message types once scoped out
message_header_schema = api.model( full_message_schema = api.model(
"MessageHeader", "FullMessageSchema",
{ {
"timestamp": fields.DateTime( "timestamp": fields.DateTime(
required=True, required=True,
...@@ -43,33 +43,59 @@ message_header_schema = api.model( ...@@ -43,33 +43,59 @@ message_header_schema = api.model(
"type": fields.String( "type": fields.String(
required=True, required=True,
description="Type of message", description="Type of message",
example="platform_status", example="vehicle_status",
),
"payload": fields.Raw(
required=True,
description="Content of Message",
# example="{}",
),
}
)
constraints_schema = api.model(
"ConstraintsSchema",
{
"min_altitude": fields.Float(
required=True,
description="Minimum altitude set for squad.",
example=15.2,
),
"min_velocity": fields.Float(
required=True,
description="Minimum velocity set for squad.",
example=0.1,
),
"max_velocity": fields.Float(
required=True,
description="Maximum altitude set for squad.",
example=0.9,
), ),
# "payload":# TODO: schema applicable changes according to "type"
}, },
) )
platform_schema = api.model( vehicle_schema = api.model(
"PlatformSchema", "vehicleSchema",
{ {
"platform_ID": fields.Integer( "vehicle_ID": fields.Integer(
required=True, required=True,
description="unique identifier for platform", description="unique identifier for vehicle",
example="ah-1", example="ah-1",
), ),
"serial": fields.Integer( "serial": fields.Integer(
required=True, required=True,
description="platform serial number", description="vehicle serial number",
example="ah-1", example="ah-1",
), ),
"model": fields.Integer( "model": fields.Integer(
required=True, required=True,
description="platform serial number", description="vehicle serial number",
example="ah-1", example="ah-1",
), ),
"constraints": fields.Nested(constraints_schema),
"active": fields.Boolean( "active": fields.Boolean(
required=False, required=False,
description="platform in mission", description="When a vehicle is in deployment (executing a mission plan) this should be True",
example=True, example=True,
), ),
}, },
......
"""
schemas: configuration sent to Autonomy Engine (i.e. during an emergency,
if a platform needs to be removed from the mission planning)
"""
from . import api, message_header_schema, platform_schema
from flask_restx import fields
squad_metadata_schema = api.model(
"SquadMetadataSchema",
{
"squad_ID": fields.Integer(
required=True,
description="platform serial number",
example="ah-1",
),
"no_of_platforms": fields.Integer(
required=True,
description="number of platform serial number",
example="ah-1",
),
"platforms": fields.List(
fields.Nested(platform_schema),
required=True,
description="Metadata pf each platform",
),
"squad_mission_type": fields.String(
required=True,
description="Survey or Detail",
example="survey",
),
"squad_state": fields.Boolean(
required=True,
description="True if given Squad is executing mission type "
+ "according to the Autonomy Engine plan",
example=False,
),
},
)
constraints_schema = api.model(
"ConstraintsSchema",
# TODO: Should this be per platform instead of squad?
{
"min_altitude": fields.Float(
required=True,
description="Minimum altitude set for squad.",
example=15.2,
),
"min_velocity": fields.Float(
required=True,
description="Minimum velocity set for squad.",
example=0.1,
),
"max_velocity": fields.Float(
required=True,
description="Maximum altitude set for squad.",
example=0.9,
),
},
)
environment_config_schema = api.model( # TODO: Discuss how regions are defined
"EnvironmentConfig",
{
"region_of_interest": fields.String(),
"exclusion_zone": fields.String(),
},
)
# Main Autonomy Configuration Schema
autonomy_configuration_schema = api.model(
"SquadConfigurationSchema",
{
"message": fields.Nested(
message_header_schema,
required=True,
description="Message header",
),
"ID": fields.Integer(
required=True,
description="Unique identifier tagged to version of this"
+ " configuration plan",
example=3,
),
"time": fields.String(
required=True,
description="",
example="",
),
"squads": fields.Nested(
squad_metadata_schema,
required=False,
description="Details of each squad",
),
"environment": fields.Nested(
environment_config_schema,
required=False,
description="Region of interest and exclusion zone",
),
},
)
"""
schemas: configuration sent to Autonomy Engine (i.e. during an emergency,
if a vehicle needs to be removed from the mission planning)
"""
from . import api, message_header_schema
from flask_restx import fields
mission_plan_schema = api.model(
"MissionPlan",
{
"message": fields.Nested(
message_header_schema,
required=True,
description="Message header",
),
"ID": fields.Integer(
required=True,
description="Unique identifier tagged to version of this"
+ " configuration plan",
example=3,
),
"time": fields.String(
required=True,
description="",
example="",
),
"vehicle_ID": fields.Integer(
required=False,
description="Details of each squad",
),
"payload": fields.Raw(
required=True,
)
},
)
""" """
schema: platform-specific decoded status message (DRAFT) schema: vehicle-specific decoded status message (DRAFT)
""" """
from . import message_header_schema, platform_schema, api from . import message_header_schema, vehicle_schema, api
from flask_restx import fields from flask_restx import fields
...@@ -13,16 +13,33 @@ observation_schema = api.model( ...@@ -13,16 +13,33 @@ observation_schema = api.model(
required=True, required=True,
description="Message header", description="Message header",
), ),
"platform": fields.Nested(platform_schema), "vehicle": fields.Nested(vehicle_schema),
"time": fields.String( "time": fields.String(
required=True, required=True,
description="Timestamp of message", description="Timestamp of message",
example="2022-11-16T00:00:00Z", example="2022-11-16T00:00:00Z",
), ),
"discuss_other_fields": fields.String( # "observation_type" ==> payloads tied to different types maybe?
# properties of each observation?
"points_of_interest": fields.Float(
required=False, required=False,
description="", # we can track the version of the AE plan? description="Points from features of interest identified by vehicle if any found. DEFINE FORMAT.",
example="", example="",
), ),
"region_surveyed": fields.Float(
required=False,
description="Region surveyed by given vehicle. DEFINE FORMAT. GEOJSON?",
example="",
),
"quality_of_points": fields.Float(
required=False,
description="Quality/strength of points from features of interest identified by vehicle. DEFINE FORMAT.",
example=0.98,
),
"additional_data": fields.Raw(
required=False,
description="Placeholder field for any additional data",
example={"sensor_payload": False},
),
} }
) )
\ No newline at end of file
""" """
schemas: configuration sent to Autonomy Engine (i.e. during an emergency, schemas: configuration sent to Autonomy Engine (i.e. during an emergency,
if a platform needs to be removed from the mission planning) if a vehicle needs to be removed from the mission planning)
""" """
from . import api, message_header_schema, platform_schema from . import api, message_header_schema, vehicle_schema
from flask_restx import fields from flask_restx import fields
...@@ -11,62 +11,32 @@ squad_metadata_schema = api.model( ...@@ -11,62 +11,32 @@ squad_metadata_schema = api.model(
{ {
"squad_ID": fields.Integer( "squad_ID": fields.Integer(
required=True, required=True,
description="platform serial number", description="Identifier of given squad",
example="ah-1", example="ah-1",
), ),
"no_of_platforms": fields.Integer( "no_of_vehicles": fields.Integer(
required=True, required=True,
description="number of platform serial number", description="number of vehicles",
example="ah-1", example="ah-1",
), ),
"platforms": fields.List( "vehicles": fields.List(
fields.Nested(platform_schema), fields.Nested(vehicle_schema),
required=True, required=True,
description="Metadata pf each platform", description="Squad consists of these vehicles",
), ),
"squad_mission_type": fields.String( "squad_mission_type": fields.String(
required=True, required=True,
description="Survey or Detail", description="Mission of given squad: `tracking`, `survey`, `inspection`",
example="survey", example="survey",
), ),
"squad_state": fields.Boolean( "squad_state": fields.Boolean(
required=True, required=True,
description="True if given Squad is executing mission type " description="In execution, Waiting.. <define further>",
+ "according to the Autonomy Engine plan",
example=False, example=False,
), ),
}, },
) )
constraints_schema = api.model(
"ConstraintsSchema",
# TODO: Should this be per platform instead of squad?
{
"min_altitude": fields.Float(
required=True,
description="Minimum altitude set for squad.",
example=15.2,
),
"min_velocity": fields.Float(
required=True,
description="Minimum velocity set for squad.",
example=0.1,
),
"max_velocity": fields.Float(
required=True,
description="Maximum altitude set for squad.",
example=0.9,
),
},
)
environment_config_schema = api.model( # TODO: Discuss how regions are defined
"EnvironmentConfig",
{
"region_of_interest": fields.String(),
"exclusion_zone": fields.String(),
},
)
# Main Autonomy Configuration Schema # Main Autonomy Configuration Schema
autonomy_configuration_schema = api.model( autonomy_configuration_schema = api.model(
"SquadConfigurationSchema", "SquadConfigurationSchema",
...@@ -92,10 +62,66 @@ autonomy_configuration_schema = api.model( ...@@ -92,10 +62,66 @@ autonomy_configuration_schema = api.model(
required=False, required=False,
description="Details of each squad", description="Details of each squad",
), ),
"environment": fields.Nested( "region_of_operation": fields.Raw(
environment_config_schema, required=True,
required=False, description="Using GEOJSON, exact region of interest EXCLUDING exclusion zone",
description="Region of interest and exclusion zone", example={
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"coordinates": [
[
[
-4.187143188645706,
50.37072283932642
],
[
-4.202697005964865,
50.368816892405874
],
[
-4.203156724702808,
50.365640144076906
],
[
-4.19449868846155,
50.362267670845654
],
[
-4.187373048015246,
50.35933489062816
],
[
-4.1859938917992565,
50.36207215780212
],
[
-4.188598964651192,
50.36471151593676
],
[
-4.192506573927574,
50.367350727294706
],
[
-4.188675584440716,
50.36837704762925
],
[
-4.187143188645706,
50.37072283932642
]
]
],
"type": "Polygon"
# "projection": coordinate system used
}
}
]
}
), ),
}, },
) )
""" """
schema: platform-specific decoded status message (DRAFT) schema: vehicle-specific decoded status message (DRAFT)
""" """
from . import message_header_schema, platform_schema, api from . import message_header_schema, vehicle_schema, api
from flask_restx import fields from flask_restx import fields
# TODO: Discuss nomenclature > platform or vehicle? # TODO: Discuss nomenclature > vehicle or vehicle?
gps_schema = api.model( gps_schema = api.model(
"GPS", "GPS",
{ {
"gps_source": fields.Float( # TODO: TBD with partners "gps_source": fields.Float( # TODO: TBD with partners
required=False, required=False,
description="Source of gps position. E.g. Beacon", description="Source of gps position. E.g. USBL (external), vehicle itself (internal)",
example="internal", example="internal",
), ),
"latitude_type": fields.String( "latitude_type": fields.String(
...@@ -26,53 +26,109 @@ gps_schema = api.model( ...@@ -26,53 +26,109 @@ gps_schema = api.model(
), ),
"latitude": fields.Float( "latitude": fields.Float(
required=False, required=False,
description="Latitude in <insert units>", description="Latitude in <DEFINE UNITS>",
example="", example="",
), ),
"longitude": fields.Float( "longitude": fields.Float(
required=False, required=False,
description="Longitude in <insert units>", description="Longitude in <DEFINE UNITS>",
example="", example="",
), ),
"depth": fields.Float( "depth": fields.Float(
required=False, required=False,
description="", description="Depth in <DEFINE UNITS>",
example="", example="",
), ),
"gps_fix_seconds_ago": fields.Float( "altitude": fields.Float(
required=False, required=False,
description="", description="Altitude in <DEFINE UNITS>",
example="", example="",
), ),
# "gps_fix_seconds_ago": fields.Float(
# required=False,
# description="",
# example="",
# ),
}, },
) )
platform_status_message_schema = api.model( # battery_schema = api.model(
"PlatformStatusMessage", # "Battery",
# {
# "voltage_v": fields.Float(
# required=True,
# description="Volts",
# example=23.0,
# ),
# "current_amps": fields.Float(
# required=False,
# description="Amps",
# example=1.2,
# ),
# "current_usage_amphours": fields.Float(
# required=False,
# description="Amp-Hours",
# example=1.2,
# ),
# "wattage_w": fields.Float(
# required=False,
# description="Watts",
# example=23.0,
# ),
# "wattage_usage_watthours": fields.Float(
# required=False,
# description="Watt-Hours",
# example=23.0,
# ),
# "remaining_capacity": fields.Float(
# required=False,
# description="Battery remaining capacity % provided by respective C2 if any.",
# example=80.0,
# ),
# }
# )
sensor_schema = api.model(
"Sensor",
{
"sensor_name": fields.String(
required=False,
description="Name of sensor (e.g. MBES for AH1 and SideScan for Ecosub",
example="MBES",
),
"sensor_status": fields.Boolean(
required=False,
description="Sensor switched on (True) or off (False)",
example=True,
),
"additional_data": fields.Raw(
required=False,
description="Add any additional sensor-related data here.",
example={"sensor_loadtime_seconds": 30.0},
),
}
)
vehicle_status_message_schema = api.model(
"vehicleStatusMessage",
{ {
"message": fields.Nested( "message": fields.Nested(
message_header_schema, message_header_schema,
required=True, required=True,
description="Message header", description="Message header",
), ),
"platform": fields.Nested(platform_schema), "vehicle": fields.Nested(vehicle_schema),
"time": fields.String( "vehicle_state": fields.String(
required=True, # TODO: Define dictionary with potential STATES of each vehicle
description="Timestamp of message",
example="2022-11-16T00:00:00Z",
),
"version": fields.Integer(
required=False, required=False,
description="", # we can track the version of the AE plan? description="Current state executed by vehicle. E.g. "
example="",
),
"platform_state": fields.String(
# TODO: Define dictionary with potential STATES of each platform
required=True,
description="Current state executed by platform. E.g. "
+ "STOP, IDLE, ABORT.", + "STOP, IDLE, ABORT.",
example="IDLE", example="IDLE",
), ),
"autonomy_mission_ID": fields.Integer(
required=False,
description="Last mission plan ID (according to Autonomy Engine's mission plan number) executed by vehicle",
example=1,
),
"mission_track_number": fields.Integer( "mission_track_number": fields.Integer(
required=False, required=False,
description=( description=(
...@@ -86,39 +142,49 @@ platform_status_message_schema = api.model( ...@@ -86,39 +142,49 @@ platform_status_message_schema = api.model(
description="Estimated distance to reach next waypoint", description="Estimated distance to reach next waypoint",
example=124.3, example=124.3,
), ),
"c2_health_status": fields.String( "speed_over_ground": fields.Float(
required=False,
description="",
example=124.3,
),
"water_current_velocity": fields.Float(
required=False,
description="",
example=124.3,
),
"thrust_applied": fields.Float(
required=False, required=False,
description="Health status extracted by respective platform's C2 " description="TODO: Needs further consideration",
example=124.3,
),
"health_status": fields.String(
required=False,
description="Health status extracted by respective vehicle "
+ "if any diagnosis available checks on sensors", + "if any diagnosis available checks on sensors",
example="Warning", example="Warning",
), ),
"gps_data": fields.Nested(gps_schema), "gps_data": fields.List(
"battery_voltage": fields.Float( fields.Nested(gps_schema), # TODO: TBD Do we want a list of gps readings to allow > 1 reading i.e. vehicle + usbl
required=True, required=True,
description="Volts", description="Metadata pf each vehicle",
example=23.0,
),
"battery_current": fields.Float(
required=False,
description="Amps",
example=1.2,
), ),
"battery_current_per_hour": fields.Float( "localisation_error": fields.Float(
required=False, required=False,
description="Amp-Hours", description="Localisation error at last USBL update.",
example=1.2, example="",
), ),
"battery_wattage": fields.Float( "usbl_fix_seconds_ago": fields.Float(
required=False, required=False,
description="Watts", description="",
example=23.0, example="",
), ),
"battery_wattage_per_hour": fields.Float( "battery_remaining_capacity": fields.Float(
required=False, required=False,
description="Watt-Hours", description="Battery remaining capacity % provided by respective C2 if any.",
example=23.0, example=80.0,
), ),
"sensor_config": fields.Nested(sensor_schema), # TODO: TBD Do we want a list of sensors to allow > 1 sensor
}, },
) )
# TBD: Do we append beacon positions with platform positions? # TBD: Do we append beacon positions with vehicle positions?
"""
schema: platform-specific decoded status message (DRAFT)
"""
from . import message_header_schema, platform_schema, api
from flask_restx import fields
# TODO: Discuss nomenclature > platform or vehicle?
gps_schema = api.model(
"GPS",
{
"gps_source": fields.Float( # TODO: TBD with partners
required=False,
description="Source of gps position. E.g. Beacon",
example="internal",
),
"latitude_type": fields.String(
required=False,
description="",
example="",
),
"longitude_type": fields.String(
required=False,
description="",
example="",
),
"latitude": fields.Float(
required=False,
description="Latitude in <insert units>",
example="",
),
"longitude": fields.Float(
required=False,
description="Longitude in <insert units>",
example="",
),
"depth": fields.Float(
required=False,
description="",
example="",
),
"gps_fix_seconds_ago": fields.Float(
required=False,
description="",
example="",
),
},
)
platform_status_message_schema = api.model(
"PlatformStatusMessage",
{
"message": fields.Nested(
message_header_schema,
required=True,
description="Message header",
),
"platform": fields.Nested(platform_schema),
"time": fields.String(
required=True,
description="Timestamp of message",
example="2022-11-16T00:00:00Z",
),
"version": fields.Integer(
required=False,
description="", # we can track the version of the AE plan?
example="",
),
"platform_state": fields.String(
# TODO: Define dictionary with potential STATES of each platform
required=True,
description="Current state executed by platform. E.g. "
+ "STOP, IDLE, ABORT.",
example="IDLE",
),
"mission_track_number": fields.Integer(
required=False,
description=(
"Track number - stage in mission (e.g. "
+ "4 --> Waypoint 3 to Waypoint 4)"
),
example=4,
),
"range_to_go": fields.Float(
required=False,
description="Estimated distance to reach next waypoint",
example=124.3,
),
"c2_health_status": fields.String(
required=False,
description="Health status extracted by respective platform's C2 "
+ "if any diagnosis available checks on sensors",
example="Warning",
),
"gps_data": fields.Nested(gps_schema),
"battery_voltage": fields.Float(
required=True,
description="Volts",
example=23.0,
),
"battery_current": fields.Float(
required=False,
description="Amps",
example=1.2,
),
"battery_current_per_hour": fields.Float(
required=False,
description="Amp-Hours",
example=1.2,
),
"battery_wattage": fields.Float(
required=False,
description="Watts",
example=23.0,
),
"battery_wattage_per_hour": fields.Float(
required=False,
description="Watt-Hours",
example=23.0,
),
},
)
# TBD: Do we append beacon positions with platform positions?
Flask
flask-restx
flasgger
\ No newline at end of file
#!/bin/bash
firefox "$1"
python3 docs/generate_swagger.py
./urlopener "https://google.com"
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment