diff --git a/1.jpg b/1.jpg new file mode 100644 index 0000000..b00180e Binary files /dev/null and b/1.jpg differ diff --git a/2.jpg b/2.jpg new file mode 100644 index 0000000..f0c87af Binary files /dev/null and b/2.jpg differ diff --git a/3.jpg b/3.jpg new file mode 100644 index 0000000..7ff28dd Binary files /dev/null and b/3.jpg differ diff --git a/DronePhoto1.jpg b/DronePhoto1.jpg new file mode 100644 index 0000000..a25c38e Binary files /dev/null and b/DronePhoto1.jpg differ diff --git a/DronePhoto2.jpg b/DronePhoto2.jpg new file mode 100644 index 0000000..8985494 Binary files /dev/null and b/DronePhoto2.jpg differ diff --git a/__pycache__/auvsiServerCommunication.cpython-34.pyc b/__pycache__/auvsiServerCommunication.cpython-34.pyc new file mode 100644 index 0000000..4120829 Binary files /dev/null and b/__pycache__/auvsiServerCommunication.cpython-34.pyc differ diff --git a/__pycache__/bluetoothServer.cpython-34.pyc b/__pycache__/bluetoothServer.cpython-34.pyc new file mode 100644 index 0000000..f0290e4 Binary files /dev/null and b/__pycache__/bluetoothServer.cpython-34.pyc differ diff --git a/__pycache__/challenges.cpython-34.pyc b/__pycache__/challenges.cpython-34.pyc new file mode 100644 index 0000000..1b60ee9 Binary files /dev/null and b/__pycache__/challenges.cpython-34.pyc differ diff --git a/__pycache__/variables.cpython-34.pyc b/__pycache__/variables.cpython-34.pyc new file mode 100644 index 0000000..9cdba97 Binary files /dev/null and b/__pycache__/variables.cpython-34.pyc differ diff --git a/__pycache__/xbee.cpython-34.pyc b/__pycache__/xbee.cpython-34.pyc new file mode 100644 index 0000000..a18c57c Binary files /dev/null and b/__pycache__/xbee.cpython-34.pyc differ diff --git a/auvsiServerCommunication.py b/auvsiServerCommunication.py new file mode 100644 index 0000000..83c9c12 --- /dev/null +++ b/auvsiServerCommunication.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python +import sys +import json +import requests +''' +server = IP +server = http://... +''' +url2 = 'http://betatestback.journeytheapp.com' ; +url = 'http://ec2-52-0-198-215.compute-1.amazonaws.com' ; + +teamCode = 'VTEC' ; +PORT = 8080 ; +#PORT = 80; +PORT_AUVSI = 8080 ; + +retryCount = 0 ; +connectionLost = False; +courseA = 'courseA'; +courseB = 'courseB'; +courseC = 'courseC'; + +def send_http_followLeader(course): + ''' + GET + /followLeader/{course}/{teamCode} + ''' + ''' + expected return value {"code":"23"} + ''' + addr = '/followLeader/'; + + server = url + addr + course + '/' + teamCode ; + + r = requests.get(server); + + #print(server) + + if(r.status_code == 200): + print ('Status 200: OK'); + print((r.text)) + elif(r.status_code == 400): + print('Status 400: The requested Form isnt Ok, Please check it'); + elif(r.status_code == 404): + print('Status 404: Course or Team are Wrong'); + elif(r.status_code == 500): + print('Status 500: The gate assigment is broken'); + elif(r.status_code == 503): + print('Status 503: Please try the request again'); + if(retryCount < 100): + send_http_heartbeat(course,timestamp,challenge,latitude,longitude) + else: + retryCount = 0; + connectionLost = True; + +def send_http_heartbeat(course,timestamp,challenge,latitude,longitude): + ''' + POST + /heartbeat/ + course + teamCode + timestamp = YYYYMMDDHHMMSS in UTC + challenge = "speed", "docking", "path", "follow" or "return" + latitude = hddd.dddddd + longitude = hddd.dddddd + ''' + ''' + expected return value {"success":} + status = true //Run still active + status = felse //Run have ended + ''' + addr = '/heartbeat/' + course + '/' + teamCode; + + server = url + addr ; + + payload = {"timestamp":str(timestamp),"challenge":challenge,"position":{"datum":"WGS84","latitude":round(latitude,6),"longitude":round(longitude,6)}} + + r = requests.post(server, data=json.dumps(payload), headers={'Content-type': 'application/json'}) ; + + #print("-----Heartbeat: ") + #print(challenge) + #print(r) + #print(payload) + + if(r.status_code == 200): + print ('Status 200: OK'); + print((r.text)) + elif(r.status_code == 400): + print('Status 400: The requested Form isnt Ok, Please check it'); + elif(r.status_code == 404): + print('Status 404: Course or Team are Wrong'); + elif(r.status_code == 500): + print('Status 500: The gate assigment is broken'); + elif(r.status_code == 503): + print('Status 503: Please try the request again'); + if(retryCount < 100): + send_http_heartbeat(course,timestamp,challenge,latitude,longitude) + else: + print("Response unexpected") + + +def send_http_start(course): + ''' + POST + /run/start + course + teamCode + ''' + ''' + expected return value {"success":} + status = true //Run still active + status = felse //Run have ended + ''' + addr = '/run/start/' + course + '/' + teamCode; + + server = url + addr ; + + #print(server) + r = requests.post(server); + + #print(server) + #print(payload) + + if(r.status_code == 200): + print ('Status 200: OK'); + print((r.text)) + elif(r.status_code == 400): + print('Status 400: The requested Form isnt Ok, Please check it'); + elif(r.status_code == 404): + print('Status 404: Course or Team are Wrong'); + elif(r.status_code == 500): + print('Status 500: The gate assigment is broken'); + elif(r.status_code == 503): + print('Status 503: Please try the request again'); + if(retryCount < 100): + send_http_heartbeat(course,timestamp,challenge,latitude,longitude) + +def send_http_end(course): + ''' + POST + /run/end + course + teamCode + ''' + ''' + expected return value {"success":} + status = true //Run still active + status = felse //Run have ended + ''' + addr = '/run/end/' + course + '/' + teamCode; + + server = url + addr ; + + print(server) + + r = requests.post(server); + + if(r.status_code == 200): + print ('Status 200: OK'); + print((r.text)) + elif(r.status_code == 400): + print('Status 400: The requested Form isnt Ok, Please check it'); + elif(r.status_code == 404): + print('Status 404: Course or Team are Wrong'); + elif(r.status_code == 500): + print('Status 500: The gate assigment is broken'); + elif(r.status_code == 503): + print('Status 503: Please try the request again'); + if(retryCount < 100): + send_http_heartbeat(course,timestamp,challenge,latitude,longitude) + + +def send_http_docking(course,filename): + ''' + POST + /docking/image/ + course + teamCode + name = file + filename = 'test.jpg' + ''' + ''' + expected return value {"id":}} + ''' + + print("--- Send image to AUVSI ---") + + addr = '/docking/image/' + course +'/' + teamCode ; + + header = {'Content-type':'multipart/form-data', 'Content-Length':7280} ; + + server = url + addr ; + + files = {'name' : open(filename,'rb') } + + payload = {'filename': filename } ; + + r = requests.post(server, data = payload, files=files) ; + imgId = '-1' + if(r.status_code == 100): + print ('Status 100: Server is ready to accept multipart chunk'); + elif(r.status_code == 200): + print ('Status 200: OK'); + print((r.text)) + imgId = json.loads(r.text) + elif(r.status_code == 202): + print('Status 202: Upload successfully completed'); + print((r.text)) + imgId = json.loads(r.text) + elif(r.status_code == 400): + print('Status 400: The requested Form isnt Ok, Please check it'); + elif(r.status_code == 404): + print('Status 404: Course or Team are Wrong'); + elif(r.status_code == 500): + print('Status 500: The gate assigment is broken'); + elif(r.status_code == 503): + print('Status 503: Please try the request again'); + if(retryCount < 100): + send_http_heartbeat(course,timestamp,challenge,latitude,longitude) + + return imgId + diff --git a/bluetoothServer.py b/bluetoothServer.py new file mode 100644 index 0000000..7b47b5e --- /dev/null +++ b/bluetoothServer.py @@ -0,0 +1,181 @@ +from bluetooth import * +import os +import io +from PIL import Image +from array import array +#### +## 29.153847 +## -81.015432 +### +socketBusy = False + +''' + Receive images when you send the takeoff message to the drone +''' +def beginMission(): + + action = "takeoff" + actionBytes = action.encode('utf-8') + client_sock.send(actionBytes) + + #Se bloquea el socket para evitar mensajes inesperados + global socketBusy + socketBusy = True + + data = bytes() + moreImages = True + photoCount = 1 + while(moreImages): + try: + image_bytes = bytes() + moreBytes = True + print("waiting for image..") + while(moreBytes): + + data = client_sock.recv(1024) + if len(data) == 0: + break + + if(data == bytes("endimage", 'utf-8')): + moreBytes = False + print("Recieved image..") + break + + if(data == bytes("finish", 'utf-8')): + print("Finished getting images...") + moreBytes = False + moreImages = False + break + + print(data) + + image_bytes += data + + if not moreImages: + break + + image = Image.open(io.BytesIO(image_bytes)) + image.save("DronePhoto" + str(photoCount) + ".jpg") + #image.show() + + photoCount += 1 + except IOError as e: + print("I/O error") + pass + + waitForLand() + +''' + +''' +def waitForLand(): + print("Waiting for the drone to land...") + try: + data = client_sock.recv(1024) + if len(data) == 0: + print("nada") + + land = data.decode("utf-8") + + if(land == "land"): + print("Drone landed...") + #Volver a mover barco + + except IOError as e: + print("I/O error") + pass + + # Se libera el socket + global socketBusy + socketBusy = False + + +''' + Recibe las coordenadas gps del dron, se debe bloquear la + llamada a esta función cuando el dron está volando porque + se podrían recibir datos no esperados +''' +def getDroneGPS(): + if(not socketBusy): + try: + data = client_sock.recv(1024) + if len(data) == 0: + print("nada") + + coords = data.decode("utf-8") + + # Las coordenadas se mandan en la forma "22.1342,-100.21341" + latitude, longitude = coords.split(",") + + # Si se necesitan en tipo float, descomentar lo siguiente + latitudeFloat = float(latitude) + longitudeFloat = float(longitude) + + print("Latitude: " + latitude) + print("Longitude: " + longitude) + + ## Hacer algo con las coordenadas + # + # + # + except IOError as e: + print("I/O error") + pass + + + +server_sock=BluetoothSocket( RFCOMM ) +server_sock.bind(("",PORT_ANY)) +server_sock.listen(1) + +port = server_sock.getsockname()[1] + +uuid = "fa87c0d0-afac-11de-8a39-0800200c9a66" + +advertise_service( server_sock, "SampleServer", + service_id = uuid, + service_classes = [ uuid, SERIAL_PORT_CLASS ], + profiles = [ SERIAL_PORT_PROFILE ], +# protocols = [ OBEX_UUID ] + ) + +print("Waiting for connection on RFCOMM channel %d" % port) + +client_sock, client_info = server_sock.accept() +print("Accepted connection from ", client_info) + + +# Flujo: Primero se manda un mensaje con el string "takeoff" +# para después pasar a un estado donde espera las imagenes +# - Cuando termina de recibir una, el android manda el string "endimage" +# - Cuando termina de recibir todas las imagenes, el android manda el string "finish" +# - Cuando el dron aterriza, android manda el string "land" +# - Cuando los dos booleanos estan en true, el barco puede continuar + +moreMessages = True +''' +while(moreMessages): + action = input() + actionBytes = action.encode('utf-8') + client_sock.send(actionBytes) + if action == "takeoff": + print("Mission in progress...") + beginMission() + elif action == "gps": + print("Getting drone coords...") + getDroneGPS() + elif action == "emergency": + print("Returning to home...") + elif action == "bye": + moreMessages = False + print("Bye") + +''' + +def disconnect(): + ## Al final se desconecta y se deben cerrar los sockets. + print("disconnected") + + client_sock.close() + server_sock.close() + print("all done") \ No newline at end of file diff --git a/boat.py b/boat.py new file mode 100644 index 0000000..8ca462f --- /dev/null +++ b/boat.py @@ -0,0 +1,255 @@ +import sys +import os +import xbee +import time +import variables as var +#import lib.imu as imu +#import lib.variables as var + +x = xbee.xbee("/dev/ttyUSB1") + +challenges = ['autonomous','speed', 'follow', 'path', 'docking', 'return'] + +courses = ['courseA', 'courseB', 'courseC'] + +#To do: Sacar coordenadas de la imu +lat_long = ["29.151098","-81.016505"]; + +# challenge string +var.currChallenge = 'N' +data = ['','','','','','','',''] +enable_pos = 0 +R_kill_switch = 1 +status = 2 +course = 3 +challenge_pos = 4 +dock = 5 + +def testing_case(): + global data + #imu.init(); + var.currChallenge = 's' + for i in range(1,5): + send_heartbeat() + + var.currChallenge = 'a' + for i in range(1,5): + send_heartbeat() + + var.currChallenge = 'N' + for i in range(1,5): + send_heartbeat() + + var.currChallenge = 'd' + for i in range(1,5): + send_heartbeat() + + # Aqui esta haciendo el docking + resp = '0' + counter = 0 + print("Receiving docking data...") + while resp == '0': + s = x.receive_from_station(); + resp = s[enable_pos]; + counter += 1 + + print("Go to dock : ", s[dock]) + if(counter < 5): + time.sleep(6-counter); + else: + print("Algo salio mal con la respuesta del dock") + + var.currChallenge = 'r' + for i in range(1,5): + send_heartbeat() + + var.currChallenge = 'e' + for i in range(1,5): + send_heartbeat() + + +def start_mission(): + global data + #imu.init(); + for i in range(1,5): + send_start(lat_long) + + while(data[challenge_pos] != 'd'): + send_heartbeat() + + # Aqui esta haciendo el docking + resp = '0' + counter = 0 + print("Receiving docking data...") + while resp == '0': + s = x.receive_from_station(); + resp = s[enable_pos]; + counter += 1 + + print("Go to dock : ", s[dock]) + + if(counter < 5): + time.sleep(6-counter); + else: + print("Algo salio mal con la respuesta del dock") + + # To Do: Mover el barco hacia s[dock] + + # Espera a que se mande la 'e' de fin de mision + while(data[challenge_pos] != 'e'): + send_heartbeat() + + +def send_heartbeat(): + # To Do: Obtener coordenadas y cambiar en la siguiente linea + #coords = imu.get_gps_coords(); + la = lat_long[0].zfill(10); + lo = lat_long[1].zfill(10); + x.set_latlong(la,lo); + x.set_challenge(var.currChallenge) + x.send2station() + time.sleep(1.05) + + +def send_start(latlong): + x.set_flying("0"); + x.set_takeoff("0"); + la = lat_long[0].zfill(10); + lo = lat_long[1].zfill(10); + x.set_latlong(la,lo); + x.set_challenge('s'); + x.send2station(); + time.sleep(1.05); + +def send_end(latlong): + x.set_flying("0"); + x.set_takeoff("0"); + x.set_latlong(latlong[0],latlong[1]); + x.set_challenge('e'); + x.send2station(); + time.sleep(1.05); + +def send_return(latlong): + x.set_flying("0"); + x.set_takeoff("0"); + x.set_latlong(latlong[0],latlong[1]); + x.set_challenge('r'); + x.send2station(); + time.sleep(1.05); + +def send_follow(latlong): + x.set_flying("0"); + x.set_takeoff("0"); + x.set_latlong(latlong[0],latlong[1]); + x.set_challenge('f'); + x.send2station(); + time.sleep(1.05); + +def send_docking(latlong): + x.set_flying("0"); + x.set_takeoff("0"); + x.set_latlong(latlong[0],latlong[1]); + x.set_challenge('d'); + x.send2station(); + time.sleep(1.05); + +def send_heart_beat(latlong): + x.set_flying("0"); + x.set_takeoff("0"); + x.set_latlong(latlong[0],latlong[1]); + x.set_challenge('N'); + x.send2station(); + time.sleep(1.05); + +def send_takeoff(latlong): + x.set_flying("0"); + x.set_takeoff("1"); + x.set_latlong(latlong[0],latlong[1]); + x.set_challenge('d'); + x.send2station(); + time.sleep(1.05); + +def send_flying(latlong): + x.set_flying("1"); + x.set_takeoff("1"); + x.set_latlong(latlong[0],latlong[1]); + x.set_challenge('d'); + x.send2station(); + time.sleep(1.05); + +def send_landing(latlong): + x.set_flying("0"); + x.set_takeoff("0"); + x.set_landing("1"); + x.set_latlong(latlong[0],latlong[1]); + x.set_challenge('d'); + x.send2station(); + time.sleep(1.05); + +#Send Testing OK +def send_testing(): + global enable_pos + #while True: + send_start(lat_long); + send_start(lat_long); + send_start(lat_long); + + for i in range(1,5): + send_heart_beat(lat_long); + if i == 2: + send_docking(lat_long); + send_docking(lat_long); + time.sleep(2); + resp = '0' + counter = 0 + while resp == '0': + print("Receiving") + s = x.receive_from_station(); + resp = s[enable_pos]; + counter += 1 + print("Go to dock : ", s[dock]) + + if(counter < 5): + time.sleep(6-counter); + send_takeoff(lat_long); + send_flying(lat_long); + send_landing(lat_long); + elif i == 5: + send_follow(lat_long); + elif i == 9: + send_return(lat_long); + + send_end(lat_long); + send_end(lat_long); + send_end(lat_long); + + +def send_testing_2(): + resp = '' + while(resp != '1'): + s = x.receive_from_station(); + resp = s[enable_pos]; + while(s[challenge_pos] == '0'): + send_start(lat_long); + s = x.receive_from_station(); + print("Starting") + x.send_end(); + +#Receive Testing +def receive_testing(): + s = x.receive_from_station(); + print(s) + return s + + + +if __name__ == '__main__': + testing_case() + #start_mission() + ''' + while True: + s = receive_testing(); + if (s[enable_pos] == '1'): + send_heart_beat() + ''' + diff --git a/challenges.py b/challenges.py new file mode 100644 index 0000000..bd76f0b --- /dev/null +++ b/challenges.py @@ -0,0 +1,442 @@ +import Jetson.dbscan_contours +import math +import pathfindingv2 as pathfinding +from pathfinding import closest_node +from scipy import spatial +import numpy as np +import sys +sys.path.append('/usr/local/lib/python3.4/site-packages/') +import cv2 + +class Autonomous_Navigation: + + def __init__(self): + self.red_lower_bounds=[] + self.red_upper_bounds=[] + with open('red_bounds.txt', 'r') as f: + content = f.readlines() + content = [x.strip('\n') for x in content] + for line in content: + split=line.split(',') + #print(split) + if (len(split)>1): + self.red_lower_bounds.append(np.array([float(split[0]),float(split[1]),float(split[2])])) + self.red_upper_bounds.append(np.array([float(split[3]),float(split[4]),float(split[5])])) + + + self.green_lower_bounds=[] + self.green_upper_bounds=[] + with open('green_bounds.txt', 'r') as f: + content = f.readlines() + content = [x.strip('\n') for x in content] + for line in content: + split=line.split(',') + if (len(split)>1): + self.green_lower_bounds.append(np.array([float(split[0]),float(split[1]),float(split[2])])) + self.green_upper_bounds.append(np.array([float(split[3]),float(split[4]),float(split[5])])) + + def get_destination(self,image): + h,w,c=image.shape + red_binary=np.zeros((h,w),dtype=np.uint8) + green_binary=np.zeros((h,w),dtype=np.uint8) + image2=image.copy() + hsv=cv2.cvtColor(image,cv2.COLOR_BGR2HSV) + kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) + for i,lower in enumerate(self.green_lower_bounds): + green_hsv_filtered=cv2.inRange(hsv,lower,self.green_upper_bounds[i]) + #print(lower) + #print(self.green_upper_bounds[i]) + green1 = cv2.morphologyEx(green_hsv_filtered, cv2.MORPH_OPEN, kernel) + green_binary=np.bitwise_or(green_binary,green1) + + + for i,lower in enumerate(self.red_lower_bounds): + #print(lower) + #print(self.red_upper_bounds[i]) + red_hsv_filtered=cv2.inRange(image,lower,self.red_upper_bounds[i]) + red1 = cv2.morphologyEx(red_hsv_filtered, cv2.MORPH_OPEN, kernel) + red_binary=np.bitwise_or(red_binary,red1) + + red_contours=cv2.findContours(red_binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) + green_contours=cv2.findContours(green_binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) + binary=np.bitwise_or(green_binary,red_binary) + foundRed=False + foundGreen=False + if len(red_contours[1])>=1: + + red_area_max=0 + #Find 2 biggest areas + biggest_red=None + for contorno in red_contours[1]: + #print('Contour len:',len(contorno)) + area=cv2.contourArea(contorno) + x1,y1,dx1,dy1 = cv2.boundingRect(contorno) + #print('Area:',area) + if area>2 and y1>120: + if area>red_area_max: + red_area_max=area + biggest_red=contorno + foundRed=True + + if len(green_contours[1])>=1: + + green_area_max=0 + #Find 2 biggest areas + biggest_green=None + for contorno in green_contours[1]: + #print('Contour len:',len(contorno)) + area=cv2.contourArea(contorno) + #print('Area:',area) + if area>20: + if area>green_area_max: + green_area_max=area + biggest_green=contorno + foundGreen=True + + + if foundRed: + x1,y1,dx1,dy1 = cv2.boundingRect(biggest_red) + #print(x1+dx1,y1+dy1) + cv2.rectangle(image2,(x1,y1),(x1+dx1,y1+dy1),(0,0,255),-1,8) + + if foundGreen: + x2,y2,dx2,dy2=cv2.boundingRect(biggest_green) + #print(x2+dx2,y2+dy2) + cv2.rectangle(image2,(x2,y2),(x2+dx2,y2+dy2),(0,255,0),-1,8) + + #cv2.waitKey(0) + if foundRed and foundGreen: + x=int((x1+x2)/2) + y=int((y1+y2)/2) + cv2.circle(image2,(x,y),10,(255,255,255),-1,8) + #cv2.imshow('image2',image2) + return foundRed,foundGreen,x,y,image2 + else: + if foundRed: + x=x1 + y=y1 + cv2.circle(image2,(x,y),10,(255,255,255),-1,8) + #cv2.imshow('image2',image2) + elif foundGreen: + x=x2 + y=y2 + cv2.circle(image2,(x,y),10,(255,255,255),-1,8) + #cv2.imshow('image2',image2) + return foundRed,foundGreen,x,y,image2 + + + + return False,False,0,0,image2 + +class Speed_Challenge: + + def get_entrance(self,image): + obstacles,centroid=dbscan_contours.get_obstacles(image,'rg',True,'A2') #Get a centroid of all red and green obstacles + x=int(centroid[0]*math.cos(centroid[1])) + y=int(centroid[0]*math.sin(centroid[1])) + return [centroid[0],centroid[1],(x,y)] #return distance, degrees and pixels for map image + + def get_blue_buoy(self,image): + obstacles,centroid=dbscan_contours.get_obstacles(image,'b',False,'A2') #Get a centroid of all red and green obstacles + x=int(centroid[0]*math.cos(centroid[1])) + y=int(centroid[0]*math.sin(centroid[1])) + return [centroid[0],centroid[1],(x,y)] #return distance, degrees and pixels for map image + +class Find_The_Path: + + def get_route_from_obstacles(self,boat_map): + mapa=cv2.cvtColor(boat_map, cv2.COLOR_BGR2GRAY) + contornos=cv2.findContours(array,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) + distance_matrix=np.zeros((len(contours),len(contours)),dtype=np.float32) + if len(contours)>1: + centroids=np.zeros((len(contours),2),dtype=np.uint32) + for i,contorno in enumerate(contours): + #agregar condicion de area aqui para filtrar muy pequenos? + M1 = cv2.moments(contorno) + if (M1['m00']==0): + M1['m00']=1 + cx1 = int(M1['m10']/M1['m00']) + cy1 = int(M1['m01']/M1['m00']) + centroids[i]=[cy1,cx1] + + distance_matrix=np.zeros((len(contours),len(contours)),dtype=np.float32) + #print centroids + for A in range(0,len(contours)): + for B in range(A+1,len(contours)): + + pointA=centroids[A] + pointB=centroids[B] + #print pointA, pointB + dist=spatial.distance.chebyshev(pointA, pointB) + distance_matrix[A][B]=dist + distance_matrix[B][A]=dist + + distance_matrix[A][A]=999 + + #print(distance_matrix) + + links=np.argwhere(distance_matrix1: + for contorno in contours[1]: + save=False + if save: + copy=np.full(image.shape,255,dtype=np.uint8) + epsilon = 0.1*cv2.arcLength(contorno,True) + approx = cv2.approxPolyDP(contorno,epsilon,True) + #print(len(approx)) + area=cv2.contourArea(contorno) + #print('area:',area) + value1=cv2.matchShapes(contorno, self.number1, 3, 0.0) + value2=cv2.matchShapes(contorno, self.number2, 3, 0.0) + value3=cv2.matchShapes(contorno, self.number3, 3, 0.0) + + + if area>100 and save: + cv2.drawContours(copy, contorno, -1, (0,0,255), 1) + #cv2.imshow('copy',copy) + tecla=cv2.waitKey(0) + if tecla==49: + np.save('one',contorno) + if tecla==50: + np.save('two',contorno) + if tecla==51: + np.save('three',contorno) + + #For method 1, <0.2 is really good + x,y,dx,dy=cv2.boundingRect(contorno) + y_threshold=250 + y_threshold2=320 #p #pixels + area_threshold=80 + cv2.line(copy,(0,y_threshold),(640,y_threshold),(255,0,0),1,8) + cv2.line(copy,(0,y_threshold2),(640,y_threshold2),(255,0,0),1,8) + if value1<0.1 and y>y_threshold and yarea_threshold: + print('Area',area) + x,y,dx,dy=cv2.boundingRect(contorno) + if (dx/dy)>0.5 and (dy/dx)<1.5: + if value1y_threshold and yarea_threshold: + print('Area',area) + x,y,dx,dy=cv2.boundingRect(contorno) + if (dx/dy)>0.5 and (dy/dx)<1.5: + if value2y_threshold and yarea_threshold: + print('Area',area) + x,y,dx,dy=cv2.boundingRect(contorno) + if (dx/dy)>0.5 and (dy/dx)<1.5: + if value31: + for contorno in contours[1]: + save=False + if save: + copy=np.full(image.shape,255,dtype=np.uint8) + epsilon = 0.1*cv2.arcLength(contorno,True) + approx = cv2.approxPolyDP(contorno,epsilon,True) + #print(len(approx)) + area=cv2.contourArea(contorno) + #print('area:',area) + value1=cv2.matchShapes(contorno, self.display1, 3, 0.0) + value2=cv2.matchShapes(contorno, self.display2, 3, 0.0) + value3=cv2.matchShapes(contorno, self.display3, 3, 0.0) + + + if save and area>100: + cv2.drawContours(copy, contorno, -1, (0,0,255), 1) + #cv2.imshow('copy',copy) + tecla=cv2.waitKey(0) + if tecla==49: + cv2.drawContours(copy, contorno, -1, (255,0,0), 1) + print('Saved 1') + np.save('display_one',contorno) + #cv2.imshow('numero 1',copy) + if tecla==50: + cv2.drawContours(copy, contorno, -1, (255,0,0), 1) + print('Saved 2') + np.save('display_two',contorno) + #cv2.imshow('numero 2', copy) + if tecla==51: + cv2.drawContours(copy, contorno, -1, (255,0,0), 1) + print('Saved 3') + np.save('display_three',contorno) + #cv2.imshow('numero 3',copy) + + #For method 1, <0.2 is really good + x,y,dx,dy=cv2.boundingRect(contorno) + y_threshold=0 + y_threshold2=480 #p #pixels + area_threshold=10 + #cv2.line(copy,(0,y_threshold),(640,y_threshold),(255,0,0),1,8) + #cv2.line(copy,(0,y_threshold2),(640,y_threshold2),(255,0,0),1,8) + + if value1<0.2 and area>150 and area<1000000: + print('one:',value1) + cv2.drawContours(copy, contorno, -1, (255,0,0), 1) + print('Area',area) + if value1150 and area<1000000: + print('two:',value2) + cv2.drawContours(copy, contorno, -1, (255,0,0), 1) + print('Area',area) + if value2150 and area<1000000: + print('three:',value3) + cv2.drawContours(copy, contorno, -1, (255,0,0), 1) + print('Area',area) + if value3 0): + data[0] = data[0][data[0].find('2') : ] + + print(data) + + set_challenge(data) + #Cast the values of the # values + t = int(data[timePos]) + la = float(data[latPos]) + lo = float(data[longPos]) + #Send the heart_beat with the current information + auvsi.send_http_heartbeat(currCourse,t,currChallenge,la,lo); + +def start_autnonmous(): + s = '123412341234123412341234123412341234123412341234123412' + global dock + global info2Boat + global currCourse + global data + global currChallenge + ###Read HeartBeat Untill End + select_course() + + #Init the process to wait for the autodocking position + wait_for_docking(); + print("Wait For Docking") + x.clean_buffer() + #Ask for the current challenge to submit to the server + set_challenge(data) + #Send the heart_beat with the current information + auvsi.send_http_heartbeat(currCourse,int(data[timePos]),currChallenge,float(data[latPos]),float(data[longPos])); + + + #Ask the dock from drone by BT + d = read_dock_from_drone() + print("read_dock_from_drone") + dock = d + + send_dock(); + print("send_dock") + + x.clean_buffer() + #Wait for the end of the run + wait_for_end(); + #bt.disconnect(); + +def read_dock_from_drone(): + #bt.beginMission() + # To Do: Image process Image + #img = cv2.imread("DronePhoto1.jpg"); + #cv2.imshow(img) + #dock_object=chall.Automated_Docking(img) + #dock_object.search_number() + return 2 + +#Get the challenge from the Heart_beat +def set_challenge(s): + #challPos = 3 + global currChallenge ; + global challPos + + #print("Set_Challenge: ", s , s[challPos]); + if s[challPos] == 's' or s[challPos] == 'S': + currChallenge = 'start' + elif s[challPos] == 'd' or s[challPos] == 'D': + currChallenge = 'docking'; + #print("Docking"); + if data[takePos] == '1': + print("Drone Taking Off"); + if data[flyingPos] == '1': + print("Drone Flying"); + if data[landPos] == '1': + print("Drone landing"); + elif s[challPos] == 'f' or s[challPos] == 'F': + currChallenge = 'follow'; + #print("Follow the leader"); + elif s[challPos] == 'r' or s[challPos] == 'R': + currChallenge = 'return'; + #print("Returning"); + elif s[challPos] == 'v' or s[challPos] == 'V': + currChallenge = 'speed'; + #print("Speed Challenge"); + elif s[challPos] == 'a' or s[challPos] == 'A': + currChallenge = 'speed'; + #print("Autonomous"); + elif s[challPos] == 'p' or s[challPos] == 'P': + currChallenge = 'path'; + #print("Path Planning"); + elif s[challPos] == 'n' or s[challPos] == 'N': + currChallenge = 'speed'; + #print("Between challenges"); + elif s[challPos] == 'e' or s[challPos] == 'E': + currChallenge = 'end'; + #print("END of communication"); + + + + +def read_heart_beat(): + s = '123412341234123412341234123412341234123412341234123412' + ###Read HeartBeat Untill End + select_course() + global currChallenge + + while s[challPos] != 'e': + s = x.receive_from_boat(); + data = s.split(','); + if s[challPos] == 's' or s[challPos] == 'S': + print("Starting"); + print(data) + #Send first target point to the boat + #Report to http sever + elif s[challPos] == 'd' or s[challPos] == 'D': + currChallenge = 'dock'; + print("Docking"); + if data[takePos] == '1': + print("Drone Taking Off"); + if data[flyingPos] == '1': + print("Drone Flying"); + if data[landPos] == '1': + print("Drone landing"); + elif s[challPos] == 'f' or s[challPos] == 'F': + currChallenge = 'follow'; + print("Follow the leader"); + elif s[challPos] == 'r' or s[challPos] == 'R': + currChallenge = 'return'; + print("Returning"); + elif s[challPos] == 'v' or s[challPos] == 'V': + currChallenge = 'speed'; + print("Speed Challenge"); + elif s[challPos] == 'r' or s[challPos] == 'R': + currChallenge = 'return'; + print("Returning home"); + elif s[challPos] == 'p' or s[challPos] == 'P': + currChallenge = 'path'; + print("Path Planning"); + elif s[challPos] == 'n' or s[challPos] == 'N': + currChallenge = 'speed'; + print("Transition"); + + + print("Boat ended") + +def testing3(): + send_dock(); + +def send_return_data(): + global status + while True: + x.send2boat(info2Boat); + time.sleep(1.05) + +if __name__ == '__main__': + start_autnonmous() + #testing3() diff --git a/test.jpg b/test.jpg new file mode 100644 index 0000000..178674c Binary files /dev/null and b/test.jpg differ diff --git a/three.npy b/three.npy new file mode 100644 index 0000000..3f0af06 Binary files /dev/null and b/three.npy differ diff --git a/two.npy b/two.npy new file mode 100644 index 0000000..446f286 Binary files /dev/null and b/two.npy differ diff --git a/variables.py b/variables.py new file mode 100644 index 0000000..c0010cc --- /dev/null +++ b/variables.py @@ -0,0 +1,77 @@ +import os +import sys +import serial +import serial.tools.list_ports as ports + +previousRightMotorValue = 0; +previousLeftMotorValue = 0; + +baudRateArduino = 115200 +baudRateIMU = 115200 +baudRateRPLidar = 115200 + +lidarPort = '' +imuPort = '' +arduinoPort = '' +arduinoUnoPort = '' +arduinoMega = '' + +servoLeft = 'l' +servoRight = 'r' +servoBoth = 'b' +servoMoveLeft = 180 +servoMoveRight = 0 +servoMoveInitP = 90 + +thrusterLeft = 'l' +thrusterRight = 'r' +thrustersBack = 'b' +thrustersFront = 'f' +thrustersAll = 'a' +thrusterMoveFront = 1650 #Min 1500 Max 1900 +thrusterMoveBack = 1350 #Min 1499 Max 1100 +thrusterMoveInitP = 1500 + +##Motors Information +numberOfMotors = 2 +numberOfBatteries = 2 + +maxSpeed = 9.8 + +boatWeight = 25 #Kg + +currChallenge = 'N' + +pts = list(ports.comports()); + +if not pts: + print ('Theres no connected sensors') +else: + for p in pts : + print(p, p[1]) + if (p[1].find('ACM') == 3): + arduinoUnoPort = p[0] + elif (p[1].find('Serial') == 7): + arduinoPort = p[0] + elif (p[1].find('3-3') == 0 or p[1].find('3-4') == 0 or p[1].find('Silicon Labs CP2102 USB to UART') == 0 or p[1].find('CP2102') == 0 ): + lidarPort = p[0]; + elif (p[1].find('USB-RS232') == 0) : + imuPort = p[0]; + elif (p[1].find('USB2.0-Serial') == 0) : + ardionoMega = p[0]; + + +#ser = serial.Serial('/dev/ttyACM1', baudRateArduino); + +#ser = serial.Serial('/dev/ttyACM0', baudRateArduino); + +''' +if(arduinoMega != ''): + ser = serial.Serial(arduinoMega, baudRateArduino ) + +elif(arduinoPort != ''): + ser = serial.Serial(arduinoUnoPort, baudRateArduino) + +elif(arduinoUnoPort != ''): + ser = serial.Serial(arduinoPort, baudRateArduino) +''' diff --git a/xbee.py b/xbee.py new file mode 100644 index 0000000..9ed7f03 --- /dev/null +++ b/xbee.py @@ -0,0 +1,79 @@ +import datetime +import serial +import time + +leidoAnterior = "" + +class xbee: + def __init__(self,USB): + self.connection=serial.Serial(USB,9600) + self.timestamp='' + self.challenge='0' + self.latitude= 'HDDD.DDDDDD' + self.longitude='HDDD.DDDDDD' + self.takeoff='0' + self.flying='0' + self.landing = '0' + + def set_challenge(self,chal='N'): + self.challenge = chal + + def set_latlong(self,latitude,longitude): + self.latitude=latitude + self.longitude=longitude + + def set_takeoff(self,take): + self.takeoff=take + + def set_flying(self, fly): + self.flying=fly + + def set_landing(self, land): + self.landing=land + + def send2station(self): + date=str(datetime.datetime.now()) + #print(date) + fecha=date.split('-') + dia=fecha[2].split(' ')[0] + horas=fecha[2].split(' ')[1].split(':') + self.timestamp=(fecha[0]+fecha[1]+dia+horas[0]+horas[1]+horas[2][:2]).zfill(14) + string=self.timestamp+','+self.latitude+','+self.longitude+','+self.challenge+','+self.takeoff+','+self.flying+','+self.landing+','+'%' + print(string) + self.connection.write(bytes(string, encoding='utf-8')) + + def send2boat(self,data): + transmit = data[0] + R_kill_switch = data[1] + status = data[2] + course = data[3] + challenge = data[4] + dock = data[5] + string=','+str(transmit)+','+str(R_kill_switch)+','+str(status)+','+str(course)+','+str(challenge)+','+str(dock)+','+'%' + print(string) + self.connection.write(bytes(string, encoding='utf-8')) + + def receive_from_station(self): + leido=self.connection.read(17).decode("utf-8") + self.connection.flush() + time.sleep(.1) + data = leido.split(','); + data = data[1 :] + data = data[: 6] + return data + + #29.151098, -81.016505 + def receive_from_boat(self): + + #self.connection.flush() + #self.connection.reset_input_buffer() + #time.sleep(.1) + #print("After connection") + leido=self.connection.readline(48).decode("utf-8") + #print("Before Connection") + print(leido) + return leido; + + def clean_buffer(self): + self.connection.flush() +