From 627447c3c0044ee101e392d2621c8965aff6ea92 Mon Sep 17 00:00:00 2001 From: Fernando Julio Cendra Date: Sun, 12 Jul 2020 23:58:00 +0800 Subject: [PATCH 1/7] Implemented multiprocessing module (have not tested yet on jetson) --- main.py | 85 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/main.py b/main.py index b421708..1e53270 100644 --- a/main.py +++ b/main.py @@ -1,10 +1,11 @@ import time import argparse import logging -import asyncio +import multiprocessing from serial import serialutil from imutils.video import FPS import cv2 +from queue import Queue from detector import yolo from report import report @@ -12,34 +13,42 @@ from report import pixhawk from report import thing_speak -async def writeData(pixhawk, thing_speak, report): - try: - pixhawk_init = pixhawk.Pixhawk() - pixhawk_data = pixhawk_init.get_data() - logging.debug(pixhawk_data) - - # post to thingspeak.com - visualize = thing_speak.Thing_speak(r, pixhawk_data) - visualize.show_thingspeak() - - # saved to reports.json - get_report = report.Report(r, pixhawk_data) - get_report.create_report() - get_report.print_report() - get_report.write_report(report_path) - reports.combine(reports_path) - return 0 - - except serialutil.SerialException as e: - # @utkarsh867: 9th July, 2020 - # I added this exception handler so that the code does not crash when it does not find a serial connection - # to the Pixhawk - logging.error(e) - return -1 - -async def main(args): - report_path = 'report/report_folder/report.json' - reports_path = 'report/report_folder/reports.json' +report_path = 'report/report_folder/report.json' +reports_path = 'report/report_folder/reports.json' +q = Queue(maxsize=0) + +def writeData(): + while True: + while True: + if (q.empty == False): + break + + try: + yolo_data = q.get() + pixhawk_init = pixhawk.Pixhawk() + pixhawk_data = pixhawk_init.get_data() + logging.debug(pixhawk_data) + + # post to thingspeak.com + visualize = thing_speak.Thing_speak(yolo_data, pixhawk_data) + visualize.show_thingspeak() + + # saved to reports.json + get_report = report.Report(yolo_data, pixhawk_data) + get_report.create_report() + get_report.print_report() + get_report.write_report(report_path) + reports.combine(reports_path) + return 0 + + except serialutil.SerialException as e: + # @utkarsh867: 9th July, 2020 + # I added this exception handler so that the code does not crash when it does not find a serial connection + # to the Pixhawk + logging.error(e) + return -1 + +def main(args): logging.info("accessing video stream...") vs = cv2.VideoCapture(0) @@ -63,14 +72,9 @@ async def main(args): logging.debug(result) for r in result: + q.put(r) # This loop is iterating over all YOLO results # TODO: Optimise this section so that each frame is sent only once. - task1 = asyncio.create_task( - writeData(pixhawk, thing_speak, report) - ) - - val = await task1 - print(val) if args.video_out: cv2.imshow("Clearbot", frame) @@ -97,4 +101,13 @@ async def main(args): else: logging.getLogger().setLevel(logging.INFO) - asyncio.run(main(args)) + # Set multiprocessing + p1 = multiprocessing.Process(target=main) + p2 = multiprocessing.Process(target=writeData) + + # Start Multiprocessing + p1.start() + p2.start() + + p1.join() + p2.join() \ No newline at end of file From 1b71f6beb679aee30fb7a60ee7b6f48177e305f6 Mon Sep 17 00:00:00 2001 From: Fernando Julio Cendra Date: Mon, 13 Jul 2020 00:21:13 +0800 Subject: [PATCH 2/7] Hide channel id and apikey for thinkspeak --- report/thing_speak.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/report/thing_speak.py b/report/thing_speak.py index ae1d2a7..c25a3c5 100644 --- a/report/thing_speak.py +++ b/report/thing_speak.py @@ -1,12 +1,13 @@ +import os import paho.mqtt.publish as publish from report.clearbot_attributes import * import time import re -channelID = "1092630" -apiKey = "FGN0JQQLW5D88TJ1" +CHANNEL_ID = os.environ.get("CHANNEL_ID") +API_KEY = os.environ.get("API_KEY") -topic = "channels/"+ channelID +"/publish/"+ apiKey +topic = "channels/"+ CHANNEL_ID +"/publish/"+ API_KEY mqttHost = "mqtt.thingspeak.com" tTransport = "tcp" tPort = 1883 From d8fd1c58a43f41c2a952cb1a0a0b0c15a4f3f2fb Mon Sep 17 00:00:00 2001 From: fcendra Date: Mon, 13 Jul 2020 13:22:53 +0800 Subject: [PATCH 3/7] set config.py into .gitignore --- .gitignore | 3 ++- main.py | 45 ++++++++++++++++++++++++++++--------------- report/thing_speak.py | 6 ++---- testing.py | 32 ++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 21 deletions(-) create mode 100644 testing.py diff --git a/.gitignore b/.gitignore index 42f978b..2065c23 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ .venv/ .idea/ __pycache__/ -.DS_Store \ No newline at end of file +.DS_Store +config.py \ No newline at end of file diff --git a/main.py b/main.py index b421708..fddb2bc 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,7 @@ import time import argparse import logging -import asyncio +import multiprocessing from serial import serialutil from imutils.video import FPS import cv2 @@ -12,18 +12,27 @@ from report import pixhawk from report import thing_speak -async def writeData(pixhawk, thing_speak, report): +report_path = 'report/report_folder/report.json' +reports_path = 'report/report_folder/reports.json' + +def writeData(conn): + while True: + msg = conn.recv() + if msg != None: + break + print("Received the message") try: + reports = reports.Reports() pixhawk_init = pixhawk.Pixhawk() pixhawk_data = pixhawk_init.get_data() logging.debug(pixhawk_data) # post to thingspeak.com - visualize = thing_speak.Thing_speak(r, pixhawk_data) + visualize = thing_speak.Thing_speak(msg, pixhawk_data) visualize.show_thingspeak() # saved to reports.json - get_report = report.Report(r, pixhawk_data) + get_report = report.Report(msg, pixhawk_data) get_report.create_report() get_report.print_report() get_report.write_report(report_path) @@ -37,14 +46,10 @@ async def writeData(pixhawk, thing_speak, report): logging.error(e) return -1 -async def main(args): - report_path = 'report/report_folder/report.json' - reports_path = 'report/report_folder/reports.json' - +def main12(conn,args): logging.info("accessing video stream...") vs = cv2.VideoCapture(0) detector = yolo.Detector("model", use_gpu=True) - reports = reports.Reports() fps = FPS().start() while True: @@ -65,12 +70,9 @@ async def main(args): for r in result: # This loop is iterating over all YOLO results # TODO: Optimise this section so that each frame is sent only once. - task1 = asyncio.create_task( - writeData(pixhawk, thing_speak, report) - ) - - val = await task1 - print(val) + conn.send(r) + print("Sent the message to writeData()") + conn.close() if args.video_out: cv2.imshow("Clearbot", frame) @@ -97,4 +99,15 @@ async def main(args): else: logging.getLogger().setLevel(logging.INFO) - asyncio.run(main(args)) + # Multiprocessing process + parent_conn, child_conn = multiprocessing.Pipe() + + p1 = multiprocessing.Process(target=main12, args=(parent_conn, args)) + p2 = multiprocessing.Process(target=writeData, args=(child_conn,)) + + p1.start() + p2.start() + + p1.join() + p2.join() + diff --git a/report/thing_speak.py b/report/thing_speak.py index ae1d2a7..c68a848 100644 --- a/report/thing_speak.py +++ b/report/thing_speak.py @@ -2,11 +2,9 @@ from report.clearbot_attributes import * import time import re +import config -channelID = "1092630" -apiKey = "FGN0JQQLW5D88TJ1" - -topic = "channels/"+ channelID +"/publish/"+ apiKey +topic = "channels/"+ config.CHANNEL_ID +"/publish/"+ config.API_KEY mqttHost = "mqtt.thingspeak.com" tTransport = "tcp" tPort = 1883 diff --git a/testing.py b/testing.py new file mode 100644 index 0000000..711148a --- /dev/null +++ b/testing.py @@ -0,0 +1,32 @@ +from dronekit import connect, VehicleMode, LocationGlobalRelative + + +connection_port="/dev/ttyTHS1" + +baud=57600 +vehicle = connect(connection_port, wait_ready=True, baud=baud) +vehicle.mode = VehicleMode("MANUAL") + + +# print('Autopilot Firmware version: %s' % vehicle.version) +# print('Autopilot capabilities (supports ftp): %s' % vehicle.capabilities.ftp) +print('Global Location: %s' % vehicle.location.global_frame) +# print('Global Location (relative altitude): %s' % vehicle.location.global_relative_frame) +# print('Local Location: %s' % vehicle.location.local_frame) +# print('Attitude: %s' % vehicle.attitude) +# print('Velocity: %s' % vehicle.velocity) +# print('GPS: %s' % vehicle.gps_0) +# print('Groundspeed: %s' % vehicle.groundspeed) +# print('Airspeed: %s' % vehicle.airspeed) +# print('Gimbal status: %s' % vehicle.gimbal) +# print('Battery: %s' % vehicle.battery) +# print('EKF OK?: %s' % vehicle.ekf_ok) +# print('Last Heartbeat: %s' % vehicle.last_heartbeat) +# print('Rangefinder: %s' % vehicle.rangefinder) +# print('Rangefinder distance: %s' % vehicle.rangefinder.distance) +# print('Rangefinder voltage: %s' % vehicle.rangefinder.voltage) +# print('Heading: %s' % vehicle.heading) +# print('Is Armable?: %s' % vehicle.is_armable) +# print('System status: %s' % vehicle.system_status.state) +# print('Mode: %s' % vehicle.mode.name) +# print('Armed: %s' % vehicle.armed) From 3cb3496016c3783ffdbb9389c9d080a41fdd849e Mon Sep 17 00:00:00 2001 From: fcendra Date: Mon, 13 Jul 2020 13:30:05 +0800 Subject: [PATCH 4/7] add conifg.py into .gitignore --- report/thing_speak.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/report/thing_speak.py b/report/thing_speak.py index aaeede7..a94984e 100644 --- a/report/thing_speak.py +++ b/report/thing_speak.py @@ -5,10 +5,8 @@ import re import config -CHANNEL_ID = os.environ.get("CHANNEL_ID") -API_KEY = os.environ.get("API_KEY") -topic = "channels/"+ CHANNEL_ID +"/publish/"+ API_KEY +topic = "channels/"+ config.CHANNEL_ID +"/publish/"+ config.API_KEY mqttHost = "mqtt.thingspeak.com" tTransport = "tcp" tPort = 1883 From 0b306ce656d702544750baefd024341b679bc4ae Mon Sep 17 00:00:00 2001 From: fcendra Date: Mon, 13 Jul 2020 14:21:18 +0800 Subject: [PATCH 5/7] set up multiprocess moduleinto main.py --- main.py | 6 +++++- report/thing_speak.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index f50786d..a9e9351 100644 --- a/main.py +++ b/main.py @@ -18,6 +18,7 @@ q = Queue(maxsize=0) def writeData(): + print("THinkspeak is starting") while True: while True: if (q.empty == False): @@ -48,7 +49,9 @@ def writeData(): logging.error(e) return -1 -def main(args): +#def main(args): +def main(): + print("Yolo is starting") logging.info("accessing video stream...") vs = cv2.VideoCapture(0) @@ -92,6 +95,7 @@ def main(args): parser = argparse.ArgumentParser(description="Clearbot AI and PController") parser.add_argument('-v', '--video_out', type=bool, default=False, help="Show the camera video output") parser.add_argument('--debug', type=bool, default=False, help="Switch to debug mode") + global args args = parser.parse_args() # Added the logging package instead of printing data randomly diff --git a/report/thing_speak.py b/report/thing_speak.py index a94984e..c0689b6 100644 --- a/report/thing_speak.py +++ b/report/thing_speak.py @@ -3,7 +3,7 @@ from report.clearbot_attributes import * import time import re -import config +from report import config topic = "channels/"+ config.CHANNEL_ID +"/publish/"+ config.API_KEY From 108d0f1ecf6154e6dfd8c8182aaae04024bd40ad Mon Sep 17 00:00:00 2001 From: utkarsh867 Date: Mon, 13 Jul 2020 20:50:48 +0530 Subject: [PATCH 6/7] Adds tiny weights to the project --- detector/model/clearbot-tiny.cfg | 281 +++++++++++++++++++++++++++ detector/model/clearbot-tiny.weights | 3 + report/main.py | 2 +- 3 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 detector/model/clearbot-tiny.cfg create mode 100644 detector/model/clearbot-tiny.weights diff --git a/detector/model/clearbot-tiny.cfg b/detector/model/clearbot-tiny.cfg new file mode 100644 index 0000000..5a6b22b --- /dev/null +++ b/detector/model/clearbot-tiny.cfg @@ -0,0 +1,281 @@ +[net] +# Testing +# batch=1 +# subdivisions=1 +# Training +batch=64 +subdivisions=16 +width=416 +height=416 +channels=3 +momentum=0.9 +decay=0.0005 +angle=0 +saturation = 1.5 +exposure = 1.5 +hue=.1 + +learning_rate=0.00261 +burn_in=1000 +max_batches = 128000 +policy=steps +steps=102400,115200 +scales=.1,.1 + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=2 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers=-1 +groups=2 +group_id=1 + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -1,-2 + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -6,-1 + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers=-1 +groups=2 +group_id=1 + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -1,-2 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -6,-1 + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers=-1 +groups=2 +group_id=1 + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -1,-2 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -6,-1 + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +################################## + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=207 +activation=linear + + + +[yolo] +mask = 3,4,5 +anchors = 9, 7, 30, 25, 61, 51, 95, 95, 191,120, 234,242 +classes=64 +num=6 +jitter=.3 +scale_x_y = 1.05 +cls_normalizer=1.0 +iou_normalizer=0.07 +iou_loss=ciou +ignore_thresh = .7 +truth_thresh = 1 +random=0 +resize=1.5 +nms_kind=greedynms +beta_nms=0.6 + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 23 + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=207 +activation=linear + +[yolo] +mask = 1,2,3 +anchors = 9, 7, 30, 25, 61, 51, 95, 95, 191,120, 234,242 +classes=64 +num=6 +jitter=.3 +scale_x_y = 1.05 +cls_normalizer=1.0 +iou_normalizer=0.07 +iou_loss=ciou +ignore_thresh = .7 +truth_thresh = 1 +random=0 +resize=1.5 +nms_kind=greedynms +beta_nms=0.6 diff --git a/detector/model/clearbot-tiny.weights b/detector/model/clearbot-tiny.weights new file mode 100644 index 0000000..ff99f98 --- /dev/null +++ b/detector/model/clearbot-tiny.weights @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb0d0dfce42caaa9e6a171adcd2ffc2a26139276fc32416a5ac5ac30d522662f +size 43914873 diff --git a/report/main.py b/report/main.py index 538cfe7..9e403ac 100644 --- a/report/main.py +++ b/report/main.py @@ -11,7 +11,7 @@ print("[INFO] accessing video stream...") vs = cv2.VideoCapture(0) -detector = yolo.Detector("model", use_gpu=True, weights_file="clearbot_26_06_20.weights") +detector = yolo.Detector("model", use_gpu=True, weights_file="clearbot.weights") reports = Reports() previous = 0 From 125479b57765d0eb84485ef7de2a3bbd9d0cc7c2 Mon Sep 17 00:00:00 2001 From: utkarsh867 Date: Tue, 14 Jul 2020 00:08:38 +0530 Subject: [PATCH 7/7] Major code refactoring --- detector/detector.py | 123 ++++++++ detector/yolo.py | 129 --------- main.py | 34 +-- report/attributes.py | 166 +++++++++++ report/clearbot_attributes/Air_speed.py | 7 - report/clearbot_attributes/Attitude.py | 7 - report/clearbot_attributes/Battery_status.py | 7 - .../Check_vehicle_armed.py | 6 - report/clearbot_attributes/Confidence.py | 7 - report/clearbot_attributes/Confidence.pyc | Bin 655 -> 0 bytes report/clearbot_attributes/Ekf_ok.py | 6 - .../clearbot_attributes/Firmware_version.py | 8 - report/clearbot_attributes/Gimbal_status.py | 7 - report/clearbot_attributes/Gps.py | 7 - report/clearbot_attributes/Ground_speed.py | 7 - report/clearbot_attributes/Heading.py | 6 - report/clearbot_attributes/Label.py | 6 - report/clearbot_attributes/Label.pyc | Bin 625 -> 0 bytes report/clearbot_attributes/Last_heartbeat.py | 6 - report/clearbot_attributes/Location.py | 6 - report/clearbot_attributes/Location.pyc | Bin 981 -> 0 bytes .../Range_finder_distance.py | 6 - .../Range_finder_voltage.py | 6 - report/clearbot_attributes/System_status.py | 6 - .../Vehicle_capabilities.py | 7 - .../clearbot_attributes/Vehicle_is_armable.py | 6 - .../clearbot_attributes/Vehicle_mode_name.py | 6 - report/clearbot_attributes/Velocity.py | 7 - report/clearbot_attributes/__init__.py | 4 - report/main.py | 36 --- report/pixhawk.py | 266 +++++++++--------- report/report.py | 110 ++++---- report/{thing_speak.py => thingspeak.py} | 24 +- 33 files changed, 506 insertions(+), 523 deletions(-) create mode 100644 detector/detector.py delete mode 100644 detector/yolo.py create mode 100644 report/attributes.py delete mode 100644 report/clearbot_attributes/Air_speed.py delete mode 100644 report/clearbot_attributes/Attitude.py delete mode 100644 report/clearbot_attributes/Battery_status.py delete mode 100644 report/clearbot_attributes/Check_vehicle_armed.py delete mode 100644 report/clearbot_attributes/Confidence.py delete mode 100644 report/clearbot_attributes/Confidence.pyc delete mode 100644 report/clearbot_attributes/Ekf_ok.py delete mode 100644 report/clearbot_attributes/Firmware_version.py delete mode 100644 report/clearbot_attributes/Gimbal_status.py delete mode 100644 report/clearbot_attributes/Gps.py delete mode 100644 report/clearbot_attributes/Ground_speed.py delete mode 100644 report/clearbot_attributes/Heading.py delete mode 100644 report/clearbot_attributes/Label.py delete mode 100644 report/clearbot_attributes/Label.pyc delete mode 100644 report/clearbot_attributes/Last_heartbeat.py delete mode 100644 report/clearbot_attributes/Location.py delete mode 100644 report/clearbot_attributes/Location.pyc delete mode 100644 report/clearbot_attributes/Range_finder_distance.py delete mode 100644 report/clearbot_attributes/Range_finder_voltage.py delete mode 100644 report/clearbot_attributes/System_status.py delete mode 100644 report/clearbot_attributes/Vehicle_capabilities.py delete mode 100644 report/clearbot_attributes/Vehicle_is_armable.py delete mode 100644 report/clearbot_attributes/Vehicle_mode_name.py delete mode 100644 report/clearbot_attributes/Velocity.py delete mode 100644 report/clearbot_attributes/__init__.py delete mode 100644 report/main.py rename report/{thing_speak.py => thingspeak.py} (68%) diff --git a/detector/detector.py b/detector/detector.py new file mode 100644 index 0000000..cc5d850 --- /dev/null +++ b/detector/detector.py @@ -0,0 +1,123 @@ +import numpy as np +import cv2 +import os +import functools, operator + +import logging + + +class Detector: + weights_file = None + config_file = None + names_file = None + + confidence_threshold = 0 + nms_threshold = 0 + LABELS = [] + + net = None + ln = None + + def __init__(self, model_path="model", use_gpu=False, confidence_thres=0.5, nms_thres=0.3, + weights_file="clearbot.weights", config_file="clearbot.cfg", names_file="clearbot.names"): + + self.confidence_threshold = confidence_thres + self.nms_threshold = nms_thres + + self.weights_file = os.path.sep.join([os.path.dirname(os.path.realpath(__file__)), model_path, weights_file]) + self.config_file = os.path.sep.join([os.path.dirname(os.path.realpath(__file__)), model_path, config_file]) + self.names_file = os.path.sep.join([os.path.dirname(os.path.realpath(__file__)), model_path, names_file]) + logging.debug("Finished initialising model file paths") + + try: + self.LABELS = open(self.names_file).read().strip().split("\n") + logging.debug(f"Loaded labels from the names file: \n{self.LABELS}") + except Exception as e: + logging.error(e) + + try: + logging.debug("Loading Darknet model") + self.net = cv2.dnn.readNetFromDarknet(self.config_file, self.weights_file) + logging.debug("Finished loading Darknet model") + except Exception as e: + logging.error(e) + + if use_gpu: + logging.info("Will try to use GPU backend") + self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) + self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) + else: + logging.info("Using CPU only") + + self.ln = self.net.getLayerNames() + + unconnected_layers = functools.reduce(operator.iconcat, self.net.getUnconnectedOutLayers(), []) + logging.debug(f"Indexes of unconnected layers: {unconnected_layers}") + self.ln = [self.ln[i - 1] for i in unconnected_layers] + logging.debug(f"Output layers for YOLO are: {self.ln}") + + def detect(self, frame): + """ + Detect the objects in the frame + :param frame: Frame that has been captured from the OpenCV video stream + :return: dict object with the objects and the bounding boxes + """ + (H, W) = frame.shape[:2] + blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False) + + self.net.setInput(blob) + layer_outputs = self.net.forward(self.ln) + + boxes = [] + confidences = [] + class_ids = [] + + for output in layer_outputs: + for detection in output: + scores = detection[5:] + class_id = np.argmax(scores) + confidence = scores[class_id] + + if confidence > self.confidence_threshold: + box = detection[0:4] * np.array([W, H, W, H]) + (centerX, centerY, width, height) = box.astype("int") + + x = int(centerX - (width / 2)) + y = int(centerY - (width / 2)) + + # Adding int(width) and int(height) is really important for some reason. + # Removing it gives an error in NMSBoxes() call + # Shall figure out soon and write a justification here. + boxes.append([x, y, int(width), int(height)]) + confidences.append(float(confidence)) + class_ids.append(class_id) + + logging.debug((boxes, confidences, self.confidence_threshold, self.nms_threshold)) + indexes = cv2.dnn.NMSBoxes(boxes, confidences, self.confidence_threshold, self.nms_threshold) + logging.debug(f"Indexes: {indexes}") + if len(indexes) > 0: + indexes = indexes.flatten() + return map(lambda idx: self.detected_to_result(boxes[idx], confidences[idx], class_ids[idx]), indexes) + + def detected_to_result(self, box, confidence, class_id): + (x, y) = (box[0], box[1]) + (w, h) = (box[2], box[3]) + + label = self.LABELS[class_id] + + return { + "label": label, + "confidence": confidence, + "bbox": { + "x": x, + "y": y, + "width": w, + "height": h + } + } + + +if __name__ == "__main__": + logging.getLogger().setLevel(logging.DEBUG) + + detector = Detector() diff --git a/detector/yolo.py b/detector/yolo.py deleted file mode 100644 index 145619d..0000000 --- a/detector/yolo.py +++ /dev/null @@ -1,129 +0,0 @@ -import numpy as np -import cv2 -import os - - -class Detector: - net = None - confidence_threshold = 0 - nms_threshold = 0 - LABELS = None - ln = None - - def __init__(self, model_path, use_gpu=False, confidence_thres=0.5, nms_thres=0.3, weights_file="clearbot_26_06_20.weights", - config_file="clearbot.cfg", names_file="clearbot.names"): - """ - Initialise a instance for YOLOv4 object detection. - :param model_path: The path of the model relative to the python script - :param use_gpu: Whether to use GPU CUDA or not. - :param confidence_thres: The confidence threshold of the results (0 to 1). - :param nms_thres: The NMS threshold of the results - """ - self.confidence_threshold = confidence_thres - self.nms_threshold = nms_thres - - labels_path = os.path.sep.join([os.path.dirname(os.path.realpath(__file__)), model_path, names_file]) - self.LABELS = open(labels_path).read().strip().split("\n") - - weights_path = os.path.sep.join([os.path.dirname(os.path.realpath(__file__)), model_path, weights_file]) - config_path = os.path.sep.join([os.path.dirname(os.path.realpath(__file__)), model_path, config_file]) - print("[INFO] loading YOLO from disk...") - self.net = cv2.dnn.readNetFromDarknet(config_path, weights_path) - - if use_gpu: - # set CUDA as the preferable backend and target - print("[INFO] setting preferable backend and target to CUDA...") - self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) - self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) - - # determine only the *output* layer names that we need from YOLO - self.ln = self.net.getLayerNames() - self.ln = [self.ln[i[0] - 1] for i in self.net.getUnconnectedOutLayers()] - - def detect(self, frame): - """ - Detect the objects in the frame - :param frame: Frame that has been captured from the OpenCV video stream - :return: dict object with the objects and the bounding boxes - """ - - # construct a blob from the input frame and then perform a forward - # pass of the YOLO object detector, giving us our bounding boxes - # and associated probabilities - (H, W) = frame.shape[:2] - blob = cv2.dnn.blobFromImage( - frame, 1 / 255.0, (416, 416), swapRB=True, crop=False - ) - self.net.setInput(blob) - layer_outputs = self.net.forward(self.ln) - - boxes = [] - confidences = [] - class_ids = [] - - for output in layer_outputs: - # loop over each of the detections - for detection in output: - # extract the class ID and confidence (i.e., probability) - # of the current object detection - scores = detection[5:] - class_id = np.argmax(scores) - confidence = scores[class_id] - - # filter out weak predictions by ensuring the detected - # probability is greater than the minimum probability - if confidence > self.confidence_threshold: - # scale the bounding box coordinates back relative to - # the size of the image, keeping in mind that YOLO - # actually returns the center (x, y)-coordinates of - # the bounding box followed by the boxes' width and - # height - box = detection[0:4] * np.array([W, H, W, H]) - (centerX, centerY, width, height) = box.astype("int") - - # use the center (x, y)-coordinates to derive the top - # and and left corner of the bounding box - x = int(centerX - (width / 2)) - y = int(centerY - (height / 2)) - - # update our list of bounding box coordinates, - # confidences, and class IDs - boxes.append([x, y, int(width), int(height)]) - confidences.append(float(confidence)) - class_ids.append(class_id) - - # Gives the indexes of the boxes that we should use - idxs = cv2.dnn.NMSBoxes(boxes, confidences, self.confidence_threshold, self.nms_threshold) - result = [] - - # Extract the results from the detector - if len(idxs) > 0: - # loop over the indexes we are keeping - for i in idxs.flatten(): - # extract the bounding box coordinates - (x, y) = (boxes[i][0], boxes[i][1]) - (w, h) = (boxes[i][2], boxes[i][3]) - class_id = class_ids[i] - label = self.LABELS[class_id] - confidence = confidences[i] - result.append({ - "label": label, - "confidence": confidence, - "bbox": { - "x": x, - "y": y, - "width": w, - "height": h - } - }) - return result - -# Sample code for using object detection -# print("[INFO] accessing video stream...") -# vs = cv2.VideoCapture(0) -# detector = Detector("model", use_gpu=True, weights_file="clearbot_26_06_20.weights") -# while True: -# (grabbed, frame) = vs.read() -# if not grabbed: -# break -# result = detector.detect(frame) diff --git a/main.py b/main.py index a9e9351..429ee98 100644 --- a/main.py +++ b/main.py @@ -7,21 +7,22 @@ import cv2 from queue import Queue -from detector import yolo +from detector import detector as dt from report import report from report import reports from report import pixhawk -from report import thing_speak +from report import thingspeak report_path = 'report/report_folder/report.json' reports_path = 'report/report_folder/reports.json' q = Queue(maxsize=0) + def writeData(): - print("THinkspeak is starting") while True: while True: if (q.empty == False): + logging.debug("Message queue is empty") break try: @@ -31,7 +32,8 @@ def writeData(): logging.debug(pixhawk_data) # post to thingspeak.com - visualize = thing_speak.Thing_speak(yolo_data, pixhawk_data) + logging.debug(f"Sending data to ThingSpeak:\n{yolo_data}\n{pixhawk_data}") + visualize = thingspeak.ThingSpeak(yolo_data, pixhawk_data) visualize.show_thingspeak() # saved to reports.json @@ -41,7 +43,7 @@ def writeData(): get_report.write_report(report_path) reports.combine(reports_path) return 0 - + except serialutil.SerialException as e: # @utkarsh867: 9th July, 2020 # I added this exception handler so that the code does not crash when it does not find a serial connection @@ -49,13 +51,13 @@ def writeData(): logging.error(e) return -1 -#def main(args): -def main(): + +def main(params): print("Yolo is starting") logging.info("accessing video stream...") vs = cv2.VideoCapture(0) - detector = yolo.Detector("model", use_gpu=True) + detector = dt.Detector("model", use_gpu=True) fps = FPS().start() while True: @@ -75,37 +77,37 @@ def main(): for r in result: q.put(r) - # This loop is iterating over all YOLO results - # TODO: Optimise this section so that each frame is sent only once. + # This loop is iterating over all YOLO results + # TODO: Optimise this section so that each frame is sent only once. - if args.video_out: + if params.video_out: cv2.imshow("Clearbot", frame) # If this is not there, frame will not actually show: I did not dig into the explanation if cv2.waitKey(1) & 0xFF == ord('q'): break fps.update() - + fps.stop() logging.info("approx. FPS: {:.2f}".format(fps.fps())) vs.release() cv2.destroyAllWindows() + if __name__ == "__main__": parser = argparse.ArgumentParser(description="Clearbot AI and PController") parser.add_argument('-v', '--video_out', type=bool, default=False, help="Show the camera video output") parser.add_argument('--debug', type=bool, default=False, help="Switch to debug mode") - global args args = parser.parse_args() # Added the logging package instead of printing data randomly if args.debug: - logging.getLogger().setLevel(logging.DEBUG) + logging.getLogger('root').setLevel(logging.DEBUG) else: - logging.getLogger().setLevel(logging.INFO) + logging.getLogger('root').setLevel(logging.INFO) # Set multiprocessing - p1 = multiprocessing.Process(target=main) + p1 = multiprocessing.Process(target=main, args=(args,)) p2 = multiprocessing.Process(target=writeData) # Start Multiprocessing diff --git a/report/attributes.py b/report/attributes.py new file mode 100644 index 0000000..16ff98c --- /dev/null +++ b/report/attributes.py @@ -0,0 +1,166 @@ +class AirSpeed: + def __init__(self, y): + self.y = y[7] + + def get_air_speed(self): + return self.y + + +class Altitude: + def __init__(self, y): + self.y = y[3] + + def get_altitude(self): + return self.y + + +class BatteryStatus: + def __init__(self, y): + self.y = y[9] + + def get_battery_status(self): + return self.y + + +class CheckVehicleArmed: + def __init__(self, y): + self.y = y[18] + + def get_armed_status(self): + return self.y + + +class Confidence: + def __init__(self, y): + self.y = y["confidence"] + + def get_confidence(self): + return self.y + + +class EkfOK: + def __init__(self, y): + self.y = y[10] + + def get_ekf_status(self): + return self.y + + +class FirmwareVersion: + def __init__(self, y): + self.y = y[0] + + def __version__(self): + return self.y + + +class GimbalStatus: + def __init__(self, y): + self.y = y[8] + + def get_gimbal_status(self): + return self.y + + +class GPS: + def __init__(self, y): + self.y = y[5] + + def get_gps(self): + return self.y + + +class GroundSpeed: + def __init__(self, y): + self.y = y[6] + + def get_ground_speed(self): + return self.y + + +class Heading: + def __init__(self, y): + self.y = y[14] + + def get_heading(self): + return self.y + + +class Label: + def __init__(self, x): + self.x = x["label"] + + def get_label(self): + return self.x + + +class LastHeartbeat: + def __init__(self, y): + self.y = y[11] + + def get_last_heartbeat(self): + return self.y + + +class Location: + def __init__(self, z): + self.z = z[2] + + def get_coordinates(self): + return self.z + + +class RangeFinderDistance: + def __init__(self, y): + self.y = y[12] + + def get_distance(self): + return self.y + + +class RangeFinderVoltage: + def __init__(self, y): + self.y = y[13] + + def get_voltage(self): + return self.y + + +class SystemStatus: + def __init__(self, y): + self.y = y[16] + + def get_system_status(self): + return self.y + + +class VehicleCapabilities: + def __init__(self, y): + self.y = y[1] + + def get_capabilities(self): + return self.y + + +class VehicleArmable: + def __init__(self, y): + self.y = y[15] + + def get_armable(self): + return self.y + + +class VehicleModeName: + def __init__(self, y): + self.y = y[17] + + def get_mode_name(self): + return self.y + + +class Velocity: + def __init__(self, y): + self.y = y[4] + + def get_velocity(self): + return self.y diff --git a/report/clearbot_attributes/Air_speed.py b/report/clearbot_attributes/Air_speed.py deleted file mode 100644 index 453813b..0000000 --- a/report/clearbot_attributes/Air_speed.py +++ /dev/null @@ -1,7 +0,0 @@ -class Air_speed: - def __init__(self, y): - self.y = y[7] - - def get_air_speed(self): - return self.y - \ No newline at end of file diff --git a/report/clearbot_attributes/Attitude.py b/report/clearbot_attributes/Attitude.py deleted file mode 100644 index 79f3a5f..0000000 --- a/report/clearbot_attributes/Attitude.py +++ /dev/null @@ -1,7 +0,0 @@ -class Attitude: - def __init__(self, y): - self.y = y[3] - - def get_attitude(self): - return self.y - \ No newline at end of file diff --git a/report/clearbot_attributes/Battery_status.py b/report/clearbot_attributes/Battery_status.py deleted file mode 100644 index b3533a4..0000000 --- a/report/clearbot_attributes/Battery_status.py +++ /dev/null @@ -1,7 +0,0 @@ -class Battery_status: - def __init__(self, y): - self.y = y[9] - - def get_battery(self): - return self.y - \ No newline at end of file diff --git a/report/clearbot_attributes/Check_vehicle_armed.py b/report/clearbot_attributes/Check_vehicle_armed.py deleted file mode 100644 index b9e6919..0000000 --- a/report/clearbot_attributes/Check_vehicle_armed.py +++ /dev/null @@ -1,6 +0,0 @@ -class Check_vehicle_armed: - def __init__(self, y): - self.y = y[18] - - def get_check(self): - return self.y \ No newline at end of file diff --git a/report/clearbot_attributes/Confidence.py b/report/clearbot_attributes/Confidence.py deleted file mode 100644 index 9c80331..0000000 --- a/report/clearbot_attributes/Confidence.py +++ /dev/null @@ -1,7 +0,0 @@ -class Confidence: - def __init__(self, y): - self.y = y["confidence"] - - def get_confidence(self): - return self.y - \ No newline at end of file diff --git a/report/clearbot_attributes/Confidence.pyc b/report/clearbot_attributes/Confidence.pyc deleted file mode 100644 index f03e7a77347a5edfe2c877637eee206a6a693222..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 655 zcmbu6zfQw25XR3je=C(0i6_WH{Q?Lfx_3w>GGG6@T6qj(k)hK+X-(awI{@$#PS&cvl$B+qzHE*^bEocmp3zh~RPwtuGk8~heug}5_or*Hh2&aG!ucS`U8__G#U5&h;sysk19s+Kgg>~Otfyy-^ zoB=FREm#5Ex)?=jNxCWvv|EOK+%Rbd*a_MZnKZd7S#O>&^6@1RBM%SOEj8ClM25ge z_27G}T4$SK;iE$IuJxT&gWdWes^s^4`y5a3voY(#8nF}?4e98xWjYTm@p=ydwk7Bu+j cwt45@qErBcx2HjmlQLl7GXsEQX-Kle%yBv_V7p?ohwRpZ)HR9kb_ar1S96IKiJF+LbM}~{or0-Z!8a-e^jr@O-m=K4r15*DW3dlp>;b{kL`^7eb})N;gu1sVD~ z3onBgWJ@eo(Jw4;ir3`lwDtf1 diff --git a/report/clearbot_attributes/Range_finder_distance.py b/report/clearbot_attributes/Range_finder_distance.py deleted file mode 100644 index 7c32b82..0000000 --- a/report/clearbot_attributes/Range_finder_distance.py +++ /dev/null @@ -1,6 +0,0 @@ -class Range_finder_distance: - def __init__(self, y): - self.y = y[12] - - def get_distance(self): - return self.y \ No newline at end of file diff --git a/report/clearbot_attributes/Range_finder_voltage.py b/report/clearbot_attributes/Range_finder_voltage.py deleted file mode 100644 index 00a0cf5..0000000 --- a/report/clearbot_attributes/Range_finder_voltage.py +++ /dev/null @@ -1,6 +0,0 @@ -class Range_finder_voltage: - def __init__(self, y): - self.y = y[13] - - def get_voltage(self): - return self.y \ No newline at end of file diff --git a/report/clearbot_attributes/System_status.py b/report/clearbot_attributes/System_status.py deleted file mode 100644 index c3b4698..0000000 --- a/report/clearbot_attributes/System_status.py +++ /dev/null @@ -1,6 +0,0 @@ -class System_status: - def __init__(self, y): - self.y = y[16] - - def get_system_status(self): - return self.y \ No newline at end of file diff --git a/report/clearbot_attributes/Vehicle_capabilities.py b/report/clearbot_attributes/Vehicle_capabilities.py deleted file mode 100644 index 5386c93..0000000 --- a/report/clearbot_attributes/Vehicle_capabilities.py +++ /dev/null @@ -1,7 +0,0 @@ -class Vehicle_capabilities: - def __init__(self, y): - self.y = y[1] - - def get_capabilities(self): - return self.y - \ No newline at end of file diff --git a/report/clearbot_attributes/Vehicle_is_armable.py b/report/clearbot_attributes/Vehicle_is_armable.py deleted file mode 100644 index ed78573..0000000 --- a/report/clearbot_attributes/Vehicle_is_armable.py +++ /dev/null @@ -1,6 +0,0 @@ -class Vehicle_is_armable: - def __init__(self, y): - self.y = y[15] - - def get_armable(self): - return self.y \ No newline at end of file diff --git a/report/clearbot_attributes/Vehicle_mode_name.py b/report/clearbot_attributes/Vehicle_mode_name.py deleted file mode 100644 index 2564984..0000000 --- a/report/clearbot_attributes/Vehicle_mode_name.py +++ /dev/null @@ -1,6 +0,0 @@ -class Vehicle_mode_name: - def __init__(self, y): - self.y = y[17] - - def get_name(self): - return self.y \ No newline at end of file diff --git a/report/clearbot_attributes/Velocity.py b/report/clearbot_attributes/Velocity.py deleted file mode 100644 index 8f715ad..0000000 --- a/report/clearbot_attributes/Velocity.py +++ /dev/null @@ -1,7 +0,0 @@ -class Velocity: - def __init__(self, y): - self.y = y[4] - - def get_velocity(self): - return self.y - \ No newline at end of file diff --git a/report/clearbot_attributes/__init__.py b/report/clearbot_attributes/__init__.py deleted file mode 100644 index 1cb91d4..0000000 --- a/report/clearbot_attributes/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from os.path import dirname, basename, isfile, join -import glob -modules = glob.glob(join(dirname(__file__), "*.py")) -__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')] \ No newline at end of file diff --git a/report/main.py b/report/main.py deleted file mode 100644 index 9e403ac..0000000 --- a/report/main.py +++ /dev/null @@ -1,36 +0,0 @@ -import time -import cv2 -from detector import yolo - -from .pixhawk import Pixhawk -from .report import Report -from .reports import Reports - -report_path = 'report_folder/report.json' -reports_path = 'report_folder/reports.json' - -print("[INFO] accessing video stream...") -vs = cv2.VideoCapture(0) -detector = yolo.Detector("model", use_gpu=True, weights_file="clearbot.weights") - -reports = Reports() -previous = 0 - -while True: - (grabbed, frame) = vs.read() - if not grabbed: - break - result = detector.detect(frame) - current = len(result) - if (current > 0 and current > previous): - result_object = result[current - 1] - pixhawk = Pixhawk() - yolo_result = result_object - pixhawk_location = str(pixhawk.do_capture_global_location()) - report = Report(yolo_result, pixhawk_location) - report.create_report() - report.print_report() - report.write_report(report_path) - reports.combine(reports_path) - previous = current - time.sleep(5) diff --git a/report/pixhawk.py b/report/pixhawk.py index c2e0800..a4543c6 100644 --- a/report/pixhawk.py +++ b/report/pixhawk.py @@ -1,143 +1,143 @@ from dronekit import connect, VehicleMode, LocationGlobalRelative + class Pixhawk: - vehicle = None - - def __init__(self, connection_port="/dev/ttyTHS1", baud=57600): - - self.vehicle = connect(connection_port, wait_ready=True, baud=baud) - self.vehicle.mode = VehicleMode("MANUAL") - self.result = [] - - def firmware_version(self): - return self.vehicle.version - - def vehicle_capabilities(self): - return self.vehicle.capabilities.ftp - - def do_capture_global_location(self): - return self.vehicle.location.global_frame - - def do_capture_relative_global_location(self): - return self.vehicle.location.global_relative_frame - - def do_capture_altitude(self): - return self.vehicle.altitude - - def do_capture_velocity(self): - return self.vehicle.velocity - - def do_capture_gps(self): - return self.vehicle.gps_0 - - def do_capture_ground_speed(self): - return self.vehicle.groundspeed - - def do_capture_air_speed(self): - return self.vehicle.airspeed - - def gimbal_status(self): - return self.vehicle.gimbal - - def battery_status(self): - return self.vehicle.battery - - def EKF_OK(self): - return self.vehicle.ekf_ok - - def last_heartbeat(self): - return self.vehicle.last_heartbeat - - def range_finder(self): - return self.vehicle.rangefinder - - def range_finder_distance(self): - return self.vehicle.rangefinder.distance - - def range_finder_voltage(self): - return self.vehicle.rangefinder.voltage - - def heading(self): - return self.vehicle.heading - - def vehicle_is_armable(self): - return self.vehicle.is_armable - - def system_status(self): - return self.vehicle.system_status.state - - def vehicle_mode_name(self): - return self.vehicle.mode.name - - def check_vehicle_armed(self): - return self.vehicle.armed - - def get_data(self): - # self.result.append + vehicle = None + + def __init__(self, connection_port="/dev/ttyTHS1", baud=57600): + self.vehicle = connect(connection_port, wait_ready=True, baud=baud) + self.vehicle.mode = VehicleMode("MANUAL") + self.result = [] + + def firmware_version(self): + return self.vehicle.version + + def vehicle_capabilities(self): + return self.vehicle.capabilities.ftp + + def do_capture_global_location(self): + return self.vehicle.location.global_frame + + def do_capture_relative_global_location(self): + return self.vehicle.location.global_relative_frame + + def do_capture_altitude(self): + return self.vehicle.altitude + + def do_capture_velocity(self): + return self.vehicle.velocity + + def do_capture_gps(self): + return self.vehicle.gps_0 + + def do_capture_ground_speed(self): + return self.vehicle.groundspeed + + def do_capture_air_speed(self): + return self.vehicle.airspeed + + def gimbal_status(self): + return self.vehicle.gimbal + + def battery_status(self): + return self.vehicle.battery + + def EKF_OK(self): + return self.vehicle.ekf_ok + + def last_heartbeat(self): + return self.vehicle.last_heartbeat + + def range_finder(self): + return self.vehicle.rangefinder + + def range_finder_distance(self): + return self.vehicle.rangefinder.distance + + def range_finder_voltage(self): + return self.vehicle.rangefinder.voltage + + def heading(self): + return self.vehicle.heading + + def vehicle_is_armable(self): + return self.vehicle.is_armable + + def system_status(self): + return self.vehicle.system_status.state + + def vehicle_mode_name(self): + return self.vehicle.mode.name + + def check_vehicle_armed(self): + return self.vehicle.armed + + def get_data(self): + # self.result.append # "firmware_version" : self.vehicle.version, # "vehicle_capabilities" : self.vehicle.capabilities.ftp, # "location" :self.vehicle.location.global_frame, - # "altitude" : self.vehicle.attitude, - # "velocity" : self.vehicle.velocity, - # "gps" : self.vehicle.gps_0, - # "ground_speed" : self.vehicle.groundspeed, - # "air_speed" : self.vehicle.airspeed, - # "gimbal_status" : self.vehicle.gimbal, - # "battery_status" : self.vehicle.battery, - # "EKF_OK" : self.vehicle.ekf_ok, - # "last_heartbeat" : self.vehicle.last_heartbeat, - # "range_finder_distance" : self.vehicle.rangefinder.distance, - # "range_finder_voltage" : self.vehicle.rangefinder.voltage, - # "heading" : self.vehicle.heading, - # "vehicle_is_armable" : self.vehicle.is_armable, - # "system_status" : self.vehicle.system_status.state, - # "vehicle_mode_name" : self.vehicle.mode.name, - # "check_vehicle_armed" : self.vehicle.armed + # "altitude" : self.vehicle.attitude, + # "velocity" : self.vehicle.velocity, + # "gps" : self.vehicle.gps_0, + # "ground_speed" : self.vehicle.groundspeed, + # "air_speed" : self.vehicle.airspeed, + # "gimbal_status" : self.vehicle.gimbal, + # "battery_status" : self.vehicle.battery, + # "EKF_OK" : self.vehicle.ekf_ok, + # "last_heartbeat" : self.vehicle.last_heartbeat, + # "range_finder_distance" : self.vehicle.rangefinder.distance, + # "range_finder_voltage" : self.vehicle.rangefinder.voltage, + # "heading" : self.vehicle.heading, + # "vehicle_is_armable" : self.vehicle.is_armable, + # "system_status" : self.vehicle.system_status.state, + # "vehicle_mode_name" : self.vehicle.mode.name, + # "check_vehicle_armed" : self.vehicle.armed # }) - self.result=[ + self.result = [ str(self.vehicle.version), str(self.vehicle.capabilities.ftp), str(self.vehicle.location.global_frame), - str(self.vehicle.attitude), - str(self.vehicle.velocity), - str(self.vehicle.gps_0), - self.vehicle.groundspeed, - self.vehicle.airspeed, - str(self.vehicle.gimbal), - str(self.vehicle.battery), - self.vehicle.ekf_ok, - self.vehicle.last_heartbeat, - str(self.vehicle.rangefinder.distance), - str(self.vehicle.rangefinder.voltage), - self.vehicle.heading, - self.vehicle.is_armable, - self.vehicle.system_status.state, - self.vehicle.mode.name, - self.vehicle.armed - ] - #self.result = result - return self.result - - def debug(self): - print('Autopilot Firmware version: %s' % self.vehicle.version) - print('Autopilot capabilities (supports ftp): %s' % self.vehicle.capabilities.ftp) - print('Global Location: %s' % self.vehicle.location.global_frame) - print('Global Location (relative altitude): %s' % self.vehicle.location.global_relative_frame) - print('Local Location: %s' % self.vehicle.location.local_frame) - print('Attitude: %s' % self.vehicle.attitude) - print('Velocity: %s' % self.vehicle.velocity) - print('GPS: %s' % self.vehicle.gps_0) - print('Groundspeed: %s' % self.vehicle.groundspeed) - print('Airspeed: %s' % self.vehicle.airspeed) - print('Gimbal status: %s' % self.vehicle.gimbal) - print('Battery: %s' % self.vehicle.battery) - print('EKF OK?: %s' % self.vehicle.ekf_ok) - print('Last Heartbeat: %s' % self.vehicle.last_heartbeat) - print('Rangefinder: %s' % self.vehicle.rangefinder) - print('Rangefinder distance: %s' % self.vehicle.rangefinder.distance) - print('Rangefinder voltage: %s' % self.vehicle.rangefinder.voltage) - print('Heading: %s' % self.vehicle.heading) - print('Is Armable?: %s' % self.vehicle.is_armable) - print('System status: %s' % self.vehicle.system_status.state) - print('Mode: %s' % self.vehicle.mode.name) - print('Armed: %s' % self.vehicle.armed) + str(self.vehicle.attitude), + str(self.vehicle.velocity), + str(self.vehicle.gps_0), + self.vehicle.groundspeed, + self.vehicle.airspeed, + str(self.vehicle.gimbal), + str(self.vehicle.battery), + self.vehicle.ekf_ok, + self.vehicle.last_heartbeat, + str(self.vehicle.rangefinder.distance), + str(self.vehicle.rangefinder.voltage), + self.vehicle.heading, + self.vehicle.is_armable, + self.vehicle.system_status.state, + self.vehicle.mode.name, + self.vehicle.armed + ] + # self.result = result + return self.result + + def debug(self): + print('Autopilot Firmware version: %s' % self.vehicle.version) + print('Autopilot capabilities (supports ftp): %s' % self.vehicle.capabilities.ftp) + print('Global Location: %s' % self.vehicle.location.global_frame) + print('Global Location (relative altitude): %s' % self.vehicle.location.global_relative_frame) + print('Local Location: %s' % self.vehicle.location.local_frame) + print('Attitude: %s' % self.vehicle.attitude) + print('Velocity: %s' % self.vehicle.velocity) + print('GPS: %s' % self.vehicle.gps_0) + print('Groundspeed: %s' % self.vehicle.groundspeed) + print('Airspeed: %s' % self.vehicle.airspeed) + print('Gimbal status: %s' % self.vehicle.gimbal) + print('Battery: %s' % self.vehicle.battery) + print('EKF OK?: %s' % self.vehicle.ekf_ok) + print('Last Heartbeat: %s' % self.vehicle.last_heartbeat) + print('Rangefinder: %s' % self.vehicle.rangefinder) + print('Rangefinder distance: %s' % self.vehicle.rangefinder.distance) + print('Rangefinder voltage: %s' % self.vehicle.rangefinder.voltage) + print('Heading: %s' % self.vehicle.heading) + print('Is Armable?: %s' % self.vehicle.is_armable) + print('System status: %s' % self.vehicle.system_status.state) + print('Mode: %s' % self.vehicle.mode.name) + print('Armed: %s' % self.vehicle.armed) diff --git a/report/report.py b/report/report.py index ecf0e70..09b2390 100644 --- a/report/report.py +++ b/report/report.py @@ -1,62 +1,62 @@ import json -from report.clearbot_attributes import * +from report.attributes import * -class Report: - def __init__(self, yolo, pixhawk): - self.label = Label.Label(yolo) - self.confidence = Confidence.Confidence(yolo) - self.firmware_version = Firmware_version.Firmware_version(pixhawk) - self.vehicle_capabilities = Vehicle_capabilities.Vehicle_capabilities(pixhawk) - self.location = Location.Location(pixhawk) - self.attitude = Attitude.Attitude(pixhawk) - self.velocity = Velocity.Velocity(pixhawk) - self.gps = Gps.Gps(pixhawk) - self.ground_speed = Ground_speed.Ground_speed(pixhawk) - self.air_speed = Air_speed.Air_speed(pixhawk) - self.gimbal_status = Gimbal_status.Gimbal_status(pixhawk) - self.battery_status = Battery_status.Battery_status(pixhawk) - self.ekf_ok = Ekf_ok.Ekf_ok(pixhawk) - self.last_heartbeat = Last_heartbeat.Last_heartbeat(pixhawk) - self.range_finder_distance = Range_finder_distance.Range_finder_distance(pixhawk) - self.range_finder_voltage = Range_finder_voltage.Range_finder_voltage(pixhawk) - self.heading = Heading.Heading(pixhawk) - self.vehicle_is_armable = Vehicle_is_armable.Vehicle_is_armable(pixhawk) - self.system_status = System_status.System_status(pixhawk) - self.vehicle_mode_name = Vehicle_mode_name.Vehicle_mode_name(pixhawk) - self.check_vehicle_armed = Check_vehicle_armed.Check_vehicle_armed(pixhawk) - self.report = {} - def create_report(self): - report = { - "label": self.label.get_label(), - "confidence": self.confidence.get_confidence(), - "firmware_version" : self.firmware_version.get_version(), - "vehicle_capabilities" : self.vehicle_capabilities.get_capabilities(), - "location" :self.location.get_coordinate(), - "attitude" : self.attitude.get_attitude(), - "velocity" : self.velocity.get_velocity(), - "gps" : self.gps.get_gps(), - "ground_speed" : self.ground_speed.get_speed(), - "air_speed" : self.air_speed.get_air_speed(), - "gimbal_status" : self.gimbal_status.get_status(), - "battery_status" : self.battery_status.get_battery(), - "EKF_OK" : self.ekf_ok.get_ekf(), - "last_heartbeat" : self.last_heartbeat.get_last_heartbeat(), - "range_finder_distance" : self.range_finder_distance.get_distance(), - "range_finder_voltage" : self.range_finder_voltage.get_voltage(), - "heading" : self.heading.get_heading(), - "vehicle_is_armable" : self.vehicle_is_armable.get_armable(), - "system_status" : self.system_status.get_system_status(), - "vehicle_mode_name" : self.vehicle_mode_name.get_name(), - "check_vehicle_armed" : self.check_vehicle_armed.get_check() - } - self.report = report +class Report: + def __init__(self, yolo, pixhawk): + self.label = Label(yolo) + self.confidence = Confidence(yolo) + self.firmware_version = FirmwareVersion(pixhawk) + self.vehicle_capabilities = VehicleCapabilities(pixhawk) + self.location = Location(pixhawk) + self.attitude = Altitude(pixhawk) + self.velocity = Velocity(pixhawk) + self.gps = GPS(pixhawk) + self.ground_speed = GroundSpeed(pixhawk) + self.air_speed = AirSpeed(pixhawk) + self.gimbal_status = GimbalStatus(pixhawk) + self.battery_status = BatteryStatus(pixhawk) + self.ekf_ok = EkfOK(pixhawk) + self.last_heartbeat = LastHeartbeat(pixhawk) + self.range_finder_distance = RangeFinderDistance(pixhawk) + self.range_finder_voltage = RangeFinderVoltage(pixhawk) + self.heading = Heading(pixhawk) + self.vehicle_is_armable = VehicleArmable(pixhawk) + self.system_status = SystemStatus(pixhawk) + self.vehicle_mode_name = VehicleModeName(pixhawk) + self.check_vehicle_armed = CheckVehicleArmed(pixhawk) + self.report = {} - def print_report(self): - print(self.report) + def create_report(self): + report = { + "label": self.label.get_label(), + "confidence": self.confidence.get_confidence(), + "firmware_version": self.firmware_version.__version__(), + "vehicle_capabilities": self.vehicle_capabilities.get_capabilities(), + "location": self.location.get_coordinates(), + "attitude": self.attitude.get_altitude(), + "velocity": self.velocity.get_velocity(), + "gps": self.gps.get_gps(), + "ground_speed": self.ground_speed.get_ground_speed(), + "air_speed": self.air_speed.get_air_speed(), + "gimbal_status": self.gimbal_status.get_gimbal_status(), + "battery_status": self.battery_status.get_battery_status(), + "EKF_OK": self.ekf_ok.get_ekf_status(), + "last_heartbeat": self.last_heartbeat.get_last_heartbeat(), + "range_finder_distance": self.range_finder_distance.get_distance(), + "range_finder_voltage": self.range_finder_voltage.get_voltage(), + "heading": self.heading.get_heading(), + "vehicle_is_armable": self.vehicle_is_armable.get_armable(), + "system_status": self.system_status.get_system_status(), + "vehicle_mode_name": self.vehicle_mode_name.get_mode_name(), + "check_vehicle_armed": self.check_vehicle_armed.get_armed_status() + } + self.report = report - def write_report(self, path): - with open(path, 'w') as file_stream: - json.dump(self.report, file_stream, indent=4, sort_keys= True) + def print_report(self): + print(self.report) + def write_report(self, path): + with open(path, 'w') as file_stream: + json.dump(self.report, file_stream, indent=4, sort_keys=True) diff --git a/report/thing_speak.py b/report/thingspeak.py similarity index 68% rename from report/thing_speak.py rename to report/thingspeak.py index c0689b6..1c11b54 100644 --- a/report/thing_speak.py +++ b/report/thingspeak.py @@ -1,30 +1,28 @@ import os import paho.mqtt.publish as publish -from report.clearbot_attributes import * -import time +from report.attributes import Label, Confidence, Location, BatteryStatus, SystemStatus import re -from report import config -topic = "channels/"+ config.CHANNEL_ID +"/publish/"+ config.API_KEY +# topic = "channels/"+ config.CHANNEL_ID +"/publish/"+ config.API_KEY +topic = "channels/publish" mqttHost = "mqtt.thingspeak.com" tTransport = "tcp" tPort = 1883 tTLS = None -class Thing_speak: +class ThingSpeak: + def __init__(self, yolo, pixhawk): + self.label = Label(yolo) + self.confidence = Confidence(yolo) + self.location = Location(pixhawk) + self.battery_status = BatteryStatus(pixhawk) + self.system_status = SystemStatus(pixhawk) - def __init__(self,yolo, pixhawk): - self.label = Label.Label(yolo) - self.confidence = Confidence.Confidence(yolo) - self.location = Location.Location(pixhawk) - self.battery_status = Battery_status.Battery_status(pixhawk) - self.system_status = System_status.System_status(pixhawk) - def show_thingspeak(self): #get gps_location from string variable and stored it in a list - location_string = self.location.get_coordinate() + location_string = self.location.get_coordinates() gps_location = re.findall(r"[-+]?\d*\.\d+|\d+", location_string) label_data = str(self.label.get_label())