Commit ca8d8e59 authored by Trishna Saeharaseelan's avatar Trishna Saeharaseelan
Browse files

refactor: update fields for all formats

......@@ -41,7 +41,7 @@ To add/edit labels, go to [manage labels](https://git.noc.ac.uk/communications-b
| -------- | ---------------------------------------------------------- | ----------------------------------------------------------------------- |
| Project | `SoAR` | Associated project |
| Partner | `Planet Ocean`, `Hydro-Surv`, `NOC`, `RHU` | Associated partner |
| Asset | `ah1`, `ecosub`, `reav`, `autonomy engine` | Associated vehicle |
| Asset | `ah1`, `ecosub`, `reav`, `autonomy engine` | Associated platform |
| Status | `In Sprint Backlog`, `In Progress`, `In Review`, `BLOCKED` | Status of resolving issue |
| Weight | `0`, `1`, `2`, `3`, `5`, `8` | Complexity of issue (0 - quick task and 8 - full 2 weeks worth of work) |
| - | `bug`, `feature` | Type of issue i.e. new feature, bug |
......
# Overview
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.
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 platform's data and statuses defined by each partner.
# 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? |
| Type | Summary of File | Serialized/Compiled in Platform-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 |
| `planning_configuration` | Autonomy Engine's Configuration file (if c2 needs to update its respective platform directly)| No |
| `mission_plan` | Mission plan generated by Autonomy Engine per platform | No |
| `encoded_mission_plan` | Encoded/serialized platform-specific mission plan | Yes |
| `encoded_platform_status`| Encoded/serialized platform-specific platform status | Yes |
| `platform_status` | Decoded/de-serialized generic platform status | No |
| `encoded_observation` | Encoded/serialized observation data from platform for Autonomy Engine | Yes |
| `observation` | Decoded/de-serialized observation data from platform for Autonomy Engine | No |
| `acknowledgement` | Decoded/de-serialized acknowledgement message from the Hydrosurv Adapater | No |
-----------------------------------
## 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
# Quick Links
1. [Schema Fields Definitions](https://git.noc.ac.uk/communications-backbone-system/backbone-message-format/-/tree/7-message-formats-initial/formats)
2. [JSON Schema Examples](https://git.noc.ac.uk/communications-backbone-system/backbone-message-format/-/tree/7-message-formats-initial/examples)
3. [SoAR README.md](https://git.noc.ac.uk/communications-backbone-system/backbone-message-format/-/tree/7-message-formats-initial/project/SOAR_README.md)
\ No newline at end of file
# from flask_marshmallow import Marshmallow
from flask_restx import Api
from flask import Flask
# import os
......@@ -8,4 +10,5 @@ __all__ = [
]
app = Flask(__name__)
api = Api(app)
# api = Marshmallow(app)
......@@ -50,7 +50,7 @@ message_header_schema = api.model(
"type": fields.String(
required=True,
description="Type of message",
example="vehicle_status",
example="platform_status",
),
"payload": fields.Raw(required=True) # TODO: schema applicable changes according to "type"
},
......@@ -88,7 +88,7 @@ full_message_schema = api.model(
"type": fields.String(
required=True,
description="Type of message",
example="vehicle_status",
example="platform_status",
),
"payload": fields.Raw(
required=True,
......@@ -120,28 +120,28 @@ constraints_schema = api.model(
},
)
vehicle_schema = api.model(
"VehicleSchema",
platform_schema = api.model(
"PlatformSchema",
{
"vehicle_ID": fields.Integer(
"platform_ID": fields.Integer(
required=True,
description="unique identifier for vehicle",
description="unique identifier for platform",
example="ah-1",
),
"serial": fields.Integer(
required=True,
description="vehicle serial number",
description="platform serial number",
example="ah-1",
),
"model": fields.Integer(
required=True,
description="vehicle serial number",
description="platform serial number",
example="ah-1",
),
"constraints": fields.Nested(constraints_schema),
"active": fields.Boolean(
required=False,
description="When a vehicle is in deployment (executing a mission plan) this should be True",
description="When a platform is in deployment (executing a mission plan) this should be True",
example=True,
),
},
......@@ -155,15 +155,15 @@ squad_metadata_schema = api.model(
description="Identifier of given squad",
example="ah-1",
),
"no_of_vehicles": fields.Integer(
"no_of_platforms": fields.Integer(
required=True,
description="number of vehicles",
description="number of platforms",
example="ah-1",
),
"vehicles": fields.List(
fields.Nested(vehicle_schema),
"platforms": fields.List(
fields.Nested(platform_schema),
required=True,
description="Squad consists of these vehicles",
description="Squad consists of these platforms",
),
"squad_mission_type": fields.String(
required=True,
......@@ -183,7 +183,7 @@ gps_schema = api.model(
{
"gps_source": fields.Float( # TODO: TBD with partners
required=False,
description="Source of gps position. E.g. USBL (external), vehicle itself (internal)",
description="Source of gps position. E.g. USBL (external), platform itself (internal)",
example="internal",
),
"latitude_type": fields.String(
......@@ -232,7 +232,7 @@ observation_schema = api.model(
required=True,
description="Message header",
),
"vehicle": fields.Nested(vehicle_schema),
"platform": fields.Nested(platform_schema),
"time": fields.String(
required=True,
description="Timestamp of message",
......@@ -242,17 +242,17 @@ observation_schema = api.model(
# properties of each observation?
"points_of_interest": fields.Float(
required=False,
description="Points from features of interest identified by vehicle if any found. DEFINE FORMAT.",
description="Points from features of interest identified by platform if any found. DEFINE FORMAT.",
example="",
),
"region_surveyed": fields.Float(
required=False,
description="Region surveyed by given vehicle. DEFINE FORMAT. GEOJSON?",
description="Region surveyed by given platform. 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.",
description="Quality/strength of points from features of interest identified by platform. DEFINE FORMAT.",
example=0.98,
),
"additional_data": fields.Raw(
......@@ -282,28 +282,28 @@ sensor_schema = api.model(
),
}
)
vehicle_status_message_schema = api.model(
"VehicleStatusMessage",
platform_status_message_schema = api.model(
"platformStatusMessage",
{
"message": fields.Nested(
message_header_schema,
required=True,
description="Message header",
),
"vehicle": fields.Nested(vehicle_schema),
"vehicle_state": fields.String(
# TODO: Define dictionary with potential STATES of each vehicle
"platform": fields.Nested(platform_schema),
"platform_state": fields.String(
# TODO: Define dictionary with potential STATES of each platform
required=False,
description="Current state executed by vehicle. E.g. "
description="Current state executed by platform. E.g. "
+ "STOP, IDLE, ABORT.",
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",
description="Last mission plan ID (according to Autonomy Engine's mission plan number) executed by platform",
example=1,
),
"mission_track_number": fields.Integer(
"mission_track_ID": fields.Integer(
required=False,
description=(
"Track number - stage in mission (e.g. "
......@@ -311,6 +311,11 @@ vehicle_status_message_schema = api.model(
),
example=4,
),
"mission_action_ID": fields.Integer(
required=False,
description="to add description",
example=1,
),
"range_to_go": fields.Float(
required=False,
description="Estimated distance to reach next waypoint",
......@@ -333,14 +338,14 @@ vehicle_status_message_schema = api.model(
),
"health_status": fields.String(
required=False,
description="Health status extracted by respective vehicle "
description="Health status extracted by respective platform "
+ "if any diagnosis available checks on sensors",
example="Warning",
),
"gps_data": fields.List(
fields.Nested(gps_schema), # TODO: TBD Do we want a list of gps readings to allow > 1 reading i.e. vehicle + usbl
fields.Nested(gps_schema), # TODO: TBD Do we want a list of gps readings to allow > 1 reading i.e. platform + usbl
required=True,
description="Metadata pf each vehicle",
description="GPS of each platform",
),
"localisation_error": fields.Float(
required=False,
......@@ -353,8 +358,8 @@ vehicle_status_message_schema = api.model(
example="",
),
"battery_remaining_capacity": fields.Float(
required=False,
description="Battery remaining capacity % provided by respective C2 if any.",
required=True,
description="Battery remaining capacity % provided by respective platform/C2.",
example=80.0,
),
"sensor_config": fields.Nested(sensor_schema), # TODO: TBD Do we want a list of sensors to allow > 1 sensor
......@@ -380,7 +385,7 @@ mission_plan_schema = api.model(
description="",
example="",
),
"vehicle_ID": fields.Integer(
"platform_ID": fields.Integer(
required=False,
description="Details of each squad",
),
......@@ -514,16 +519,16 @@ class MessageWrapper(Resource):
pass
ns2 = api.namespace("vehicle_status", description="vehicle Status Message Format")
ns2 = api.namespace("platform_status", description="platform Status Message Format")
@ns2.route("")
class VehicleStatus(Resource):
@ns2.response(200, "Success", vehicle_status_message_schema)
class platformStatus(Resource):
@ns2.response(200, "Success", platform_status_message_schema)
def get(self):
pass
ns3 = api.namespace(
"autonomy_configuration", description="Autonomy Configuration Format. Do we want region of interest to be per squad, per vehicle or in the main schema?"
"autonomy_configuration", description="Autonomy Configuration Format. Do we want region of interest to be per squad, per platform or in the main schema?"
)
@ns3.route("")
......@@ -533,9 +538,9 @@ class AutonomyConfiguration(Resource):
pass
# @api.route('/mission-plan/<str:vehicle_type')
# @api.doc(params={"vehicle_type": "The type of vehicle of the mission plan to target."})
ns4 = api.namespace("mission_plan", description="Mission Plan Format Per vehicle")
# @api.route('/mission-plan/<str:platform_type')
# @api.doc(params={"platform_type": "The type of platform of the mission plan to target."})
ns4 = api.namespace("mission_plan", description="Mission Plan Format Per platform")
@ns4.route("")
class MissionPlan(Resource):
......@@ -559,7 +564,7 @@ class MissionPlanAutosubHover(Resource):
def get(self):
pass
ns5 = api.namespace("observation", description="Observation Format --> Per vehicle or generic?")
ns5 = api.namespace("observation", description="Observation Format --> Per platform or generic?")
@ns5.route("")
class Observation(Resource):
@ns5.response(200, "Success", observation_schema)
......
//****************************************************************
// File: config.json (THIS FILE WILL BE IN JSON FORMAT, NOT JSONC)
// Description: This file is configured by the respective
// vehicle's C2 if a vehicle is no longer active or change
// a configured value.
//
// Notes: All comments in this document will be stripped out
// during SOAR operations.
// (TODO: RHU to identify values that can and cannot be
// configured).
//----------------------------------------------------------------
// CHANGELOG
// -------------------
// 11-11-2022 Trishna S. Added comments, header, and data types
// for each field.
// 10-11-2022 Izzat K. Converted contents to json schema.
// 06-10-2022 Trishna S. New initialisation file.
//****************************************************************
{
"mission_config": {
"execute_stage": {
"survey": true, // bool
"detail": false // bool
}
},
"survey_team": {
"no_of_vehicles": 3, // int
"vehicles": [
{
"id": 1, // int
"vehicle": "ecosub", // str
"vehicle_serial": "eco101", // str
"active": true // bool
},
{
"id": 2,
"vehicle": "ecosub", // str
"vehicle_serial": "eco-102", // str
"active": true // bool
},
{
"id": 3, // int
"vehicle": "ecosub", // str
"vehicle_serial": "ecosub3", // str
"active": true // bool
}
],
"min_altitude": 0.0, // float
"min_velocity": 0.0, // float
"max_velocity": 0.0 // float
},
"detail_team": {
"execute_stage": true, // bool
"no_of_vehicles": 1, // int
"vehicles": [
{
"id": 1, // int
"vehicle": "autosub-hover", // str
"vehicle_serial": "ah1", // str
"active": true // bool
}
],
"min_altitude": 0.0, // float
"min_velocity": 0.0, // float
"max_velocity": 0.0 // float
},
"environment": {
"region_of_interest": 0.0, // float
"exclusion_zone": 0.0 // float
}
}
\ No newline at end of file
File deleted
{
"reason": "ready",
"gps_source": "internal",
"gps_lat": 60.16048651129611,
"gps_lon": -1.156730960091541,
"gps_fix_seconds_ago": 1665580800,
"alr_data": {
"format_version": "ocsv3",
"message_type": "H",
"message_source": 3,
"transmit_timestamp": 1665580753.564244,
"content_mask": 18410715202459939000,
"depth": -1.304158329963684,
"water_conductivity": 0,
"water_temperature": 0,
"max_depth": 0,
"altitude": 1000,
"min_altitude": 0,
"vehicle_heading": -58.08430862426758,
"water_speed": -0.000008320044798892923,
"time_since_last_gps": 1665580800,
"time_on_surface": 7814.99365234375,
"w_hours": 28.418603897094727,
"battery_current": 0.4806833267211914,
"battery_max_current": 65.45500183105469,
"battery_voltage": 25.113433837890625,
"battery_min_voltage": 23.034000396728516,
"leak_sensor_output": 9,
"ground_fault_sensor_out": 752,
"propeller_rpm": 0,
"rs485_fault_flags": {},
"rs232_fault_flags": {},
"helm_state": {
"8": "idle"
},
"max_abort_link_state": 358,
"health_events": {},
"helm_events": {
"14": "waiting"
},
"log_storage_space": 98649407488,
"sbd_parser_error": {},
"alr_warning": 0,
"compass_align_value": -1.8788431882858276,
"battery_energy_used": 0,
"dead_nodes": {},
"position": {
"latitude": 60.16048651129611,
"longitude": -1.156730960091541
},
"pth_1": {
"pressure_temp": 2.0399177074432373,
"pressure": 593,
"temp": 17.80158233642578,
"rel_humidity": 7
},
"pth_2": {
"pressure_temp": 1.9932914972305298,
"pressure": 574,
"temp": 14.916650772094727,
"rel_humidity": 16
},
"rs232_mute_counts": {
"port00": 0,
"port01": 0,
"port02": 0,
"port03": 0,
"port04": 0,
"port05": 0,
"port06": 0,
"port07": 0,
"port08": 0,
"port09": 0,
"port10": 0,
"port11": 0,
"port12": 0,
"port13": 0,
"port14": 0,
"port15": 0
},
"rs485_mute_counts": {
"port00": 0,
"port01": 0,
"port02": 0,
"port03": 0,
"port04": 0,
"port05": 0,
"port06": 0,
"port07": 0,
"port08": 0,
"port09": 0,
"port10": 0,
"port11": 0,
"port12": 0,
"port13": 0,
"port14": 0,
"port15": 0
},
"helm_state_bitmask": 8388608,
"helm_state_bitstring": "00000000100000000000000000000000",
"helm_events_bitmask": 562949953421312,
"helm_events_bitstring": "0000000000000010000000000000000000000000000000000000000000000000",
"health_events_bitmask": 0,
"health_events_bitstring": "0000000000000000000000000000000000000000000000000000000000000000",
"sbd_parser_error_bitmask": 128,
"sbd_parser_error_bitstring": "10000000",
"dead_nodes_bitmask": 0,
"dead_nodes_bitstring": "0000000000000000000000000000000000000000000000000000000000000000",
"rs232_fault_flags_bitmask": 0,
"rs232_fault_flags_bitstring": "0000000000000000",
"rs485_fault_flags_bitmask": 0,
"rs485_fault_flags_bitstring": "0000000000000000",
"rudder_status": {
"errors": [
"current_info_not_received"
],
"error_bitmask": 16,
"error_bitstring": "00010000",
"angle": 0
},
"sternplane_status": {
"errors": [
"current_info_not_received"
],
"error_bitmask": 16,
"error_bitstring": "00010000",
"angle": 0
},
"auv_roll": -0.8640746474266052,
"auv_pitch": 0.2900053858757019,
"biocam_status": {
"biocam_current_mode": 9,
"biocam_cam_0_image_count": 0,
"biocam_cam_1_image_count": 0,
"biocam_cpu_temperature": 273,
"biocam_cam_0_temperature": 273,
"biocam_cam_1_temperature": 273,
"biocam_available_disk_space": 0
},
"serial_states": {
"port01": {
"3": "on"
},
"port02": {
"3": "on"
},
"port03": {
"0": "off"
},
"port04": {
"0": "off"
},
"port05": {
"0": "off"
},
"port06": {
"0": "off"
},
"port07": {
"0": "off"
},
"port08": {
"0": "off"
},
"port09": {
"0": "off"
},
"port10": {
"3": "on"
},
"port11": {
"3": "on"
},
"port12": {
"0": "off"
},
"port13": {
"3": "on"
},
"port14": {
"0": "off"
},
"port15": {
"0": "off"
},
"port16": {
"0": "off"
}
},
"computed": {}
},
"serial_number": "alr-3",
"time": 1665580753.564244,
"version": "ocsv3",
"_kind": "comms",
"autosub_message_format": {
"git_commit_hash": "ba3e33a9e786772d9642390711cf48b0a08755ea"
}
}
\ No newline at end of file
......@@ -9,8 +9,10 @@ __all__ = [
if x.endswith(".py") and x != "__init__.py"
]
# TODO: Define units for all schemas
message_types = [
"vehicle_status",
"platform_status",
"mission_plan_ecosub",
"mission_plan_reav",
"mission_plan_autosub",
......@@ -43,14 +45,14 @@ full_message_schema = api.model(
"type": fields.String(
required=True,
description="Type of message",
example="vehicle_status",
example="platform_status",
),
"payload": fields.Raw(
required=True,
description="Content of Message",
# example="{}",
),
}
},
)
constraints_schema = api.model(
......@@ -74,31 +76,29 @@ constraints_schema = api.model(
},
)
vehicle_schema = api.model(
"vehicleSchema",
platform_schema = api.model(
"PlatformSchema",
{
"vehicle_ID": fields.Integer(
"platform_ID": fields.Integer(
required=True,
description="unique identifier for vehicle",
description="unique identifier for platform",
example="ah-1",
),
"serial": fields.Integer(
required=True,
description="vehicle serial number",
description="platform serial number",
example="ah-1",
),
"model": fields.Integer(
required=True,
description="vehicle serial number",
description="platform serial number",
example="ah-1",
),
"constraints": fields.Nested(constraints_schema),
"active": fields.Boolean(
required=False,
description="When a vehicle is in deployment (executing a mission plan) this should be True",
description="When a platform is in deployment (executing a mission plan) this should be True",
example=True,
),
},
)
# TODO: Add generic positions schema
# TODO: Define units for all schemas
"""
schemas: Acknowledgement status sent by the surface platform to report
receipt of message.
"""
from . import api, full_message_schema
from flask_restx import fields
acknowledgement_schema = api.model(
"Acknowledgement",
{
"message": fields.Nested(
full_message_schema,
required=True,
description="Message header",
),
"message_ID": fields.Integer(
required=True,
description="Identifier of message received and executed with "
+ "success for mission plans sent by the Autonomy Engine.",
example=202,
),
"status": fields.String(
required=True,
description="Highest level of acknowledgement. I.e. `c2_received`: Received by C2,"
+ " `c2_sent`: Sent from C2->Platform, `executed`: Executed by platform",
),
},
)
"""
schemas: configuration sent to Autonomy Engine (i.e. during an emergency,
if a vehicle needs to be removed from the mission planning)
schemas: Mission plan (un-complied) geenrated by the Autonomy Engine
sent to the respective platform's C2 to compile into a platform-specific
mission plan.
"""
from . import api, message_header_schema
from . import api, full_message_schema
from flask_restx import fields
action_schema = api.model(
"AutonomyEngineAction",
{
"action": fields.String(
required=True,
description="Autonomy Engine's action from `move`, `payload`,"
+ " `dive`, `send_hits`, `scanline`, `scanpoint`.",
example="move",
),
"flight_style": fields.String(
required=False,
description="Platform-specific modes/flight styles to perform next action",
example="orbit",
),
"latitude_waypoint": fields.Float(
required=True,
description="Next waypoint, x-coordinate",
example=-4.187143188645706,
),
"longitude_waypoint": fields.Float(
required=True,
description="Next waypoint, y-coordinate",
example=50.37072283932642,
),
"altitude": fields.Float(
required=False,
description="Altitude of next action",
example=15.0,
),
"depth": fields.Float(
required=False,
description="Depth of next action",
example=15.0,
),
"activate_payload": fields.Boolean(
required=False,
description="To activate/deactivate sensor for Autosub "
+ "Hover-1 --> `MBES` sensor and for EcoSUB --> `Sidescan`",
example=True,
),
"send_environmental_data": fields.Boolean(
required=False,
description="To trigger the platform to send list of observations if any found",
example=False,
),
"scanline": fields.Boolean(
required=False,
description="To trigger the platform to scan-line",
example=False,
),
"scanpoint": fields.Boolean(
required=False,
description="To trigger the platform to send list of observations if any found",
example=False,
),
},
)
mission_plan_schema = api.model(
"MissionPlan",
{
"message": fields.Nested(
message_header_schema,
full_message_schema,
required=True,
description="Message header",
),
"ID": fields.Integer(
"plan_ID": fields.Integer(
required=True,
description="Unique identifier tagged to version of this"
+ " configuration plan",
example=3,
description="Identifier of given mission sequence planned",
example=1,
),
"time": fields.String(
"platform_serial": fields.String(
required=True,
description="",
example="",
description="Serial of target platform to send mission to",
example="reav-60",
),
"vehicle_ID": fields.Integer(
required=False,
description="Details of each squad",
),
"payload": fields.Raw(
"plan": fields.List(
fields.Nested(action_schema),
required=True,
)
description="Sequence of actions/instructions generated by the " +
" Autonomy Engine that should be compiled by the respective C2.",
),
},
)
"""
schema: vehicle-specific decoded status message (DRAFT)
schema: platform-specific decoded status message (DRAFT)
"""
from . import message_header_schema, vehicle_schema, api
from . import message_header_schema, platform_schema, api
from flask_restx import fields
......@@ -13,7 +13,7 @@ observation_schema = api.model(
required=True,
description="Message header",
),
"vehicle": fields.Nested(vehicle_schema),
"platform": fields.Nested(platform_schema),
"time": fields.String(
required=True,
description="Timestamp of message",
......@@ -23,17 +23,17 @@ observation_schema = api.model(
# properties of each observation?
"points_of_interest": fields.Float(
required=False,
description="Points from features of interest identified by vehicle if any found. DEFINE FORMAT.",
description="Points from features of interest identified by platform if any found. DEFINE FORMAT.",
example="",
),
"region_surveyed": fields.Float(
required=False,
description="Region surveyed by given vehicle. DEFINE FORMAT. GEOJSON?",
description="Region surveyed by given platform. 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.",
description="Quality/strength of points from features of interest identified by platform. DEFINE FORMAT.",
example=0.98,
),
"additional_data": fields.Raw(
......@@ -41,5 +41,5 @@ observation_schema = api.model(
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,
if a vehicle needs to be removed from the mission planning)
if a platform needs to be removed from the mission planning)
"""
from . import api, message_header_schema, vehicle_schema
from . import api, full_message_schema, platform_schema
from flask_restx import fields
region_schema = api.model(
"RegionSchema",
{
"region": fields.Raw(
required=True,
description="Using GEOJSON, exact region of interest in rectangle format polygon",
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],
]
],
"type": "Polygon",
},
}
],
},
),
},
)
squad_metadata_schema = api.model(
"SquadMetadataSchema",
{
"squad_ID": fields.Integer(
required=True,
description="Identifier of given squad",
example="ah-1",
example=23,
),
"no_of_vehicles": fields.Integer(
"no_of_platforms": fields.Integer(
required=True,
description="number of vehicles",
example="ah-1",
description="Number of platforms",
example=3,
),
"vehicles": fields.List(
fields.Nested(vehicle_schema),
"platforms": fields.List(
fields.Nested(platform_schema),
required=True,
description="Squad consists of these vehicles",
description="Squad consists of these platforms",
),
"squad_mission_type": fields.String(
required=True,
......@@ -34,15 +64,25 @@ squad_metadata_schema = api.model(
description="In execution, Waiting.. <define further>",
example=False,
),
"region_of_interest": fields.List(
fields.Nested(region_schema),
required=False,
description="Region of interest and exclusion zones per squad.",
),
"exclusion_zones": fields.List(
fields.Nested(region_schema),
required=True,
description="Exclusion zones exclusion zones per squad.",
),
},
)
# Main Autonomy Configuration Schema
autonomy_configuration_schema = api.model(
"SquadConfigurationSchema",
planning_configuration_schema = api.model(
"PlanningConfigurationSchema",
{
"message": fields.Nested(
message_header_schema,
full_message_schema,
required=True,
description="Message header",
),
......@@ -52,76 +92,10 @@ autonomy_configuration_schema = api.model(
+ " configuration plan",
example=3,
),
"time": fields.String(
required=True,
description="",
example="",
),
"squads": fields.Nested(
squad_metadata_schema,
required=False,
description="Details of each squad",
),
"region_of_operation": fields.Raw(
required=True,
description="Using GEOJSON, exact region of interest EXCLUDING 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: vehicle-specific decoded status message (DRAFT)
schema: platform-specific decoded status message (DRAFT)
"""
from . import message_header_schema, vehicle_schema, api
from . import full_message_schema, platform_schema, api
from flask_restx import fields
# TODO: Discuss nomenclature > vehicle or vehicle?
gps_schema = api.model(
"GPS",
{
"gps_source": fields.Float( # TODO: TBD with partners
required=False,
description="Source of gps position. E.g. USBL (external), vehicle itself (internal)",
description="Source of gps position. E.g. USBL (external), platform itself (internal)",
example="internal",
),
"latitude_type": fields.String(
......@@ -44,50 +42,10 @@ gps_schema = api.model(
description="Altitude in <DEFINE UNITS>",
example="",
),
# "gps_fix_seconds_ago": fields.Float(
# required=False,
# description="",
# example="",
# ),
# "gps_fix_seconds_ago"
},
)
# battery_schema = api.model(
# "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",
{
......@@ -106,30 +64,30 @@ sensor_schema = api.model(
description="Add any additional sensor-related data here.",
example={"sensor_loadtime_seconds": 30.0},
),
}
},
)
vehicle_status_message_schema = api.model(
"vehicleStatusMessage",
platform_status_message_schema = api.model(
"platformStatusMessage",
{
"message": fields.Nested(
message_header_schema,
full_message_schema,
required=True,
description="Message header",
),
"vehicle": fields.Nested(vehicle_schema),
"vehicle_state": fields.String(
# TODO: Define dictionary with potential STATES of each vehicle
"platform": fields.Nested(platform_schema),
"platform_state": fields.String(
# TODO: Define dictionary with potential STATES of each platform
required=False,
description="Current state executed by vehicle. E.g. "
description="Current state executed by platform. E.g. "
+ "STOP, IDLE, ABORT.",
example="IDLE",
),
"autonomy_mission_ID": fields.Integer(
"autonomy_plan_ID": fields.Integer(
required=False,
description="Last mission plan ID (according to Autonomy Engine's mission plan number) executed by vehicle",
description="Last mission plan ID (according to Autonomy Engine's mission plan number) executed by platform",
example=1,
),
"mission_track_number": fields.Integer(
"mission_track_ID": fields.Integer(
required=False,
description=(
"Track number - stage in mission (e.g. "
......@@ -137,6 +95,11 @@ vehicle_status_message_schema = api.model(
),
example=4,
),
"mission_action_ID": fields.Integer(
required=False,
description="to add description",
example=1,
),
"range_to_go": fields.Float(
required=False,
description="Estimated distance to reach next waypoint",
......@@ -159,14 +122,16 @@ vehicle_status_message_schema = api.model(
),
"health_status": fields.String(
required=False,
description="Health status extracted by respective vehicle "
description="Health status extracted by respective platform "
+ "if any diagnosis available checks on sensors",
example="Warning",
),
"gps_data": fields.List(
fields.Nested(gps_schema), # TODO: TBD Do we want a list of gps readings to allow > 1 reading i.e. vehicle + usbl
fields.Nested(
gps_schema
), # TODO: TBD Do we want a list of gps readings to allow > 1 reading i.e. platform + usbl
required=True,
description="Metadata pf each vehicle",
description="Metadata pf each platform",
),
"localisation_error": fields.Float(
required=False,
......@@ -179,12 +144,14 @@ vehicle_status_message_schema = api.model(
example="",
),
"battery_remaining_capacity": fields.Float(
required=False,
description="Battery remaining capacity % provided by respective C2 if any.",
required=True,
description="Battery remaining capacity % provided by respective platform/C2.",
example=80.0,
),
"sensor_config": fields.Nested(sensor_schema), # TODO: TBD Do we want a list of sensors to allow > 1 sensor
"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 vehicle positions?
# TBD: Do we append beacon positions with platform positions?
# SoAR Project
Squad of Adaptive Robots Project
-----------------------------------
## Message Data Flow Summary
| Partner | Message Type | Source | Destination | Via Comms Backbone? | Contains Serialized Vehicle-Specific File? |
| ------------ | ---------------------- | --------------------------- | --------------------------- | ------------------- | ------------------------------------------ |
| RHU | platform status | C2’s (Hydrosurv/Ecosub/Ah1) | Autonomy Engine | Yes | No |
| RHU | mission plan | Autonomy Engine | C2’s (Hydrosurv/Ecosub/Ah1) | Yes | No |
| RHU | planning configuration | GUI | Autonomy Engine | Yes | No |
| RHU | observation | Ecosub C2 | Autonomy Engine | Yes | No |
| Hydro-Surv | platform status | Reav-60 | Hydrosurv C2 | No | Yes |
| Hydro-Surv | platform status | Hydrosurv C2 | Autonomy Engine | Yes | No |
| Hydro-Surv | mission plan | Autonomy Engine | Hydrosurv C2 | Yes | No |
| Hydro-Surv | mission plan | Hydrosurv C2 | Reav-60 | No | Yes |
| Hydro-Surv | acknowledgement | Hydrosurv C2 | Comms Backbone (Audit) | Yes | No |
| Planet Ocean | platform status | Ecosub | Hydrosurv Adapter | No | Yes |
| Planet Ocean | platform status | Hydrosurv Adapter | Ecosub C2 | Yes | Yes |
| Planet Ocean | platform 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 |
| Planet Ocean | observation | Ecosub | Hydrosurv Adapter | No | Yes |
| Planet Ocean | observation | Hydrosurv Adapter | Ecosub C2 | Yes | Yes |
| Planet Ocean | observation | Ecosub C2 | Autonomy Engine | Yes | No |
| NOC | platform status | Ecosub | Hydrosurv Adapter | No | Yes |
| NOC | platform status | Hydrosurv Adapter | Ecosub C2 | Yes | Yes |
| NOC | platform status | Ecosub C2 | Autonomy Engine | Yes | No |
| NOC | mission plan | Autonomy Engine | Ecosub C2 | Yes | No |
| NOC | mission plan | Ecosub C2 | Hydrosurv Adapter | Yes | Yes |
| NOC | mission plan | Hydrosurv Adapter | Ecosub | No | Yes |
Flask
flask-restx
flasgger
\ No newline at end of file
flasgger
flask-marshmallow
\ 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