source: src/mlx/flight.py@ 176:cb593ff93551

Last change on this file since 176:cb593ff93551 was 176:cb593ff93551, checked in by István Váradi <ivaradi@…>, 12 years ago

Checklist playback seems to work

File size: 7.7 KB
Line 
1# Module related to the high-level tracking of the flight
2
3#---------------------------------------------------------------------------------------
4
5from soundsched import SoundScheduler, ChecklistScheduler
6
7import const
8import util
9
10import threading
11
12#---------------------------------------------------------------------------------------
13
14class Options(object):
15 """Various configuration options."""
16 def __init__(self):
17 """Construct the object with default values."""
18 self.fs2Crew = False
19 self.compensation = None
20
21#---------------------------------------------------------------------------------------
22
23class Flight(object):
24 """The object with the global flight state.
25
26 It is also the hub for the other main objects participating in the handling of
27 the flight."""
28 def __init__(self, logger, gui):
29 """Construct the flight."""
30 self._stage = None
31 self.logger = logger
32 self._gui = gui
33
34 gui.resetFlightStatus()
35
36 self._pilotHotkeyPressed = False
37 self._checklistHotkeyPressed = False
38
39 self.flareTimeFromFS = False
40 self.entranceExam = False
41
42 self.options = Options()
43
44 self.aircraftType = None
45 self.aircraft = None
46 self.simulator = None
47
48 self.blockTimeStart = None
49 self.flightTimeStart = None
50 self.flightTimeEnd = None
51 self.blockTimeEnd = None
52
53 self._lastDistanceTime = None
54 self._previousLatitude = None
55 self._previousLongitude = None
56 self.flownDistance = 0.0
57
58 self.startFuel = None
59 self.endFuel = None
60
61 self._endCondition = threading.Condition()
62
63 self._flareStart = None
64 self._flareStartFS = None
65
66 self._tdRate = None
67
68 self._soundScheduler = SoundScheduler(self)
69 self._checklistScheduler = ChecklistScheduler(self)
70
71 @property
72 def config(self):
73 """Get the configuration."""
74 return self._gui.config
75
76 @property
77 def stage(self):
78 """Get the flight stage."""
79 return self._stage
80
81 @property
82 def bookedFlight(self):
83 """Get the booked flight."""
84 return self._gui.bookedFlight
85
86 @property
87 def zfw(self):
88 """Get the Zero-Fuel Weight of the flight."""
89 return self._gui.zfw
90
91 @property
92 def cruiseAltitude(self):
93 """Get the cruise altitude of the flight."""
94 return self._gui.cruiseAltitude
95
96 @property
97 def v1(self):
98 """Get the V1 speed of the flight."""
99 return self._gui.v1
100
101 @property
102 def vr(self):
103 """Get the Vr speed of the flight."""
104 return self._gui.vr
105
106 @property
107 def v2(self):
108 """Get the V2 speed of the flight."""
109 return self._gui.v2
110
111 @property
112 def vref(self):
113 """Get the VRef speed of the flight."""
114 return self._gui.vref
115
116 @property
117 def tdRate(self):
118 """Get the touchdown rate if known, None otherwise."""
119 return self._tdRate
120
121 def handleState(self, oldState, currentState):
122 """Handle a new state information."""
123 self._updateFlownDistance(currentState)
124
125 self.endFuel = sum(currentState.fuel)
126 if self.startFuel is None:
127 self.startFuel = self.endFuel
128
129 self._soundScheduler.schedule(currentState,
130 self._pilotHotkeyPressed)
131 self._pilotHotkeyPressed = False
132
133 if self._checklistHotkeyPressed:
134 self._checklistScheduler.hotkeyPressed()
135 self._checklistHotkeyPressed = False
136
137 def setStage(self, timestamp, stage):
138 """Set the flight stage.
139
140 Returns if the stage has really changed."""
141 if stage!=self._stage:
142 self._stage = stage
143 self._gui.setStage(stage)
144 self.logger.stage(timestamp, stage)
145 if stage==const.STAGE_PUSHANDTAXI:
146 self.blockTimeStart = timestamp
147 elif stage==const.STAGE_TAKEOFF:
148 self.flightTimeStart = timestamp
149 elif stage==const.STAGE_TAXIAFTERLAND:
150 self.flightTimeEnd = timestamp
151 elif stage==const.STAGE_PARKING:
152 self.blockTimeEnd = timestamp
153 elif stage==const.STAGE_END:
154 with self._endCondition:
155 self._endCondition.notify()
156 return True
157 else:
158 return False
159
160 def handleFault(self, faultID, timestamp, what, score):
161 """Handle the given fault.
162
163 faultID as a unique ID for the given kind of fault. If another fault of
164 this ID has been reported earlier, it will be reported again only if
165 the score is greater than last time. This ID can be, e.g. the checker
166 the report comes from."""
167 self.logger.fault(faultID, timestamp, what, score)
168 self._gui.setRating(self.logger.getRating())
169
170 def handleNoGo(self, faultID, timestamp, what, shortReason):
171 """Handle a No-Go fault."""
172 self.logger.noGo(faultID, timestamp, what)
173 self._gui.setNoGo(shortReason)
174
175 def flareStarted(self, flareStart, flareStartFS):
176 """Called when the flare time has started."""
177 self._flareStart = flareStart
178 self._flareStartFS = flareStartFS
179
180 def flareFinished(self, flareEnd, flareEndFS, tdRate):
181 """Called when the flare time has ended.
182
183 Return a tuple of the following items:
184 - a boolean indicating if FS time is used
185 - the flare time
186 """
187 self._tdRate = tdRate
188 if self.flareTimeFromFS:
189 return (True, flareEndFS - self._flareStartFS)
190 else:
191 return (False, flareEnd - self._flareStart)
192
193 def wait(self):
194 """Wait for the flight to end."""
195 with self._endCondition:
196 while self._stage!=const.STAGE_END:
197 self._endCondition.wait(1)
198
199 def getFleet(self, callback, force = False):
200 """Get the fleet and call the given callback."""
201 self._gui.getFleetAsync(callback = callback, force = force)
202
203 def pilotHotkeyPressed(self):
204 """Called when the pilot hotkey is pressed."""
205 self._pilotHotkeyPressed = True
206
207 def checklistHotkeyPressed(self):
208 """Called when the checklist hotkey is pressed."""
209 self._checklistHotkeyPressed = True
210
211 def _updateFlownDistance(self, currentState):
212 """Update the flown distance."""
213 if not currentState.onTheGround:
214 updateData = False
215 if self._lastDistanceTime is None or \
216 self._previousLatitude is None or \
217 self._previousLongitude is None:
218 updateData = True
219 elif currentState.timestamp >= (self._lastDistanceTime + 30.0):
220 updateData = True
221 self.flownDistance += self._getDistance(currentState)
222
223 if updateData:
224 self._previousLatitude = currentState.latitude
225 self._previousLongitude = currentState.longitude
226 self._lastDistanceTime = currentState.timestamp
227 else:
228 if self._lastDistanceTime is not None and \
229 self._previousLatitude is not None and \
230 self._previousLongitude is not None:
231 self.flownDistance += self._getDistance(currentState)
232
233 self._lastDistanceTime = None
234
235 def _getDistance(self, currentState):
236 """Get the distance between the previous and the current state."""
237 return util.getDistCourse(self._previousLatitude, self._previousLongitude,
238 currentState.latitude, currentState.longitude)[0]
239
240#---------------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.