forked from Matioupi/realtime-adsb-out
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AbstractTrajectorySimulatorBase.py
97 lines (77 loc) · 5.15 KB
/
AbstractTrajectorySimulatorBase.py
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
""" Abstract base class for a trajectory simulation
This class provides basic services that will generate and feed broadcasting
thread with appropriate messages.
2 abstract methods need to be overriden in derived classes :
- refresh_delay which should return the simulation timestep in seconds
- update_aircraftinfos which is reponsible for animating the aircraftinfos
object at each time step, thus making the simulation "alive"
mutex protection occurs when calling replace_message
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
"""
import time
import abc
import threading
from ModeS import ModeS
class AbstractTrajectorySimulatorBase(threading.Thread,abc.ABC):
def __init__(self,mutex,broadcast_thread,aircraftinfos):
super().__init__()
self._mutex = mutex
self._broadcast_thread = broadcast_thread
self._aircraftinfos = aircraftinfos
self._modeSencoder = ModeS(df=17,icao=self._aircraftinfos.icao,ca=self._aircraftinfos.capability)
self._do_stop = False
# Thread core function
def run(self):
is_first_step = True
while not self._do_stop:
encoder_changed = False
# check if modeS encoder needs update
if self._aircraftinfos.icao_changed or self._aircraftinfos.capability_changed or is_first_step:
self._modeSencoder.icao = self._aircraftinfos.icao
self._modeSencoder.ca = self._aircraftinfos.capability
encoder_changed = True
if encoder_changed or self._aircraftinfos.callsign_changed:
self.df_callsign = self._modeSencoder.callsign_encode(self._aircraftinfos.callsign)
self._broadcast_thread.replace_message("identification",self.df_callsign)
if encoder_changed or self._aircraftinfos.squawk_changed:
self.frame_6116 = self._modeSencoder.modaA_encode(self._aircraftinfos.squawk)
self._broadcast_thread.replace_message("register_6116",self.frame_6116)
# message generation only if needed
if encoder_changed or self._aircraftinfos.on_surface_changed \
or self._aircraftinfos.lat_changed or self._aircraftinfos.lon_changed or self._aircraftinfos.alt_msl_changed \
or self._aircraftinfos.type_code_changed or self._aircraftinfos.surveillance_status_changed or self._aircraftinfos.nicsupb_changed \
or self._aircraftinfos.timesync_changed:
if not self._aircraftinfos.on_surface:
(self.df_pos_even, self.df_pos_odd) = self._modeSencoder.df_encode_airborne_position(self._aircraftinfos.lat_deg, self._aircraftinfos.lon_deg, self._aircraftinfos.alt_msl_ft, \
self._aircraftinfos.type_code, self._aircraftinfos.surveillance_status, self._aircraftinfos.nicsupb, self._aircraftinfos.timesync)
self._broadcast_thread.replace_message("airborne_position",self.df_pos_even,self.df_pos_odd)
self._broadcast_thread.replace_message("surface_position",[], [])
else:
(self.df_pos_even, self.df_pos_odd) = self._modeSencoder.df_encode_surface_position(self._aircraftinfos.lat_deg, self._aircraftinfos.lon_deg, self._aircraftinfos.alt_msl_ft, \
self._aircraftinfos.type_code, self._aircraftinfos.surveillance_status, self._aircraftinfos.nicsupb, self._aircraftinfos.timesync)
self._broadcast_thread.replace_message("surface_position",self.df_pos_even,self.df_pos_odd)
self._broadcast_thread.replace_message("airborne_position",[], [])
if encoder_changed or self._aircraftinfos.speed_changed or self._aircraftinfos.track_angle_changed or self._aircraftinfos.vspeed_changed:
self.df_velocity = self._modeSencoder.df_encode_ground_velocity(self._aircraftinfos.speed_kt, self._aircraftinfos.track_angle_deg, self._aircraftinfos.vspeed_ftpmin)
self._broadcast_thread.replace_message("airborne_velocity",self.df_velocity)
is_first_step = False
self.update_aircraftinfos() # update_aircraftinfos() : abstract method that need to be implemented i nderived classes
time.sleep(self.refresh_delay()) # refresh_delay() : abstract method that need to be implemented i nderived classes
# upon exit, reset _do_stop flag in case there is a new start
self._do_stop = False
def stop(self):
self._do_stop = True
@abc.abstractmethod
def refresh_delay(self):
...
@abc.abstractmethod
def update_aircraftinfos(self):
...