Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
-Enabled async exiting. Exit messages are all sent before waiting to join.
-General bug fixes and improvements.
-General system stability test passed. 4 Drones, 1 Client, 1 Monitor. 
    - Note: ~8% CPU usage on RPi3 : 4 Drones at 10X speed simulation, printing,connecting. 1 Server with printing.
  • Loading branch information
Scratchcat1 authored Oct 3, 2017
1 parent ae59728 commit b9096dd
Show file tree
Hide file tree
Showing 7 changed files with 553 additions and 214 deletions.
2 changes: 1 addition & 1 deletion AATC_Crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,4 @@ def Recv(self):
return data
#return data[0],data[1],data[2]
except Exception as e:
print(e)
print("Error in Cryptor while receiving ",e)
3 changes: 3 additions & 0 deletions AATC_DB.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,14 +294,17 @@ def MonitorCheckCredentials(self,MonitorName,MonitorPassword):

def GetMonitorDrones(self,MonitorID):
self.cur.execute("SELECT Drone.* FROM Drone,MonitorPermission WHERE Drone.UserID = MonitorPermission.UserID and MonitorPermission.MonitorID = %s",(MonitorID,))
self.db_con.commit()
return True,str(self.Table_Headers("Drone")),self.cur.fetchall()

def GetMonitorFlights(self,MonitorID):
self.cur.execute("SELECT Flight.* FROM Flight,Drone,MonitorPermission WHERE Flight.DroneID = Drone.DroneID AND Drone.UserID = MonitorPermission.UserID and MonitorPermission.MonitorID = %s",(MonitorID,))
self.db_con.commit()
return True,str(self.Table_Headers("Flight")),self.cur.fetchall()

def GetMonitorFlightWaypoints(self,MonitorID):
self.cur.execute("SELECT FlightWaypoints.* FROM FlightWaypoints,Flight,Drone,MonitorPermission WHERE FlightWaypoints.FlightID = Flight.FlightID AND Flight.DroneID = Drone.DroneID AND Drone.UserID = MonitorPermission.UserID and MonitorPermission.MonitorID = %s",(MonitorID,))
self.db_con.commit()
return True,str(self.Table_Headers("FlightWaypoints")),self.cur.fetchall()

def GetMonitorID(self,MonitorName):
Expand Down
135 changes: 79 additions & 56 deletions AATC_GPIO.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,35 @@
##GPIO.setup(21, GPIO.OUT) #green
##GPIO.setup(26, GPIO.IN) #button

def GPIO_Thread(Thread_Name,GPIO_Queue):
Exit = False
Function = BlankFunction
FuncArgs = ()
while not Exit:
try:
FuncReset = Function(Thread_Name,*FuncArgs) #calls the function passed to the thread

if FuncReset:
Function,FuncArgs = BlankFunction,() #Resets commands. Allows function to exit itself.

if not GPIO_Queue.empty():
Data = GPIO_Queue.get()
#GPIO_Queue.task_done()
Command,Arguments = Data[0],Data[1]

if Command == "Function":
Function, FuncArgs = Arguments[0],Arguments[1]
elif Command == "Exit":
Exit = True

except Exception as e:
print("Error occured in GPIO_Thread",Thread_Name,".",str(e))
Function,FuncArgs = BlankFunction,() #Resets commands to prevent large prints





class Thread_Handle:
def __init__(self,Thread_Name,ThreadPointer,Queue):
self.Thread_Name = Thread_Name
Expand All @@ -23,31 +52,36 @@ def Get_ThreadPointer(self):
def Get_Queue(self):
return self.Queue

class GPIO_Thread_Controller:
def __init__(self,Command_Queue):
print("Creating Thread Controller")




class Thread_Controller:
def __init__(self,Command_Queue,Name = ""):
print("Creating Thread Controller",Name)
self.Name ="TC"+ Name + " >"
self.Command_Queue = Command_Queue
self.Threads = {}

def Create_Thread(self,Thread_Name,Process = False): #If Process is True, will use a Process rather than a thread.
def Create_Thread(self,Thread_Name,TargetCommand = GPIO_Thread,TargetArgs = (),Process = False): #If Process is True, will use a Process rather than a thread.
if Thread_Name in self.Threads: #Close thread if already exists
self.Close_Thread(Thread_Name)

if Process:
Thread_Queue = multiprocessing.Queue()
threadPointer = multiprocessing.Process(target = GPIO_Thread,args = (Thread_Name,Thread_Queue))
threadPointer = multiprocessing.Process(target = TargetCommand,args = (Thread_Name,Thread_Queue)+TargetArgs)
else:
Thread_Queue = queue.Queue()
threadPointer = threading.Thread(target = GPIO_Thread,args = (Thread_Name,Thread_Queue))
threadPointer = threading.Thread(target = TargetCommand,args = (Thread_Name,Thread_Queue)+TargetArgs)
self.Threads[Thread_Name] = Thread_Handle(Thread_Name,threadPointer,Thread_Queue)
threadPointer.start()
print(self.Threads)

def Close_Thread(self,Thread_Name):
Thread = self.Threads.pop(Thread_Name)
Queue = Thread.Get_Queue()
ClosingThreadHandle = self.Threads.pop(Thread_Name)
Queue = ClosingThreadHandle.Get_Queue()
Queue.put(("Exit",()))
print("GPIO Controller closed Thread",Thread_Name)
print(self.Name,"GPIO Controller closed Thread",Thread_Name)
return ClosingThreadHandle #Returns Thread_Handle of thread


def PassData(self,Thread_Name,Data):
Expand All @@ -57,79 +91,68 @@ def PassData(self,Thread_Name,Data):
def Main(self):
Exit = False
while not Exit:
## try:
try:
Request = self.Command_Queue.get() #(Thread_Name/Controller command,"Command",Args)
self.Command_Queue.task_done()

if Request[0] == "Controller":
Command,Args = Request[1],Request[2]
if Command == "Create_Thread":
if Command == "Create_Thread": #In total form ("Controller","Create_Thread",(ThreadName,[TargetFunction,TargetArguments]))
self.Create_Thread(*Args)
elif Command == "Create_Process":
self.Create_Thread(*Args, Process = True)
elif Command == "Close_Thread":
self.Close_Thread(*Args)
elif Command == "Exit":
elif Command == "Exit": #Shutdown everything
self.Reset(*Args)
self.Exit = True
elif Command == "Reset":
self.Reset()
elif Command == "Reset": #Shutdown all threads, not controller
self.Reset(*Args)

else:
self.PassData(Request[0],(Request[1],Request[2]))




except Exception as e:
print(self.Name,"Error in GPIO_Thread_Controller",e)
print(self.Name,"Shutting down")

## except Exception as e:
## print("Error in GPIO_Thread_Controller",e)


def Reset(self):
print("Reseting GPIO Threading Controller...")
def Reset(self,Wait_Join = False):
print(self.Name,"Reseting GPIO Threading Controller...")
Thread_Names = list(self.Threads.keys())
ThreadHandles = []
for Thread_Name in Thread_Names:
self.Close_Thread(Thread_Name)
print("Reset GPIO Threading Controller")







def GPIO_Thread(Thread_Name,GPIO_Queue):
Exit = False
Function = BlankFunction
FuncArgs = ()
while not Exit:
try:
FuncReset = Function(Thread_Name,*FuncArgs) #calls the function passed to the thread
ClosingThreadHandle = self.Close_Thread(Thread_Name)
ThreadHandles.append(ClosingThreadHandle)

if FuncReset:
Function,FuncArgs = BlankFunction,() #Resets commands. Allows function to exit itself.
if Wait_Join: #In seperate loop to asyncrously call 'Exit'
for ThreadHandle in ThreadHandles:
ThreadPointer = ThreadHandle.Get_ThreadPointer()
ThreadPointer.join()

if not GPIO_Queue.empty():
Data = GPIO_Queue.get()
#GPIO_Queue.task_done()
Command,Arguments = Data[0],Data[1]

if Command == "Function":
Function, FuncArgs = Arguments[0],Arguments[1]
elif Command == "Exit":
Exit = True
print(self.Name,"Reset GPIO Threading Controller")

except Exception as e:
print("Error occured in GPIO_Thread",Thread_Name,".",str(e))
Function,FuncArgs = BlankFunction,() #Resets commands to prevent large prints








def Create_Controller():
q = queue.Queue()
g = GPIO_Thread_Controller(q)
t = threading.Thread(target = g.Main)
def Create_Controller(process = False):
if process:
q = multiprocessing.Queue()
else:
q = queue.Queue()

TC = Thread_Controller(q)

if process:
t = multiprocessing.Process(target = TC.Main)
else:
t = threading.Thread(target = TC.Main)
t.start()
return q

Expand Down
58 changes: 29 additions & 29 deletions AATC_Monitor_Viewer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pygame,AATC_Monitor,time,ast,sys
import pygame,AATC_Monitor,time,ast,sys,random
from AATC_Coordinate import *
pygame.init()

Expand All @@ -9,18 +9,32 @@ def GetImage(xSize,ySize,Colour): #Efficiently get images
result = pygame.Surface((xSize,ySize)).convert()
result.fill(Colour)
_images[(xSize,ySize,Colour)]=result
## result_copy = pygame.Surface(result.get_size())
## result_copy.blit(result,(0,0))
while len(_images) > 1500:
_images.pop(random.sample(_images.keys(),1)[0]) #If cache is full evict old versions
return result#_copy

_texts= {}
def GetText(Text,font,AA,Colour): #Efficiently get text
result = _texts.get((Text,font,AA,Colour))
def GetText(Text,fontParameters,AA,Colour): #Efficiently get text
result = _texts.get((Text,fontParameters,AA,Colour))
if result == None:
result = font.render(Text,AA,Colour)
_images[(Text,font,AA,Colour)]=result
result = GetFont(*fontParameters).render(Text,AA,Colour)
_texts[(Text,fontParameters,AA,Colour)]=result
while len(_texts) > 1500:
_texts.pop(random.sample(_texts.keys(),1)[0]) #If cache is full evict old versions
return result


_fonts = {}
def GetFont(Font,Size):
result = _fonts.get((Font,Size))
if result == None:
result = pygame.font.Font(Font,Size)
_fonts[(Font,Size)]=result
while len(_fonts) > 1500:
_fonts.pop(random.sample(_fonts.keys(),1)[0]) #If cache is full evict old versions
return result


def MaxLimit(value,Max):
if value > Max:
value = Max
Expand Down Expand Up @@ -81,14 +95,14 @@ def Draw(self):
PosY = ((Object.Coords.y- self.CameraCoord.y)/self.CameraCoord.ySize)* self.ypixel
## width,height = Object.Coords.xSize*self.CameraZoom ,Object.Coords.ySize*self.CameraZoom
width,height = int(Object.Coords.xSize/self.CameraCoord.xSize*self.xpixel) ,int(Object.Coords.ySize/self.CameraCoord.ySize*self.ypixel)
if width > 0 or height > 0:
if width > 0 and height > 0:
width = MaxLimit(width,self.xpixel)
height = MaxLimit(height,self.ypixel)
font_size = int(100*width/self.xpixel)
Object.Make_Image(width,height) # Object has coordinates and size in these coordinates
self.gameDisplay.blit(Object.image,(PosX,PosY))
if font_size > 5:
font = pygame.font.Font(None, font_size) #TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS
font = (None, font_size) #TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS
Object.Make_CoordsText(font) #TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS
Object.Make_Text(font) #TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS
Object.Make_Type(font) #TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS#TEST THIS
Expand Down Expand Up @@ -240,8 +254,8 @@ def MakeSprites(M):



xpixel = 1000
ypixel = 500
xpixel = 1200
ypixel = 700
Refresh_Delay = 60
clock = pygame.time.Clock()
pressed = pygame.key.get_pressed
Expand All @@ -257,11 +271,11 @@ def MakeSprites(M):
while True:
MonCamera.ResetDrawObject()
Sprites = MakeSprites(M)
font = pygame.font.Font(None, 30)
#font = (None, 30)
for sprite in Sprites:
sprite.Make_CoordsText(font)
sprite.Make_Text(font)
sprite.Make_Type(font)
#sprite.Make_CoordsText(font)
#sprite.Make_Text(font)
#sprite.Make_Type(font)
MonCamera.AddDrawObject(sprite,False)

Last_Refresh_Time = time.time()
Expand All @@ -276,20 +290,6 @@ def MakeSprites(M):
print("Monitor exit was called")
pygame.quit()
sys.exit()

## elif event.type == pygame.KEYDOWN and event.key == pygame.K_w: #Shift camera
## MonCamera.IncrementCameraCoordY(-0.5/MonCamera.GetZoom()) #/ as Greater zoom means need more fidelety
## elif event.type == pygame.KEYDOWN and event.key == pygame.K_s:
## MonCamera.IncrementCameraCoordY(0.5/MonCamera.GetZoom())
## elif event.type == pygame.KEYDOWN and event.key == pygame.K_a:
## MonCamera.IncrementCameraCoordX(-0.5/MonCamera.GetZoom())
## elif event.type == pygame.KEYDOWN and event.key == pygame.K_d:
## MonCamera.IncrementCameraCoordX(0.5/MonCamera.GetZoom())

## elif event.type == pygame.KEYDOWN and event.key == pygame.K_q:#Zoom out
## MonCamera.SetZoom(0.9*MonCamera.GetZoom())
## elif event.type == pygame.KEYDOWN and event.key == pygame.K_e:#Zoom in
## MonCamera.SetZoom(1.1*MonCamera.GetZoom())

elif event.type == pygame.MOUSEBUTTONDOWN:
print("Camera details")
Expand Down
14 changes: 11 additions & 3 deletions AATC_NoFlyZoneGrapher.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ class NoFlyZoneGrapher:
Could use an A/B method to update if file locking occurs where the Updating takes place on one set of data while the other set of data is read from by eg A* pathfinding
"""
def __init__(self,KillSwitch,Interval = 36000):
def __init__(self,Thread_Name,Thread_Queue,Interval = 36000):
self.DB = AATC_DB.DBConnection()
self.Interval = Interval
self.KillSwitch = KillSwitch
self.Thread_Name = Thread_Name
self.Thread_Queue = Thread_Queue

graph = AATC_AStar.DynoGraph()
graph.ImportGraph()
Expand All @@ -26,14 +27,21 @@ def __init__(self,KillSwitch,Interval = 36000):
self.Main_Loop()

def Main_Loop(self):
while not self.KillSwitch.is_set():
self.Exit = False
while not self.Exit:
try:
NoFlyZoneData = self.GetNoFlyZones()
self.Make_Values(NoFlyZoneData)
except Exception as e:
print("Error occured in NoFlyZoneGrapher",e)
print("NoFlyZoneGrapher completed. Sleeping...")
time.sleep(self.Interval)

if not self.Thread_Queue.empty():
data = self.Thread_Queue.get()
Command,Arguments = data[0],data[1]
if Command == "Exit":
self.Exit = True

def Mod(self,Coords):
return int(Coords.x//self.xSize),int(Coords.y//self.ySize),int(Coords.z//self.zSize)
Expand Down
Loading

0 comments on commit b9096dd

Please sign in to comment.