summaryrefslogtreecommitdiff
path: root/dashboard_website/datastructs.py
blob: 0171d8fa53c13f80a288a9c9d9096c5bbd87943f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import math
import time

# time since last ping before deactivating/deleting
BIKE_TIMEOUT = 60000 # 3 minutes
BIKE_DELETE = 360000 # time before bike deletes itself

# data structures
class Point:
    def __init__(self, lat, long):
        self.longitude = long
        self.latitude = lat
    
    def toJSON(self):
        json_dict = {'longitude' : self.longitude,
                     'latitude' : self.latitude}
        return json_dict
    
    def setCoords(self, lat, long):
        self.longitude = long
        self.latitude = lat

    def move(self, d_lat, d_long):
        self.longitude += d_long
        self.latitude += d_lat

    def __str__(self):
        return f"{self.longitude},{self.latitude}"
    
    def __repr__(self):
        return f"{self.longitude},{self.latitude}"
    
    def distanceTo(self, pt): # distance between points in miles
        lat1 = self.latitude; lon1 = self.longitude;
        lat2 = pt.latitude; lon2 = pt.longitude;
        R = 3958.8 # Radius of the earth 
        lat_d = math.radians(lat2-lat1); 
        lon_d = math.radians(lon2-lon1); 
        a = math.sin(lat_d/2) * math.sin(lat_d/2) + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(lon_d/2) * math.sin(lon_d/2)  
        c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a)); 
        d = R * c; # Distance in mi
        return d


class Clue(Point):
    def __init__(self, lat, long, name, info, status):
        self.longitude = long
        self.latitude = lat
        self.name = name
        self.info = info
        self.status = status # UNVISITED | ASSIGNED | VISITED 
    
    def visit(self):
        self.status = "VISITED"

    def toJSON(self):
        json_dict = {'longitude' : self.longitude,
                     'latitude' : self.latitude,
                     'clue_name' : self.name.replace('"', "'"),
                     'clue_info' : self.info.replace('"', "'"),
                     'clue_status' : self.status}
        return json_dict

class Bike(Point):
    def __init__(self, lat, long, name, status):
        self.longitude = long
        self.latitude = lat
        self.name = name
        self.last_contact = time.time()
        self.target_name = "N/A"
        self.cluster = [] # list of clues this bike team is responsible for
        self.status = status # ACTIVE | INACTIVE
    
    def setTarget(self, clue_name):
        self.target_name = clue_name
    
    def setCluster(self, clue_cluster):
        self.cluster = clue_cluster
        self.updateTarget()
    
    def updateTarget(self):
        if len(self.cluster) <= 0:
            self.target_name = "N/A"
        else:
            self.target_name = self.cluster[0].name
    
    def visitTarget(self):
        self.cluster[0].visit()
        self.cluster.pop(0)
        self.updateTarget()
        while len(self.cluster) > 0 and self.cluster[0].status == "VISITED":
            self.cluster.pop(0) # skip next node if it has been somehow visited
            self.updateTarget()


    def ping(self):
        self.status = "ACTIVE"
        self.last_contact = time.time()
    
    def disable(self):
        self.status = "INACTIVE"
        self.target = "N/A"
        self.last_contact = 0

    def checkStatus(self):
        if time.time() - self.last_contact > BIKE_TIMEOUT:
            self.status = "INACTIVE"
            self.target = "N/A"
            if time.time() - self.last_contact > BIKE_DELETE:
                return -1
        return 0

    def toJSON(self):
        json_dict = {'longitude' : self.longitude,
                     'latitude' : self.latitude,
                     'time_since_last_contact' : time.time()-self.last_contact,
                     'team_name' : self.name,
                     'team_status' : self.status,
                     'target_clue' : self.target_name}
        return json_dict