So, we passed the GSoC phase 1 evaluations. Now, that we have a Generic Hydra Server ready, things are getting a little more interesting. We’re working a Forestry Patrol Simulation using multiple Hydra servers and clients.

General Idea

We are building an application that simulates the movements of a flock of drones that have as objective to control the presence of fires or abnormal heat spots in a given geographical area using infrared sensors.

The simulation will have these 3 main components -

  • A flock N flying drones
  • A centralized Hydra server
  • A Javascript Application for the GUI part
  • Docking stations (for charging) (the docking station can be the central server position)

Design principles and some general ideas

Drones

We need a flock of N flying drones (professional drones for forestry patrol)

As a basic starting implementation, the decision is that two-ways communication channels are established between every Drone and a Central Server (or Controller), information/signals can be sent back and forth the single Drone and the Controller but NOT among Drones.

Drones will act as Hydra Servers as well as Hydra Clients (Hybrids): they will have some exposed endpoints where other Hydra Client can send orders or ask for updates, but they also have Hydra Client capabilities themselves, to send information and signals to the Controller by calling the Controller’s Hydra API.

The drones will have some endpoint like https://drone123/api/order where the Controller can send the orders using POST/PUT requests. Upon receiving new orders, drones can act upon them immediately unless they need to improvise.

Another example can be that the Drones can ask for information about other Drones by requesting the Controller using GET https://controller/api/drone or GET https://controller/api/status/<drone_id> Drones have a standard behavior given by the simulation and defined below. At least this behavior is overridden by some order, they will go on moving, acquiring data, coming back to the recharging station, recharging and taking off.

Main Functions

As defined above, the Drones will act as semi-intelligent Hydra Servers as well as Clients, they will have the following main functions:

  • Drones receive commands from the server ( can be something as simple as the central server sends orders at some endpoint like PUT https://drone123/api/order/<order_id>). Commands can include the speed and direction to move with some additional attributes.

Upon receiving the order the drone will act immediately unless there is some issue and it needs to override the orders. These orders are sequential and they stack on the limited Drone’s in-memory queue. In the case of the “ order endpoint” above, Drone will respond with and Hydra: Status that can be, for example, “204 Accepted” or “409 Conflict”.

  • A Drone publishes its status via HTTP response from its Hydra Server at some endpoint like GET https://drone123/api/status, so the Controller can reach it.
  • Drones publish their sensor data stream via requests to the server at some endpoint like POST https://controller/drone/<drone_id/data.
  • Each drone will have a unique id and some other parameters like speed and battery life.
  • Drones cannot interact with other drones or issue commands to them directly, they need to do so via the central server. For example, if any drone wants to know the nearby drones, it can just ask the server via GET https://controller/drone/<drone_id/status.
  • Drones will automatically decide when to charge and only, in that case, override the commands sent by the server only after sending a log of its status to the central server.
  • Drones obey some basic rules ( For example - can’t hit each other)

Supported Classes and their Props for Drone ApiDocumentation

### We only need to replace the subsystem_parsed_classes by this and the new hydra server for drones API is ready.
parsed_classes = [
    {
         "@id":"https://schema.org/Order",
         "@type":"hydra:Class",
         "title":"Order",
         "description":"Handle orders from the central server.",
         "supportedOperation":[
            {
                "statusCodes": [
                    {
                        "code": 200,
                        "description": "Order successfully recieved."
                    }
                ],
                "@type": "https://schema.org/UpdateAction",
                "returns": "https://schema.org/Order",
                "label": "Recieves orders from the Central Server",
                "method": "PUT",
                "@id": "_:Order_create",
                "description": "null",
                "expects": "https://schema.org/Order"
            },
                        {
                            "statusCodes": [
                                {
                                    "code": 404,
                                    "description": "If no orders were found."
                                }
                            ],
                            "@type": "hydra:Operation",
                            "returns": "https://schema.org/Order",
                            "label": "Retrieves all orders from the central server.",
                            "method": "GET",
                            "@id": "_:Order_retrieve",
                            "description": "null",
                            "expects": "null"
                        }
         ],
         "supportedProperty":[

            {  "@type": "SupportedProperty",
               "property":"https://schema.org/geo",
               "title":"Destination",
               "hydra:description":"Coordinates of the new destination",
               "required":True,
               "readonly":False,
               "writeonly":False
            },
            {  "@type": "SupportedProperty",
               "property":"https://auto.schema.org/speed",
               "title":"Speed",
               "hydra:description":"Speed of Drone in Km/h",
               "required":True,
               "readonly":False,
               "writeonly":False
            },
         ]
      },
]

Client part

Every drone will have a Client part along with the Hydra Server Part. The client part will have no idea about the server endpoints except the main entrypoint to the server (VERY IMPORTANT TO DEMONSTRATE HYDRA CAPABILITIES). The client will have to figure out the rest on its own. A Drone Client will serve the following purposes -

  • Will be used to issue POST requests to the central server to submit drone status whenever the status changes or the drone needs to override the server orders.
  • Will be used to issue POST requests to the central server to submit the data stream from sensors, this will only be done when the drone’s status will be [Progress: Analysing]. After the data stream is successfully submitted the drone will move to the next destination. Upon successful retrieval of Sensor data from the drone, the server will issue new orders to the drone (can be automatic or manual by the user).

Central server

The central server will be a Hydra based API server acting as a central data store and control center for all the drones. It will also have a client part just like the drones that will be used to issue orders to different drones.

Main Functions

The central server will serve the following purposes -

  • It will act as a central database for all the drones to store their logs and sensor data. This will be done using the drone client side, they will issue POST/PUT requests after some fixed interval of time or upon some status change.
  • It will have some endpoint to serve all the logs from all the drones in some natural language format for the GUI part.
  • The server will issue orders to all the drones to make them coordinate and cover the entire area of interest ( the client side of the server will be used to send orders to the drones).
  • The server will act as an intermediate if different drones want to interact with each other. For example - If some drone wants to know the position of all nearby drones.
  • Will act as the main docking station to recharge drones.
  • retrieve_drone_list() [GET][POST][/api/drones] - Will return list of all available drones {DroneCollection}. POST can be used to add new drones. For example /drones/123 will return Drone 123’s specs and details.

  • submit_status(drone_id, status) [GET][POST] [/api/status] - Will be used by the client side of drones to update their status using POST requests. GET can be used to list all the status submissions {statusCollection}. Status objects will include the following
  • submit_data(drone_id, data) [GET][POST] [/api/datastream] - Will be used by the client side of drones to send the analyzed data stream from sensors to the server. A simple GET request will return all the submitted datastreams {datastreamCollection}. POST requests can be used to submit new data streams. Datastream will include the following ( for simplicity of the simulation the drones will only have a temperature sensor and GPS for location)
  • get_latest_logs() [GET] [/api/logs]{logsCollection} - Will be used to serve the logs of past several seconds (say 5 seconds), logs will be used by the javascript application to display the progress on Map.

  • submit_message() [GET][POST] [/api/message] - An endpoint for the monitoring/GUI application, to receive commands issued by the end-user in the shape of a string that has to be sanitized, parsed, processed into the right sequence of API calls that have then to be dispatched. GET can be used to retrieve all the submitted messages {messageCollection}.

  • **issue_order(drone_id) [GET][POST][/api/orders/] {Order}** - If the order is issued automatically by the server like continue moving, then the request will be get and the server side client will be notified. The client will then take that order to make a `POST` request to the drone. Orders can also be issued directly without NLP using `POST` requests at `/api/orders/`. Upon receiving a new order the client will pass the order to the drone.

Supported Classes and their Props for APIDocumentation

See this Gist

Client Part

The central server will also have a Client part. The client part will have no idea about the drone endpoints except the main entrypoint to each drone (VERY IMPORTANT TO DEMONSTRATE HYDRA CAPABILITIES). The client will have to figure out the rest on its own. The Server Client will serve the following purposes -

  • It will be used to issue new orders using POST requests to each drone.

Javascript Monitoring Application

The Javascript Application serves the following purposes -

  • It uses logs from the central server to display the progress on a map in pseudo-realtime.
  • Can act as a control center to issue commands to different drones. - The user will write commands in NLP format, the commands will be sent to the server at /message via POST requests where further processing will be done. Once the processing is done, new orders will be available at issue_order/<drone_id> that can be sent to the drones.

Deploying The Simulation

The simulation is deployed using different Docker containers:

  • 1 container small to simulate the central server (controller)
  • 1 container small for the monitoring Javascript client
  • Multiple tiny containers to simulate the drones

These components interact with a private network and are reachable using aliases:

  • A’s HTTP interface is reachable at http://central (central alias maps to port 8000)
  • B’s application is reachable at http://localhost:8080
  • C’s HTTP interfaces are reachable at http://drone:port (e.g http://drone:8001 maps to port)

If you want a sneak to the project, here’s the Github repo.