Commit 8c944219 authored by Trishna Saeharaseelan's avatar Trishna Saeharaseelan
Browse files

refactor: schemas and ntoes for observation data

parent 3a1cdab5
# Message Formats (DRAFT)
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.
## Types of Messages by Software Component
## Message Types
* All messages will be wrapped in a `message_wrapper` that contains a standard `message_header`.
| Type | Summary of File | Human-Readable | SHARE FILE (Wrapped in Backbone message) |
| -------------------------- | ------------------------------------------------------------------------------------------------ | -------------- |-------------------------------------------|
| `autonomy_configuration` |  Autonomy Engine's Configuration file | Yes | No |
| `mission_plan` |  Encoded/serialized platform-specific mission plan **(shared filepath)** | No | Yes |
| `platform_status\` |  Encoded/serialized platform-specific platform status **(shared filepath)** | No | Yes |
| `platform_status` | Decoded/de-serialized generic platform status | Yes | No |
| `observation` |  Encoded/serialized observation data from platform for Autonomy Engine **(shared filepath)** | No | Yes |
| `observation` |  Decoded/de-serialized observation data from platform for Autonomy Engine | Yes | No |
------------------------------------
## Breakdown of Message Sources & Types
### 1/ Autonomy Engine
#### Transmit
* mission plan _(sent per platform)_
......@@ -14,7 +26,7 @@ Consists of all messages transferred into and out of the Communications Backbone
* decoded ecosub status message
* decoded reav status message
* decoded autosub-hover status message
* decoded ecosub survey data _(from squad 1 platforms)_
* decoded ecosub observation data _(from squad 1 platforms)_
----------------------------------
......@@ -23,13 +35,13 @@ Consists of all messages transferred into and out of the Communications Backbone
* compiled ecosub mission plan
* decoded ecosub status message
* configuration file
* decoded ecosub survey data
* decoded ecosub observation data
#### Receive
* mission plan
* encoded ecosub status message
* encoded ecosub survey data
* encoded ecosub observation data
----------------------------------
......@@ -63,7 +75,7 @@ Consists of all messages transferred into and out of the Communications Backbone
* encoded ecosub status message
* encoded (or is this already decoded?) reav status message
* encoded autosub status message
* encoded ecosub survey data
* encoded ecosub observation data
* TBD:
* are there acknowledgment messages from platforms?
* how are we receiving beacon messages per platform?
......
......@@ -4,74 +4,11 @@ import os
__all__ = [
os.path.splitext(os.path.basename(x))[0]
for x in os.listdir(os.path.dirname(__file__))
if x.endswith(".py") and x != "__init__.py"
"docs",
"formats",
# "parsers",
]
app = Flask(__name__)
api = Api(app)
message_types = [
"platform_status"
] # TODO: Add full range of message types once scoped out
message_header_schema = api.model(
"MessageHeader",
{
"timestamp": fields.String( # TODO: Update to Datetime UTC format
required=True,
description="Timestamp of message",
example="2022-11-16T00:00:00Z",
),
"source": fields.String(
required=True,
description="Where is this message from",
example="autonomy_engine",
),
"destination": fields.String(
required=True,
description="What is the destination of this message",
example="ah-1",
),
"encoded": fields.Boolean(
required=True,
description="Indicate that message raw (encoded) or decoded. "
+ "Options: encoded=True, decoded=False",
example=False,
),
"type": fields.String(
required=True,
description="Type of message",
example="platform_status",
),
},
)
platform_schema = api.model(
"PlatformSchema",
{
"platform_ID": fields.Integer(
required=True,
description="unique identifier for platform",
example="ah-1",
),
"serial": fields.Integer(
required=True,
description="platform serial number",
example="ah-1",
),
"model": fields.Integer(
required=True,
description="platform serial number",
example="ah-1",
),
"active": fields.Boolean(
required=False,
description="platform in mission",
example=True,
),
},
)
# TODO: Add generic positions schema
# TODO: Define units for all schemas
......@@ -215,7 +215,27 @@ gps_schema = api.model(
),
},
)
observation_schema = api.model(
"Observation",
{
"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",
),
"discuss_other_fields": fields.String(
required=False,
description="", # we can track the version of the AE plan?
example="",
),
}
)
platform_status_message_schema = api.model(
"PlatformStatusMessage",
{
......@@ -349,20 +369,26 @@ ns4 = api.namespace("mission_plan", description="Mission Plan Format Per Platfor
@ns4.route("/ecosub")
class MissionPlanEcosub(Resource):
@ns4.response(200, "Success", message_header_schema)
@ns4.response(200, "Success", {})
def get(self):
pass
@ns4.route("/reav")
class MissionPlanReav(Resource):
@ns4.response(200, "Success", message_header_schema)
@ns4.response(200, "Success", {})
def get(self):
pass
@ns4.route("/autosubhover")
class MissionPlanAutosubHover(Resource):
@ns4.response(200, "Success", message_header_schema)
@ns4.response(200, "Success", {})
def get(self):
pass
ns5 = api.namespace("observation", description="Observation Format --> Per Platform or generic?")
@ns5.route("")
class Observation(Resource):
@ns5.response(200, "Success", observation_schema)
def get(self):
pass
if __name__ == "__main__":
app.run()
from flask_restx import fields
from . import api
import os
__all__ = [
os.path.splitext(os.path.basename(x))[0]
for x in os.listdir(os.path.dirname(__file__))
if x.endswith(".py") and x != "__init__.py"
]
message_types = [
"platform_status",
"mission_plan_ecosub",
"mission_plan_reav",
"mission_plan_autosub",
] # TODO: Add full range of message types once scoped out
message_header_schema = api.model(
"MessageHeader",
{
"timestamp": fields.DateTime(
required=True,
description="Timestamp of message",
example="2022-11-16T00:00:00Z",
),
"source": fields.String(
required=True,
description="Where is this message from",
example="autonomy_engine",
),
"destination": fields.String(
required=True,
description="What is the destination of this message",
example="ah-1",
),
"encoded": fields.Boolean(
required=True,
description="Indicate that message raw (encoded) or decoded. "
+ "Options: encoded=True, decoded=False",
example=False,
),
"type": fields.String(
required=True,
description="Type of message",
example="platform_status",
),
# "payload":# TODO: schema applicable changes according to "type"
},
)
platform_schema = api.model(
"PlatformSchema",
{
"platform_ID": fields.Integer(
required=True,
description="unique identifier for platform",
example="ah-1",
),
"serial": fields.Integer(
required=True,
description="platform serial number",
example="ah-1",
),
"model": fields.Integer(
required=True,
description="platform serial number",
example="ah-1",
),
"active": fields.Boolean(
required=False,
description="platform in mission",
example=True,
),
},
)
# TODO: Add generic positions schema
# TODO: Define units for all schemas
"""
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",
),
},
)
"""
schema: platform-specific decoded status message (DRAFT)
"""
from . import message_header_schema, platform_schema, api
from flask_restx import fields
observation_schema = api.model(
"Observation",
{
"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",
),
"discuss_other_fields": fields.String(
required=False,
description="", # we can track the version of the AE plan?
example="",
),
}
)
\ No newline at end of file
"""
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?
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