-
Notifications
You must be signed in to change notification settings - Fork 18
Controller Design
This page explains the design, architecture and the implementation of Controller Component for the simulation.
The central controller is a Hydra based API server acting as a central datastore and control center for all the drones. All active drones submit their status updates every 15 seconds to the central controller. Just like drones the central controller also has a client part that can be used to issue commands to different drones.
- It acts as a central database for all the drones to store their logs and sensor data. This is being done using the drone client side, drones issue POST/PUT requests after every 15 seconds or upon some status change. The central controller has different endpoints for different types of data.
-
/api/DroneCollection/<drone_id>Each active drone updates their drone object usingPUT/POSTrequests here, every 15 seconds. -
/api/DatastreamCollection/Datastream from the drone sensors is stored here. -
/api/DroneLogCollection/Logs related to drones are stored here. -
/api/ControllerLogCollectionLogs related to the controller are stored here. -
/api/HttpApiLogCollectionLogs related to general interactions between different components are stored here.
-
- The user can issue a message to the central controller at
/api/MessageCollection/in a structured format. The message is then parsed and commands are issued to the respective 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.
- The central controller acts as the main docking station to recharge drones.
Central controller is driven by a 17 second time loop (2 second delay to let drones finish updating their status at the controller).
"""Main loop for the central controller."""
print("Controller Simulation Loop")
try:
handle_messages()
handle_anomalies()
except Exception as e:
print(e)
finally:
threading.Timer(LOOP_TIME, main).start()In the main Loop, the controller tries to handle two things.
- The messages submitted by the user
- Anomalies detected by drones
"""Handle messages in the MessageCollection."""
try:
message_collection = get_message_collection()
print(message_collection)
for message in message_collection:
regex = r'/(.*)/(\d*)'
matchObj = re.match(regex, message["@id"])
if matchObj:
message_id = matchObj.group(2)
message_details = get_message(message_id)
# parse message
message_string = message_details["MessageString"]
parsed_message = parse_message(message_string)
if parsed_message is not None:
drone_id, prop, value = parsed_message
if not validate_message_prop_value(prop, value):
delete_message(message_id)
else:
command = generate_command(drone_id, prop, value)
try:
RES, NAMESPACE = find_res(drone_id)
if RES is not None and NAMESPACE is not None:
issue_command(RES, NAMESPACE, command)
except:
controllerlog = gen_ControllerLog(
"Drone with id %s not found, deleting message." % (str(drone_id)), "")
send_controllerlog(controllerlog)
delete_message(message_id)
# delete message
delete_message(message_id)
except Exception as e:
print(e)""" Parsing a given message string.
Messages will be in format 'Set Drone <DroneID> <Property> <Value>'.
DroneID is the drone identifier assigned by the central controller.
Property can be Direction, Speed or Status and values can be anything
supported by that respective Property."""
message_items = message_string.lower().split(" ")
try:
drone_id = message_items[message_items.index("drone") + 1]
prop = message_items[message_items.index(drone_id) + 1]
value = message_items[message_items.index(prop) + 1]
return (drone_id, prop.title(), value.title())
except Exception as e:
print(e)
return None """Handling the anomalies in AnomalyCollection."""
try:
anomaly_collection = get_anomaly_collection()
drone_collection = get_drone_collection()
non_confirmed_anomalies, negative_anomalies = find_non_confirmed_and_negative_anomalies(
anomaly_collection)
# Handle non_confirmed_anomalies
for anomaly in non_confirmed_anomalies:
handle_anomaly(anomaly, drone_collection)
# Delete Negative anomalies
for anomaly in negative_anomalies:
delete_anomaly(anomaly["AnomalyID"])
except Exception as e:
print(e)The full implementation of the main loop is available at flock_controller.mechanics.simulate.
Full source code for the controller component is available here.