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