Avionics
Dropship Simulator
GPWS.cpp
Go to the documentation of this file.
1 #include "Module.h"
2 
4 
10 
28 
29 Gpws::Gpws(Bus* prmBus) : Module(prmBus)
30 {
31 }
32 
33 void Gpws::FrameMove(float fElapsed)
34 {
35  secsincelast += fElapsed;
36 
37  bus->GPWS = Bus::GpwsEnum::Reset;
38 
39  /*
40  WCHAR gpwsmsg[32];
41 
42  DWORD tempcolor=0L;
43 
44 
45  // sprintf_s( msg, sizeof(msg), "Bank %.1f (%.1f) sec %.1f", bus->RollAttitude, bus->PitchAttitude, secsincelast );
46  // m_pFont->DrawText( 80.0f, 660.0f, D3DCOLOR_ARGB(255,0,255,0), msg );
47 
48 
49  float bus->RadioAltitude=f_AGL-citystuff.elevation;
50  */
51 
52  /*
53  // Mode 1 - Excessive barometric descent rate
54  if (bus->RadioAltitude >= 0.009f && bus->RadioAltitude <= 0.746f) // 30' to 2450'
55  {
56  if (bus->GPWS > Bus::GpwsEnum::Mode1_Pull_Up &&
57  ((-bus->VerticalSpeed >= 0.009f && bus->RadioAltitude<0.082f) ||
58  (bus->RadioAltitude >= 0.082f && -bus->VerticalSpeed>((bus->RadioAltitude - 0.082f)*0.04367f + 0.009f))))
59  {
60  bus->GPWS = Bus::GpwsEnum::Mode1_Pull_Up;
61  }
62  else if (bus->GPWS > Bus::GpwsEnum::Mode1_Sink_Rate &&
63  (bus->RadioAltitude >= 0.009f && -bus->VerticalSpeed > ((bus->RadioAltitude - 0.009f)*0.02306f + 0.008f)))
64  {
65  bus->GPWS = Bus::GpwsEnum::Mode1_Sink_Rate;
66  }
67  }
68  */
69 
70  /*
71  // Mode 2A - Excessive terrain closure rate (not landing)
72  if (bus->RadioAltitude <= 0.609f && !bus->LandingGearExtended) // 2000'
73  {
74  if (bus->GPWS > Bus::GpwsEnum::Mode2a_Pull_Up &&
75  (-bus->TerrainClosureRate > (bus->RadioAltitude*0.020997f + 0.011f) ||
76  (-bus->TerrainClosureRate > 0.019f && bus->RadioAltitude<0.381f)))
77  {
78  bus->GPWS = Bus::GpwsEnum::Mode2a_Pull_Up;
79  }
80  else if (bus->GPWS>Bus::GpwsEnum::Mode2a_Terrain_Terrain &&
81  (-bus->TerrainClosureRate > (bus->RadioAltitude*0.020997f + 0.010f) ||
82  (bus->RadioAltitude >= 0.381f && -bus->TerrainClosureRate > ((bus->RadioAltitude - 0.381f)*0.144408f + 0.018f))))
83  {
84  bus->GPWS = Bus::GpwsEnum::Mode2a_Terrain_Terrain;
85  }
86  }
87 
88  // Mode 2B - Excessive terrain closure rate (landing config)
89  if (bus->RadioAltitude >= 0.061f && bus->RadioAltitude<0.241f && bus->LandingGearExtended) // 200' to 790'
90  {
91  if (bus->GPWS>Bus::GpwsEnum::Mode2b_Pull_Up &&
92  (-bus->TerrainClosureRate > ((bus->RadioAltitude - 0.061f) / 0.12184f*0.002538f + 0.01523f) || // front side of pull up envelope
93  (-bus->TerrainClosureRate > 0.017768f && -bus->TerrainClosureRate<((bus->RadioAltitude - 0.061f) / 0.12184f*0.03046f + 0.017768f)))) // backside of pull up envelope
94  {
95  bus->GPWS = Bus::GpwsEnum::Mode2b_Pull_Up;
96  }
97  else if (bus->GPWS>Bus::GpwsEnum::Mode2b_Terrain_Terrain &&
98  (-bus->TerrainClosureRate > ((bus->RadioAltitude - 0.061f) / 0.18f*0.002538f + 0.012692f) || // front side of terrain terrain envelope
99  (-bus->TerrainClosureRate > 0.01523f && -bus->TerrainClosureRate < ((bus->RadioAltitude - 0.118793f) / 0.12184f*0.035537f + 0.01523f)))) // backside of terrain terrain envelope
100  {
101  bus->GPWS = Bus::GpwsEnum::Mode2b_Terrain_Terrain;
102  }
103  }
104  */
105 
106  // Mode 3? Altitude loss after takeoff (don't sink)
107 
108  /*
109  // Mode 4A - Unsafe terrain clearance with gear not down AND DECENDING
110  // http://rise.unistellar.com/jira/view.php?id=457
111  if (bus->RadioAltitude<0.304599f && !bus->LandingGearExtended && bus->VerticalSpeed <= 0.0f)
112  {
113  if (bus->GPWS>Bus::GpwsEnum::Mode4a_Too_Low_Terrain && bus->IndicatedAirspeed<0.118369f && bus->IndicatedAirspeed>((bus->RadioAltitude - 0.1523f) / 0.1523f*0.010059f + 0.0977837f))
114  {
115  bus->GPWS = Bus::GpwsEnum::Mode4a_Too_Low_Terrain;
116  }
117  if (bus->GPWS > Bus::GpwsEnum::Mode4a_Too_Low_Gear && bus->IndicatedAirspeed < 0.0977837f && bus->RadioAltitude < 0.1523f) // 190 kts and 500'
118  {
119  bus->GPWS = Bus::GpwsEnum::Mode4a_Too_Low_Gear;
120  }
121  }
122 
123  // Mode 4B?
124  // Mode 4C?
125  */
126 
127  // Mode 5a soft single glideslope below 1000' RA and 1.3 dots or more BELOW the beam... each additional 20% causes a new aural warning
128  // Mode 5b hard repeat glideslope below 300' RA and 2 dots or greater deviation until less than 1.3 dots
129 
130  if (bus->RadioAltitude < 0.3048f && bus->GlideslopeDeviation <= D3DXToRadian(-1.3f * 0.35f)) // 1.3 dots , 1 dot I think is .35 degrees which is half-scale
131  {
132  if (bus->GPWS > Bus::GpwsEnum::Mode5a_Glideslope)
133  {
134  bus->GPWS = Bus::GpwsEnum::Mode5a_Glideslope;
135  }
136  }
137  if (bus->RadioAltitude < 0.09144f && fabsf(bus->GlideslopeDeviation) >= D3DXToRadian(2.0f * 0.35f))
138  {
139  if (bus->GPWS > Bus::GpwsEnum::Mode5b_Glideslope)
140  {
141  bus->GPWS = Bus::GpwsEnum::Mode5b_Glideslope;
142  }
143  }
144 
145 
146  // Mode 6 - Callout Bank Angle
147  /*
148  • ±10 degrees between 5 and 30 feet AGL,
149  • ±10 to ±40 degrees between 30 and 150 feet AGL,
150  • ±40 to ±55 degrees between 150 and 2450 feet AGL,
151  • ±55 degrees above 2450 feet AGL,
152  With the AutoPilot engaged, bank angles exceeding:
153  • ±10 degrees between 5 and 30 feet AGL,
154  • ±10 to ±33 degrees between 30 and 122 feet AGL,
155  • ±33 degrees above 122 feet AGL,
156  Once the initial roll limit is exceeded, the “BANK ANGLE, BANK
157  ANGLE” callout is given once. Another callout is not given until
158  either:
159  1) a 20% increase in roll is detected, or
160  2) the aircraft rolls below the initial roll limit (resetting the process)
161  and initial roll limit is exceeded again.
162  If the 20% increase in roll is exceeded (causing the second bank
163  angle alert), another callout is not given until either:
164  1) another 20% increase in roll is detected, or
165  2) the aircraft rolls below the initial roll limit and another (resetting
166  the process) and the initial roll is exceeded again.
167  Above the second 20% increase in roll, the callout is continuous
168  until roll is reduced below this second 20% limit.
169  If roll rate exceeds the audio callout time, then the bypassed
170  limit is not indicated (e.g., if a 20% increase is exceeded before
171  the initial roll limit callout can be completed).
172  */
173  if (fabsf(bus->RollAttitude) >= 0.96f)
174  {
175  if (bus->GPWS > Bus::GpwsEnum::Mode6_Bank_Angle)
176  {
177  bus->GPWS = Bus::GpwsEnum::Mode6_Bank_Angle;
178  }
179  }
180 
181  static float oldradioaltitude = bus->RadioAltitude;
182  if (bus->waypoints.size() > 0 && bus->waypoints.at(0).type == Waypoint::WaypointType::TouchdownZone)
183  {
184  if (oldradioaltitude >= 0.003048f && bus->RadioAltitude < 0.003048f && bus->GPWS > Bus::GpwsEnum::Mode6_Ten)
185  bus->GPWS = Bus::GpwsEnum::Mode6_Ten;
186  else if (oldradioaltitude >= 0.006096f && bus->RadioAltitude < 0.006096f && bus->GPWS > Bus::GpwsEnum::Mode6_Twenty)
187  bus->GPWS = Bus::GpwsEnum::Mode6_Twenty;
188  else if (oldradioaltitude >= 0.009144f && bus->RadioAltitude < 0.009144f && bus->GPWS > Bus::GpwsEnum::Mode6_Thirty)
189  bus->GPWS = Bus::GpwsEnum::Mode6_Thirty;
190  else if (oldradioaltitude >= 0.012192f && bus->RadioAltitude < 0.012192f && bus->GPWS > Bus::GpwsEnum::Mode6_Fourty)
191  bus->GPWS = Bus::GpwsEnum::Mode6_Fourty;
192  else if (oldradioaltitude >= 0.01524f && bus->RadioAltitude < 0.01524f && bus->GPWS > Bus::GpwsEnum::Mode6_Fifty)
193  bus->GPWS = Bus::GpwsEnum::Mode6_Fifty;
194  else if (oldradioaltitude >= 0.03048f && bus->RadioAltitude < 0.03048f && bus->GPWS > Bus::GpwsEnum::Mode6_One_Hundred)
195  bus->GPWS = Bus::GpwsEnum::Mode6_One_Hundred;
196  else if (oldradioaltitude >= 0.06096f && bus->RadioAltitude < 0.06096f && bus->GPWS > Bus::GpwsEnum::Mode6_Two_Hundred)
197  bus->GPWS = Bus::GpwsEnum::Mode6_Two_Hundred;
198  else if (oldradioaltitude >= 0.1524f && bus->RadioAltitude < 0.1524f && bus->GPWS > Bus::GpwsEnum::Mode6_Five_Hundred)
199  bus->GPWS = Bus::GpwsEnum::Mode6_Five_Hundred;
200  else if (oldradioaltitude >= 0.3048f && bus->RadioAltitude < 0.3048f && bus->GPWS > Bus::GpwsEnum::Mode6_One_Thousand)
201  bus->GPWS = Bus::GpwsEnum::Mode6_One_Thousand;
203 // else if (bus->RadioAltitude < 0.01524f && (bus->EngineThrustCommand[0]>0.0f || bus->EngineThrustCommand[1] > 0.0f))
204  // bus->GPWS = Bus::GpwsEnum::Mode6_Retard;
205  }
206 
209 
210  oldradioaltitude = bus->RadioAltitude;
211 
212  //if (bus->RadioAltitude > 0.00913798f && bus->RadioAltitude<0.761499f) // 30' to 2500'
213  //{
214  // if (bus->GPWS>Bus::GpwsEnum::Mode6_Bank_Angle && // alt-30' divided by 120' times 30° plus 10°
215  // (bus->RadioAltitude<0.0456899f && fabsf(bus->RollAttitude)>((bus->RadioAltitude - 0.00913798f) / 0.0365519f*0.523599f + 0.174532925f) ||
216  // bus->RadioAltitude > 0.0456899f && fabsf(bus->RollAttitude) > ((bus->RadioAltitude - 0.0456899f) / 0.715809f*0.261799f + 0.6981317f) ||
217  // fabsf(bus->PitchAttitude) > 1.570796f)) // >90° or <-90° is upside-down
218  // {
219  // bus->GPWS = Bus::GpwsEnum::Mode6_Bank_Angle;
220  // }
221  //}
222 
223  Command command;
224  switch (bus->GPWS)
225  {
226  case Bus::NoAlert:
227  break;
228  case Bus::Reset:
229  bus->GPWS = Bus::GpwsEnum::NoAlert;
230  break;
231  case Bus::GpwsEnum::Mode5a_Glideslope:
232  case Bus::GpwsEnum::Mode5b_Glideslope:
233  if (secsincelast < 2.0f) return; secsincelast = 0.0f; // keep from repeating too fast
234  command.name = "Glideslope";
235  bus->commandStream.push_back(command);
236  break;
237  case Bus::GpwsEnum::Mode6_Bank_Angle:
238  if (secsincelast < 2.0f) return; secsincelast = 0.0f; // keep from repeating too fast
239  command.name = "GPWSBankAngle";
240  bus->commandStream.push_back(command);
241  break;
242  case Bus::GpwsEnum::Mode6_Retard:
243  if (secsincelast < 0.648f) return; secsincelast = 0.0f; // keep from repeating too fast
244  command.name = "GPWSMode6Retard";
245  command.ttl = 0.648f;
246  bus->commandStream.push_back(command);
247  break;
248  case Bus::GpwsEnum::Mode6_Ten:
249  if (secsincelast < 0.431f) return; secsincelast = 0.0f; // buffer from twenty
250  command.name = "GPWSMode6Ten";
251  command.ttl = 0.431f;
252  bus->commandStream.push_back(command);
253  break;
254  case Bus::GpwsEnum::Mode6_Twenty:
255  if (secsincelast < 0.449f) return; secsincelast = 0.0f; // buffer from thirty
256  command.name = "GPWSMode6Twenty";
257  command.ttl = 0.449f;
258  bus->commandStream.push_back(command);
259  break;
260  case Bus::GpwsEnum::Mode6_Thirty:
261  if (secsincelast < 0.473f) return; secsincelast = 0.0f; // buffer from fourty
262  command.name = "GPWSMode6Thirty";
263  command.ttl = 0.473f;
264  bus->commandStream.push_back(command);
265  break;
266  case Bus::GpwsEnum::Mode6_Fourty:
267  if (secsincelast < 0.442f) return; secsincelast = 0.0f; // buffer from fifty
268  command.name = "GPWSMode6Fourty";
269  command.ttl = 0.442f;
270  bus->commandStream.push_back(command);
271  break;
272  case Bus::GpwsEnum::Mode6_Fifty:
273  if (secsincelast < 0.613f) return; secsincelast = 0.0f; // buffer from one hundred
274  command.name = "GPWSMode6Fifty";
275  command.ttl = 0.613f;
276  bus->commandStream.push_back(command);
277  break;
278  case Bus::GpwsEnum::Mode6_One_Hundred:
279  if (secsincelast < 0.589f) return; secsincelast = 0.0f; // buffer from two hundred
280  command.name = "GPWSMode6OneHundred";
281  command.ttl = 0.589f;
282  bus->commandStream.push_back(command);
283  break;
284  case Bus::GpwsEnum::Mode6_Two_Hundred:
285  command.name = "GPWSMode6TwoHundred";
286  bus->commandStream.push_back(command);
287  command.name = "GPWSMode9Minimums";
288  bus->commandStream.push_back(command);
289  break;
290  case Bus::GpwsEnum::Mode6_Five_Hundred:
291  command.name = "GPWSMode6FiveHundred";
292  bus->commandStream.push_back(command);
293  break;
294  case Bus::GpwsEnum::Mode6_One_Thousand:
295  command.name = "GPWSMode6OneThousand";
296  bus->commandStream.push_back(command);
297  break;
298  case Bus::Mode1_Sink_Rate: break;
299  case Bus::Mode1_Pull_Up: break;
300  case Bus::Mode2a_Terrain_Terrain: break;
301  case Bus::Mode2a_Pull_Up: break;
302  case Bus::Mode2b_Terrain_Terrain: break;
303  case Bus::Mode2b_Pull_Up: break;
304  case Bus::Mode2_Terrain: break;
305  case Bus::Mode3_Dont_Sink: break;
306  case Bus::Mode4a_Too_Low_Terrain: break;
307  case Bus::Mode4a_Too_Low_Gear: break;
308  case Bus::Mode4b_Too_Low_Terrain: break;
309  case Bus::Mode4b_Too_Low_Flaps: break;
310  case Bus::Mode4c_Too_Low_Terrain: break;
311  case Bus::Mode6_Minimums_Minimums: break;
312  case Bus::Mode6_Caution_Terrain: break;
313  case Bus::Mode6_Caution_Obstacle: break;
314  default: break;
315  }
316 }
Unsafe terrain clearance with gear not down AND DECENDING.
Definition: Bus.h:172
std::vector< Command > commandStream
Definition: Bus.h:20
Advisory callouts.
Definition: Bus.h:181
enum Bus::GpwsEnum GPWS
Altitude Loss After TakeOff.
Definition: Bus.h:170
Excessive barometric descent rate.
Definition: Bus.h:161
void FrameMove(float fElapsedTime) override
Definition: GPWS.cpp:33
std::vector< Waypoint > waypoints
Definition: Bus.h:367
float secsincelast
Definition: Module.h:41
Definition: Bus.h:12
std::string name
command name
Definition: Command.h:11
float RollAttitude
(7) Roll attitude;
Definition: Bus.h:51
float ttl
time to live in seconds (default is 10)
Definition: Command.h:17
Abstract base class for modules By definition, instruments don&#39;t do any of the work (they don&#39;t modif...
Definition: Module.h:11
Definition: Command.h:5
float RadioAltitude
Definition: Bus.h:134
Bus * bus
Definition: Module.h:17
Excessive terrain closure rate.
Definition: Bus.h:164
Gpws(Bus *prmBus)
Definition: GPWS.cpp:29
float GlideslopeDeviation
Definition: Bus.h:136