source: src/mlx/flight.py@ 244:afe588c772a0

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

Added support for calculating speeds in km/h for Soviet aircraft

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