Source code for DroneProject.VirtualDrone

# -*- coding: UTF-8 -*-


#Name:        James Hall
#Student No.: C00007006
#Institute:   Institute of Technology Carlow
#Project:     Drone Traffic Control System     
#Date:        April 2021 
#License:     GNU Affero General Public License v3.0


import math
import time
import threading
from geographiclib.geodesic import Geodesic
from threading import Thread
from AbstractDrone import AbstractDrone


battery_drain = .055

[docs]class VirtualDrone(AbstractDrone): """ Virtual Drone class """ def __init__(self, drone_id, dronetype, home_latitude, home_longitude, destination_latitude, destination_longitude, altitude, battery, speed, flying_state, heading): self.home_latitude = home_latitude self.home_longitude = home_longitude self.current_latitude = home_latitude self.current_longitude = home_longitude self.destination_latitude = destination_latitude self.destination_longitude = destination_longitude self.altitude = altitude self.battery = battery self.speed = speed self.flying_state = flying_state self.drone_id = drone_id self.drone_type = dronetype self.heading = heading
[docs] def takeoff(self): self.altitude = 2 self.flying_state = "Hovering"
[docs] def hover(self): self.flying_state = "Hovering"
[docs] def moveto(self, longitude, latitude, altitude, spe): self.altitude = altitude self.destination_latitude = latitude self.destination_longitude = longitude self.speed = spe self.createvector()#better name? self.updatecurrentposition() self.flying_state = "MovingTo" self.setbatteryinflight()
[docs] def changealtitude(self, alt): self.altitude = alt
#self.flying_state = "Changing Altitude"
[docs] def land(self): self.altitude = 0 self.flying_state = "Grounded"
[docs] def getgpsposition(self): name = self.drone_id lat = float(self.current_latitude) lon = float(self.current_longitude) alt = self.altitude return name, lat, lon, alt
[docs] def getaltitude(self): return self.altitude
[docs] def setdronestate(self, state): self.flying_state = state
[docs] def getdronestate(self): flystate = self.flying_state return flystate
#Set/Get Battery
[docs] def setbatteryinflight(self): global battery_drain # .055 is estimated drain on battery in flight per second as a % self.battery = (self.battery - battery_drain)
[docs] def setbatterytotal(self, percent): self.battery = percent
[docs] def setbatterychange(self, percent): self.battery = self.battery - percent
[docs] def getbattery(self): return self.battery
#Set/Get home lat and lon
[docs] def sethomelatitude(self,lat): self.home_latitude = lat
[docs] def gethomelatitude(self): return self.home_latitude
[docs] def sethomelongitude(self,lon): self.home_longitude = lon
[docs] def gethomelongitude(self): return self.home_longitude
#Set/Get destination lat and lon
[docs] def setdestinationlatitude(self,lat): self.destination_latitude = lat
[docs] def getdestinationlatitude(self): return self.destination_latitude
[docs] def setdestinationlongitude(self,lon): self.destination_longitude = lon
[docs] def getdestinationlongitude(self): return self.destination_longitude
#Set/Get current lat and lon
[docs] def setcurrentlatitude(self,lat): self.current_latitude = lat
[docs] def getcurrentlatitude(self): return float(self.current_latitude)
[docs] def setcurrentlongitude(self,lon): self.current_longitude = lon
[docs] def getcurrentlongitude(self): return float(self.current_longitude)
[docs] def getdistancetodestination(self): #Get travel distance from point to point #Formula adopted from top answer and source of answer: #https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula #http://www.movable-type.co.uk/scripts/latlong.html radius = 6371 #Radius in km of Earth deg_latitude = math.radians(self.destination_latitude -float(self.current_latitude)) deg_longitude = math.radians(self.destination_longitude -float(self.current_longitude)) #a = Square of half the chord length between two points a = math.sin(deg_latitude/2) * math.sin(deg_latitude/2) + math.cos(math.radians(self.current_latitude)) * math.cos(math.radians(self.destination_latitude)) * math.sin(deg_longitude/2) * math.sin(deg_longitude/2) #c = Angular distance in radians c = 2 * math.atan2(math.sqrt(a),math.sqrt(1-a)) d = radius * c return d
[docs] def getdistancetoposition(self,poslat,poslon): #Get travel distance from point to point #Formula adopted from top answer and source of answer: #https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula #http://www.movable-type.co.uk/scripts/latlong.html radius = 6371 #Average Radius in km of Earth deg_latitude = math.radians(poslat - float(self.current_latitude)) deg_longitude = math.radians(poslon - float(self.current_longitude)) #a = Square of half the chord length between two points a = math.sin(deg_latitude/2) * math.sin(deg_latitude/2) + math.cos(math.radians(float(self.current_latitude))) * math.cos(math.radians(float(self.destination_latitude))) * math.sin(deg_longitude/2) * math.sin(deg_longitude/2) #c = Angular distance in radians c = 2 * math.atan2(math.sqrt(a),math.sqrt(1-a)) d = radius * c return d
[docs] def createvector(self): self.vectorlat = float(self.destination_latitude) -float(self.current_latitude) self.vectorlon = float(self.destination_longitude) -float(self.current_longitude) return self.vectorlat, self.vectorlon
[docs] def getvectorlatitude(self): vectorlat = float(self.destination_latitude) - self.home_latitude return vectorlat
[docs] def getvectorlongitude(self): vectorlon = float(self.destination_longitude )- self.home_longitude return vectorlon
[docs] def updatecurrentposition(self): direction_length = math.sqrt(math.pow(self.getvectorlatitude(),2) + math.pow(self.getvectorlongitude(),2)) normalised_vector_lat = self.getvectorlatitude() / direction_length normalised_vector_lon = self.getvectorlongitude() / direction_length self.current_latitude=float(self.current_latitude)+ (normalised_vector_lat*(self.speed*1)) self.current_longitude =float(self.current_longitude) + (normalised_vector_lon*(self.speed*1))
[docs] def getbearing(self, startlat, startlong, destlat, destlong): heading = Geodesic.WGS84.Inverse(startlat,startlong, destlat, destlong)["azi1"] return heading
[docs] def getdronetype(self): return self.drone_type
[docs] def setdronetype(self, dronetype): self.drone_type = dronetype