97
/*******************************************************************
99
* initialize the Aircraft at the parking location
100
******************************************************************/
101
void FGAIFlightPlan::createTaxi(bool firstFlight, int direction,
102
FGAirport *apt, double latitude, double longitude,
103
double radius, const string& fltType,
104
const string& acType, const string& airline)
108
double lat2, lon2, az2;
111
int nrWaypointsToSkip;
115
// If this function is called during initialization,
116
// make sure we obtain a valid gate ID first
117
// and place the model at the location of the gate.
120
if (!(apt->getDynamics()->getAvailableParking(&lat, &lon,
125
SG_LOG(SG_INPUT, SG_WARN, "Could not find parking for a " <<
127
" of flight type " << fltType <<
128
" of airline " << airline <<
129
" at airport " << apt->getId());
131
//waypoint *wpt = new waypoint;
132
//wpt->name = "park";
133
//wpt->latitude = lat;
134
//wpt->longitude = lon;
135
//wpt->altitude = apt->getElevation();
137
//wpt->crossat = -10000;
138
//wpt->gear_down = true;
139
//wpt->flaps_down= true;
140
//wpt->finished = false;
141
//wpt->on_ground = true;
142
//waypoints.push_back(wpt);
144
string rwyClass = getRunwayClassFromTrafficType(fltType);
145
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
146
rwy = apt->getRunwayByIdent(activeRunway);
148
// Determine the beginning of he runway
149
heading = rwy->headingDeg();
150
double azimuth = heading + 180.0;
151
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
152
geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
153
rwy->lengthM() * 0.5 - 5.0,
154
&lat2, &lon2, &az2 );
156
if (apt->getDynamics()->getGroundNetwork()->exists())
159
int runwayId = apt->getDynamics()->getGroundNetwork()->findNearestNode(lat2,
163
// A negative gateId indicates an overflow parking, use a
164
// fallback mechanism for this.
165
// Starting from gate 0 in this case is a bit of a hack
166
// which requires a more proper solution later on.
169
taxiRoute = new FGTaxiRoute;
171
// Determine which node to start from.
173
// Find out which node to start from
174
FGParking *park = apt->getDynamics()->getParking(gateId);
176
node = park->getPushBackPoint();
182
// HAndle case where parking doens't have a node
183
if ((node == 0) && park) {
187
node = lastNodeVisited;
191
//cerr << "Using node " << node << endl;
192
*taxiRoute = apt->getDynamics()->getGroundNetwork()->findShortestRoute(node, runwayId);
195
if (taxiRoute->empty()) {
196
//Add the runway startpoint;
198
wpt->name = "Airport Center";
199
wpt->latitude = latitude;
200
wpt->longitude = longitude;
201
wpt->altitude = apt->getElevation();
203
wpt->crossat = -10000;
204
wpt->gear_down = true;
205
wpt->flaps_down= true;
206
wpt->finished = false;
207
wpt->on_ground = true;
209
waypoints.push_back(wpt);
211
//Add the runway startpoint;
213
wpt->name = "Runway Takeoff";
214
wpt->latitude = lat2;
215
wpt->longitude = lon2;
216
wpt->altitude = apt->getElevation();
218
wpt->crossat = -10000;
219
wpt->gear_down = true;
220
wpt->flaps_down= true;
221
wpt->finished = false;
222
wpt->on_ground = true;
224
waypoints.push_back(wpt);
228
//bool isPushBackPoint = false;
231
// If this is called during initialization, randomly
232
// skip a number of waypoints to get a more realistic
234
//isPushBackPoint = true;
235
int nrWaypoints = taxiRoute->size();
236
nrWaypointsToSkip = rand() % nrWaypoints;
237
// but make sure we always keep two active waypoints
238
// to prevent a segmentation fault
239
for (int i = 0; i < nrWaypointsToSkip-2; i++) {
240
//isPushBackPoint = false;
241
taxiRoute->next(&node);
243
apt->getDynamics()->releaseParking(gateId);
245
if (taxiRoute->size() > 1) {
246
taxiRoute->next(&node); // chop off the first waypoint, because that is already the last of the pushback route
250
while(taxiRoute->next(&node, &route))
252
//FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findSegment(node)->getEnd();
254
snprintf (buffer, 10, "%d", node);
255
FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
258
wpt->name = string(buffer); // fixme: should be the name of the taxiway
259
wpt->latitude = tn->getLatitude();
260
wpt->longitude = tn->getLongitude();
261
// Elevation is currently disregarded when on_ground is true
262
// because the AIModel obtains a periodic ground elevation estimate.
263
wpt->altitude = apt->getElevation();
265
wpt->crossat = -10000;
266
wpt->gear_down = true;
267
wpt->flaps_down= true;
268
wpt->finished = false;
269
wpt->on_ground = true;
270
wpt->routeIndex = route;
271
waypoints.push_back(wpt);
275
// finally, rewind the taxiRoute object to the point where we started
276
// generating the Flightplan, for AI use.
277
// This is a bit tricky, because the
280
for (int i = 0; i < nrWaypointsToSkip-1; i++) {
281
taxiRoute->next(&node);
284
int size = taxiRoute->size();
286
//taxiRoute->next(&node);
287
//taxiRoute->next(&node);
288
//taxiRoute->next(&node);
291
} // taxiRoute not empty
295
// This is the fallback mechanism, in case no ground network is available
296
//Add the runway startpoint;
298
wpt->name = "Airport Center";
299
wpt->latitude = apt->getLatitude();
300
wpt->longitude = apt->getLongitude();
301
wpt->altitude = apt->getElevation();
303
wpt->crossat = -10000;
304
wpt->gear_down = true;
305
wpt->flaps_down= true;
306
wpt->finished = false;
307
wpt->on_ground = true;
309
waypoints.push_back(wpt);
311
//Add the runway startpoint;
313
wpt->name = "Runway Takeoff";
314
wpt->latitude = lat2;
315
wpt->longitude = lon2;
316
wpt->altitude = apt->getElevation();
318
wpt->crossat = -10000;
319
wpt->gear_down = true;
320
wpt->flaps_down= true;
321
wpt->finished = false;
322
wpt->on_ground = true;
324
waypoints.push_back(wpt);
329
apt->getDynamics()->getAvailableParking(&lat, &lon, &heading,
330
&gateId, radius, fltType,
333
double lat3 = (*(waypoints.end()-1))->latitude;
334
double lon3 = (*(waypoints.end()-1))->longitude;
335
//cerr << (*(waypoints.end()-1))->name << endl;
337
// Find a route from runway end to parking/gate.
338
if (apt->getDynamics()->getGroundNetwork()->exists())
341
int runwayId = apt->getDynamics()->getGroundNetwork()->findNearestNode(lat3,
343
// A negative gateId indicates an overflow parking, use a
344
// fallback mechanism for this.
345
// Starting from gate 0 is a bit of a hack...
348
taxiRoute = new FGTaxiRoute;
350
*taxiRoute = apt->getDynamics()->getGroundNetwork()->findShortestRoute(runwayId,
353
*taxiRoute = apt->getDynamics()->getGroundNetwork()->findShortestRoute(runwayId, 0);
356
// No route found: go from gate directly to runway
357
if (taxiRoute->empty()) {
358
//Add the runway startpoint;
360
wpt->name = "Airport Center";
361
wpt->latitude = latitude;
362
wpt->longitude = longitude;
363
wpt->altitude = apt->getElevation();
365
wpt->crossat = -10000;
366
wpt->gear_down = true;
367
wpt->flaps_down= true;
368
wpt->finished = false;
369
wpt->on_ground = true;
371
waypoints.push_back(wpt);
373
//Add the runway startpoint;
375
wpt->name = "Runway Takeoff";
376
wpt->latitude = lat3;
377
wpt->longitude = lon3;
378
wpt->altitude = apt->getElevation();
380
wpt->crossat = -10000;
381
wpt->gear_down = true;
382
wpt->flaps_down= true;
383
wpt->finished = false;
384
wpt->on_ground = true;
386
waypoints.push_back(wpt);
390
int size = taxiRoute->size();
391
// Omit the last two waypoints, as
392
// those are created by createParking()
394
for (int i = 0; i < size-2; i++)
396
taxiRoute->next(&node, &route);
398
snprintf (buffer, 10, "%d", node);
399
//FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
400
FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
402
//wpt->name = "taxiway"; // fixme: should be the name of the taxiway
403
wpt->name = string(buffer);// fixme: should be the name of the taxiway
404
wpt->latitude = tn->getLatitude();
405
wpt->longitude = tn->getLongitude();
406
wpt->altitude = apt->getElevation();
408
wpt->crossat = -10000;
409
wpt->gear_down = true;
410
wpt->flaps_down= true;
411
wpt->finished = false;
412
wpt->on_ground = true;
413
wpt->routeIndex = route;
414
waypoints.push_back(wpt);
416
//taxiRoute->first();
417
//taxiRoute->next(&node);
422
// Use a fallback mechanism in case no ground network is available
423
// obtain the location of the gate entrance point
427
geo_direct_wgs_84 ( 0, lat, lon, heading,
429
&lat2, &lon2, &az2 );
431
wpt->name = "Airport Center";
432
wpt->latitude = apt->getLatitude();
433
wpt->longitude = apt->getLongitude();
434
wpt->altitude = apt->getElevation();
436
wpt->crossat = -10000;
437
wpt->gear_down = true;
438
wpt->flaps_down= true;
439
wpt->finished = false;
440
wpt->on_ground = true;
442
waypoints.push_back(wpt);
445
wpt->name = "Begin Parking"; //apt->getId(); //wpt_node->getStringValue("name", "END");
446
wpt->latitude = lat2;
447
wpt->longitude = lon2;
448
wpt->altitude = apt->getElevation();
450
wpt->crossat = -10000;
451
wpt->gear_down = true;
452
wpt->flaps_down= true;
453
wpt->finished = false;
454
wpt->on_ground = true;
456
waypoints.push_back(wpt);
462
apt->getDynamics()->getParking(gateId, &lat, &lon, &heading);
468
wpt->name = "END"; //wpt_node->getStringValue("name", "END");
470
wpt->longitude = lon;
473
wpt->crossat = -10000;
474
wpt->gear_down = true;
475
wpt->flaps_down= true;
476
wpt->finished = false;
477
wpt->on_ground = true;
479
waypoints.push_back(wpt);
95
FGAIFlightPlan::waypoint*
96
FGAIFlightPlan::createOnGround(FGAIAircraft *ac, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed)
98
waypoint* wpt = new waypoint;
100
wpt->longitude = aPos.getLongitudeDeg();
101
wpt->latitude = aPos.getLatitudeDeg();
102
wpt->altitude = aElev;
104
wpt->crossat = -10000;
105
wpt->gear_down = true;
106
wpt->flaps_down= true;
107
wpt->finished = false;
108
wpt->on_ground = true;
113
FGAIFlightPlan::waypoint*
114
FGAIFlightPlan::createInAir(FGAIAircraft *ac, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed)
116
waypoint* wpt = new waypoint;
118
wpt->longitude = aPos.getLongitudeDeg();
119
wpt->latitude = aPos.getLatitudeDeg();
120
wpt->altitude = aElev;
122
wpt->crossat = -10000;
123
wpt->gear_down = false;
124
wpt->flaps_down= false;
125
wpt->finished = false;
126
wpt->on_ground = false;
131
FGAIFlightPlan::waypoint*
132
FGAIFlightPlan::cloneWithPos(FGAIAircraft *ac, waypoint* aWpt, const std::string& aName, const SGGeod& aPos)
134
waypoint* wpt = new waypoint;
136
wpt->longitude = aPos.getLongitudeDeg();
137
wpt->latitude = aPos.getLatitudeDeg();
139
wpt->altitude = aWpt->altitude;
140
wpt->speed = aWpt->speed;
141
wpt->crossat = aWpt->crossat;
142
wpt->gear_down = aWpt->gear_down;
143
wpt->flaps_down= aWpt->flaps_down;
144
wpt->finished = aWpt->finished;
145
wpt->on_ground = aWpt->on_ground;
151
FGAIFlightPlan::waypoint*
152
FGAIFlightPlan::clone(waypoint* aWpt)
154
waypoint* wpt = new waypoint;
155
wpt->name = aWpt->name;
156
wpt->longitude = aWpt->longitude;
157
wpt->latitude = aWpt->latitude;
159
wpt->altitude = aWpt->altitude;
160
wpt->speed = aWpt->speed;
161
wpt->crossat = aWpt->crossat;
162
wpt->gear_down = aWpt->gear_down;
163
wpt->flaps_down= aWpt->flaps_down;
164
wpt->finished = aWpt->finished;
165
wpt->on_ground = aWpt->on_ground;
172
void FGAIFlightPlan::createDefaultTakeoffTaxi(FGAIAircraft *ac, FGAirport* aAirport, FGRunway* aRunway)
174
SGGeod runwayTakeoff = aRunway->pointOnCenterline(5.0);
175
double airportElev = aAirport->getElevation();
178
wpt = createOnGround(ac, "Airport Center", aAirport->geod(), airportElev, ac->getPerformance()->vTaxi());
179
waypoints.push_back(wpt);
180
wpt = createOnGround(ac, "Runway Takeoff", runwayTakeoff, airportElev, ac->getPerformance()->vTaxi());
181
waypoints.push_back(wpt);
184
void FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft *ac, bool firstFlight,
186
double radius, const string& fltType,
187
const string& acType, const string& airline)
189
double heading, lat, lon;
191
// If this function is called during initialization,
192
// make sure we obtain a valid gate ID first
193
// and place the model at the location of the gate.
195
if (!(apt->getDynamics()->getAvailableParking(&lat, &lon,
200
SG_LOG(SG_INPUT, SG_WARN, "Could not find parking for a " <<
202
" of flight type " << fltType <<
203
" of airline " << airline <<
204
" at airport " << apt->getId());
208
string rwyClass = getRunwayClassFromTrafficType(fltType);
210
// Only set this if it hasn't been set by ATC already.
211
if (activeRunway.empty()) {
212
//cerr << "Getting runway for " << ac->getTrafficRef()->getCallSign() << " at " << apt->getId() << endl;
213
double depHeading = ac->getTrafficRef()->getCourse();
214
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway, depHeading);
216
rwy = apt->getRunwayByIdent(activeRunway);
217
SGGeod runwayTakeoff = rwy->pointOnCenterline(5.0);
219
FGGroundNetwork* gn = apt->getDynamics()->getGroundNetwork();
221
createDefaultTakeoffTaxi(ac, apt, rwy);
226
int runwayId = gn->findNearestNode(runwayTakeoff);
228
// A negative gateId indicates an overflow parking, use a
229
// fallback mechanism for this.
230
// Starting from gate 0 in this case is a bit of a hack
231
// which requires a more proper solution later on.
233
taxiRoute = new FGTaxiRoute;
235
// Determine which node to start from.
237
// Find out which node to start from
238
FGParking *park = apt->getDynamics()->getParking(gateId);
240
node = park->getPushBackPoint();
247
// HAndle case where parking doens't have a node
248
if ((node == 0) && park) {
252
node = lastNodeVisited;
256
*taxiRoute = gn->findShortestRoute(node, runwayId);
259
if (taxiRoute->empty()) {
260
createDefaultTakeoffTaxi(ac, apt, rwy);
265
//bool isPushBackPoint = false;
267
// If this is called during initialization, randomly
268
// skip a number of waypoints to get a more realistic
270
int nrWaypointsToSkip = rand() % taxiRoute->size();
271
// but make sure we always keep two active waypoints
272
// to prevent a segmentation fault
273
for (int i = 0; i < nrWaypointsToSkip-2; i++) {
274
taxiRoute->next(&node);
276
apt->getDynamics()->releaseParking(gateId);
278
if (taxiRoute->size() > 1) {
279
taxiRoute->next(&node); // chop off the first waypoint, because that is already the last of the pushback route
283
// push each node on the taxi route as a waypoint
285
while(taxiRoute->next(&node, &route)) {
287
snprintf (buffer, 10, "%d", node);
288
FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
289
waypoint* wpt = createOnGround(ac, buffer, tn->getGeod(), apt->getElevation(), ac->getPerformance()->vTaxi());
290
wpt->routeIndex = route;
291
waypoints.push_back(wpt);
295
void FGAIFlightPlan::createDefaultLandingTaxi(FGAIAircraft *ac, FGAirport* aAirport)
298
SGGeod::fromDeg(waypoints.back()->longitude, waypoints.back()->latitude);
299
double airportElev = aAirport->getElevation();
302
wpt = createOnGround(ac, "Runway Exit", lastWptPos, airportElev, ac->getPerformance()->vTaxi());
303
waypoints.push_back(wpt);
304
wpt = createOnGround(ac, "Airport Center", aAirport->geod(), airportElev, ac->getPerformance()->vTaxi());
305
waypoints.push_back(wpt);
307
double heading, lat, lon;
308
aAirport->getDynamics()->getParking(gateId, &lat, &lon, &heading);
309
wpt = createOnGround(ac, "END", SGGeod::fromDeg(lon, lat), airportElev, ac->getPerformance()->vTaxi());
310
waypoints.push_back(wpt);
313
void FGAIFlightPlan::createLandingTaxi(FGAIAircraft *ac, FGAirport *apt,
314
double radius, const string& fltType,
315
const string& acType, const string& airline)
317
double heading, lat, lon;
318
apt->getDynamics()->getAvailableParking(&lat, &lon, &heading,
319
&gateId, radius, fltType, acType, airline);
322
SGGeod::fromDeg(waypoints.back()->longitude, waypoints.back()->latitude);
323
FGGroundNetwork* gn = apt->getDynamics()->getGroundNetwork();
325
// Find a route from runway end to parking/gate.
327
createDefaultLandingTaxi(ac, apt);
332
int runwayId = gn->findNearestNode(lastWptPos);
333
// A negative gateId indicates an overflow parking, use a
334
// fallback mechanism for this.
335
// Starting from gate 0 is a bit of a hack...
338
taxiRoute = new FGTaxiRoute;
340
*taxiRoute = gn->findShortestRoute(runwayId, gateId);
342
*taxiRoute = gn->findShortestRoute(runwayId, 0);
345
if (taxiRoute->empty()) {
346
createDefaultLandingTaxi(ac, apt);
352
int size = taxiRoute->size();
353
// Omit the last two waypoints, as
354
// those are created by createParking()
356
for (int i = 0; i < size-2; i++) {
357
taxiRoute->next(&node, &route);
359
snprintf (buffer, 10, "%d", node);
360
FGTaxiNode *tn = gn->findNode(node);
361
waypoint* wpt = createOnGround(ac, buffer, tn->getGeod(), apt->getElevation(), ac->getPerformance()->vTaxi());
362
wpt->routeIndex = route;
363
waypoints.push_back(wpt);
485
367
/*******************************************************************
487
369
* initialize the Aircraft at the parking location
488
370
******************************************************************/
489
void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double speed, const string &fltType)
371
void FGAIFlightPlan::createTakeOff(FGAIAircraft *ac, bool firstFlight, FGAirport *apt, double speed, const string &fltType)
493
double lat2, lon2, az2;
496
// Get the current active runway, based on code from David Luff
497
// This should actually be unified and extended to include
498
// Preferential runway use schema's
373
double accel = ac->getPerformance()->acceleration();
374
double vTaxi = ac->getPerformance()->vTaxi();
375
double vRotate = ac->getPerformance()->vRotate();
376
// double vTakeoff = ac->getPerformance()->vTakeoff();
377
double vClimb = ac->getPerformance()->vClimb();
378
// Acceleration = dV / dT
379
// Acceleration X dT = dV
380
// dT = dT / Acceleration
381
//d = (Vf^2 - Vo^2) / (2*a)
382
// double accelTime = (vRotate - vTaxi) / accel;
383
//cerr << "Using " << accelTime << " as total acceleration time" << endl;
384
double accelDistance = (vRotate*vRotate - vTaxi*vTaxi) / (2*accel);
385
//cerr << "Using " << accelDistance << " " << accel << " " << vRotate << endl;
387
// Get the current active runway, based on code from David Luff
388
// This should actually be unified and extended to include
389
// Preferential runway use schema's
390
// NOTE: DT (2009-01-18: IIRC, this is currently already the case,
391
// because the getActive runway function takes care of that.
502
string rwyClass = getRunwayClassFromTrafficType(fltType);
503
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
504
rwy = apt->getRunwayByIdent(activeRunway);
394
string rwyClass = getRunwayClassFromTrafficType(fltType);
395
double heading = ac->getTrafficRef()->getCourse();
396
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway, heading);
397
rwy = apt->getRunwayByIdent(activeRunway);
506
// Acceleration point, 105 meters into the runway,
507
heading = rwy->headingDeg();
508
double azimuth = heading + 180.0;
509
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
510
geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
511
rwy->lengthM() * 0.5 - 105.0,
512
&lat2, &lon2, &az2 );
515
wpt->latitude = lat2;
516
wpt->longitude = lon2;
517
wpt->altitude = apt->getElevation();
519
wpt->crossat = -10000;
520
wpt->gear_down = true;
521
wpt->flaps_down= true;
522
wpt->finished = false;
523
wpt->on_ground = true;
525
waypoints.push_back(wpt);
531
//Start Climbing to 3000 ft. Let's do this
532
// at the center of the runway for now:
534
geo_direct_wgs_84 ( 0, lat, lon, heading,
535
2560 * SG_FEET_TO_METER,
536
&lat2, &lon2, &az2 );
540
wpt->latitude = rwy->latitude();
541
wpt->longitude = rwy->longitude();
542
wpt->altitude = apt->getElevation()+1000;
544
wpt->crossat = -10000;
545
wpt->gear_down = true;
546
wpt->flaps_down= true;
547
wpt->finished = false;
548
wpt->on_ground = false;
550
waypoints.push_back(wpt);
553
geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading,
555
&lat2, &lon2, &az2 );
558
wpt->name = "3000 ft";
559
wpt->latitude = lat2;
560
wpt->longitude = lon2;
561
wpt->altitude = apt->getElevation()+3000;
563
wpt->crossat = -10000;
564
wpt->gear_down = true;
565
wpt->flaps_down= true;
566
wpt->finished = false;
567
wpt->on_ground = false;
569
waypoints.push_back(wpt);
571
// Finally, add two more waypoints, so that aircraft will remain under
572
// Tower control until they have reached the 3000 ft climb point
575
geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading,
577
&lat2, &lon2, &az2 );
581
wpt->name = "5000 ft";
582
wpt->latitude = lat2;
583
wpt->longitude = lon2;
584
wpt->altitude = apt->getElevation()+5000;
586
wpt->crossat = -10000;
587
wpt->gear_down = true;
588
wpt->flaps_down= true;
589
wpt->finished = false;
590
wpt->on_ground = false;
592
waypoints.push_back(wpt);
593
//cerr << "Created takeoff plan : " << endl;
594
//for (wpt_vector_iterator i = waypoints.begin(); i != waypoints.end(); i++) {
595
// cerr << "Waypoint Name: " << (*i)->name << ". Speed = " << (*i)->speed << endl;
599
// geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading,
601
// &lat2, &lon2, &az2 );
602
// wpt = new waypoint;
603
// wpt->name = "5100 ft";
604
// wpt->latitude = lat2;
605
// wpt->longitude = lon2;
606
// wpt->altitude = apt->getElevation()+5100;
607
// wpt->speed = speed;
608
// wpt->crossat = -10000;
609
// wpt->gear_down = true;
610
// wpt->flaps_down= true;
611
// wpt->finished = false;
612
// wpt->on_ground = false;
613
// wpt->routeIndex = 0;
614
// waypoints.push_back(wpt);
400
double airportElev = apt->getElevation();
401
// Acceleration point, 105 meters into the runway,
402
SGGeod accelPoint = rwy->pointOnCenterline(105.0);
403
wpt = createOnGround(ac, "accel", accelPoint, airportElev, vClimb);
404
waypoints.push_back(wpt);
406
//Start Climbing to 3000 ft. Let's do this
407
// at the center of the runway for now:
408
SGGeod rotate = rwy->pointOnCenterline(105.0+accelDistance);
409
wpt = cloneWithPos(ac, wpt, "SOC", rotate);
410
wpt->altitude = airportElev+1000;
411
wpt->on_ground = false;
412
waypoints.push_back(wpt);
414
wpt = cloneWithPos(ac, wpt, "3000 ft", rwy->end());
415
wpt->altitude = airportElev+3000;
416
waypoints.push_back(wpt);
418
// Finally, add two more waypoints, so that aircraft will remain under
419
// Tower control until they have reached the 3000 ft climb point
420
SGGeod pt = rwy->pointOnCenterline(5000 + rwy->lengthM() * 0.5);
421
wpt = cloneWithPos(ac, wpt, "5000 ft", pt);
422
wpt->altitude = airportElev+5000;
423
waypoints.push_back(wpt);
617
426
/*******************************************************************
619
428
* initialize the Aircraft at the parking location
620
429
******************************************************************/
621
void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed, double alt, const string &fltType)
430
void FGAIFlightPlan::createClimb(FGAIAircraft *ac, bool firstFlight, FGAirport *apt, double speed, double alt, const string &fltType)
625
double lat2, lon2, az2;
433
// bool planLoaded = false;
435
double vClimb = ac->getPerformance()->vClimb();
633
string rwyClass = getRunwayClassFromTrafficType(fltType);
634
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
635
rwy = apt->getRunwayByIdent(activeRunway);
438
string rwyClass = getRunwayClassFromTrafficType(fltType);
439
double heading = ac->getTrafficRef()->getCourse();
440
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway, heading);
441
rwy = apt->getRunwayByIdent(activeRunway);
444
for (wpt_vector_iterator i = sid->getFirstWayPoint();
445
i != sid->getLastWayPoint();
447
waypoints.push_back(clone(*(i)));
448
//cerr << " Cloning waypoint " << endl;
639
heading = rwy->headingDeg();
640
double azimuth = heading + 180.0;
641
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
642
//cerr << "Creating climb at : " << rwy._id << " " << rwy._rwy_no << endl;
643
geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading,
645
&lat2, &lon2, &az2 );
647
wpt->name = "10000ft climb";
648
wpt->latitude = lat2;
649
wpt->longitude = lon2;
650
wpt->altitude = 10000;
652
wpt->crossat = -10000;
653
wpt->gear_down = true;
654
wpt->flaps_down= true;
655
wpt->finished = false;
656
wpt->on_ground = false;
658
waypoints.push_back(wpt);
451
SGGeod climb1 = rwy->pointOnCenterline(10*SG_NM_TO_METER);
452
wpt = createInAir(ac, "10000ft climb", climb1, vClimb, 10000);
453
wpt->gear_down = true;
454
wpt->flaps_down= true;
455
waypoints.push_back(wpt);
661
geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading,
663
&lat2, &lon2, &az2 );
665
wpt->name = "18000ft climb";
666
wpt->latitude = lat2;
667
wpt->longitude = lon2;
668
wpt->altitude = 18000;
670
wpt->crossat = -10000;
671
wpt->gear_down = true;
672
wpt->flaps_down= true;
673
wpt->finished = false;
674
wpt->on_ground = false;
676
waypoints.push_back(wpt);
457
SGGeod climb2 = rwy->pointOnCenterline(20*SG_NM_TO_METER);
458
wpt = cloneWithPos(ac, wpt, "18000ft climb", climb2);
459
wpt->altitude = 18000;
460
waypoints.push_back(wpt);
680
// /*******************************************************************
682
// * initialize the Aircraft at the parking location
683
// ******************************************************************/
684
// void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep,
685
// FGAirport *arr, double latitude,
686
// double longitude, double speed,
689
// double wind_speed;
690
// double wind_heading;
692
// double lat, lon, az;
693
// double lat2, lon2, az2;
697
// wpt = new waypoint;
698
// wpt->name = "Cruise"; //wpt_node->getStringValue("name", "END");
699
// wpt->latitude = latitude;
700
// wpt->longitude = longitude;
701
// wpt->altitude = alt;
702
// wpt->speed = speed;
703
// wpt->crossat = -10000;
704
// wpt->gear_down = false;
705
// wpt->flaps_down= false;
706
// wpt->finished = false;
707
// wpt->on_ground = false;
708
// waypoints.push_back(wpt);
711
// // should be changed dynamically to allow "gen" and "mil"
712
// arr->getDynamics()->getActiveRunway("com", 2, activeRunway);
713
// if (!(globals->get_runways()->search(arr->getId(),
717
// SG_LOG(SG_INPUT, SG_ALERT, "Failed to find runway " <<
719
// " at airport " << arr->getId());
722
// heading = rwy->headingDeg();
723
// azimuth = heading + 180.0;
724
// while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
727
// geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
729
// &lat2, &lon2, &az2 );
730
// wpt = new waypoint;
731
// wpt->name = "BOD";
732
// wpt->latitude = lat2;
733
// wpt->longitude = lon2;
734
// wpt->altitude = alt;
735
// wpt->speed = speed;
736
// wpt->crossat = alt;
737
// wpt->gear_down = false;
738
// wpt->flaps_down= false;
739
// wpt->finished = false;
740
// wpt->on_ground = false;
741
// waypoints.push_back(wpt);
744
466
/*******************************************************************
746
468
* initialize the Aircraft at the parking location
747
469
******************************************************************/
748
void FGAIFlightPlan::createDecent(FGAirport *apt, const string &fltType)
470
void FGAIFlightPlan::createDecent(FGAIAircraft *ac, FGAirport *apt, const string &fltType)
751
472
// Ten thousand ft. Slowing down to 240 kts
754
double lat2, lon2, az2;
474
double vDecent = ac->getPerformance()->vDescent();
475
double vApproach = ac->getPerformance()->vApproach();
759
477
//Beginning of Decent
761
479
// allow "mil" and "gen" as well
762
480
string rwyClass = getRunwayClassFromTrafficType(fltType);
763
apt->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway);
481
double heading = ac->getTrafficRef()->getCourse();
482
apt->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway, heading);
764
483
rwy = apt->getRunwayByIdent(activeRunway);
766
heading = rwy->headingDeg();
767
azimuth = heading + 180.0;
768
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
769
geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
771
&lat2, &lon2, &az2 );
774
wpt->name = "Dec 10000ft"; //wpt_node->getStringValue("name", "END");
775
wpt->latitude = lat2;
776
wpt->longitude = lon2;
777
wpt->altitude = apt->getElevation();
485
SGGeod descent1 = rwy->pointOnCenterline(-100000); // 100km out
486
wpt = createInAir(ac, "Dec 10000ft", descent1, apt->getElevation(), vDecent);
779
487
wpt->crossat = 10000;
780
wpt->gear_down = false;
781
wpt->flaps_down= false;
782
wpt->finished = false;
783
wpt->on_ground = false;
785
488
waypoints.push_back(wpt);
787
490
// Three thousand ft. Slowing down to 160 kts
788
geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
790
&lat2, &lon2, &az2 );
792
wpt->name = "DEC 3000ft"; //wpt_node->getStringValue("name", "END");
793
wpt->latitude = lat2;
794
wpt->longitude = lon2;
795
wpt->altitude = apt->getElevation();
491
SGGeod descent2 = rwy->pointOnCenterline(-8*SG_NM_TO_METER); // 8nm out
492
wpt = createInAir(ac, "DEC 3000ft", descent2, apt->getElevation(), vApproach);
797
493
wpt->crossat = 3000;
798
494
wpt->gear_down = true;
799
495
wpt->flaps_down= true;
800
wpt->finished = false;
801
wpt->on_ground = false;
803
496
waypoints.push_back(wpt);
805
498
/*******************************************************************
807
500
* initialize the Aircraft at the parking location
808
501
******************************************************************/
809
void FGAIFlightPlan::createLanding(FGAirport *apt)
502
void FGAIFlightPlan::createLanding(FGAIAircraft *ac, FGAirport *apt)
811
// Ten thousand ft. Slowing down to 150 kts
814
double lat2, lon2, az2;
504
double vTouchdown = ac->getPerformance()->vTouchdown();
505
double vTaxi = ac->getPerformance()->vTaxi();
820
heading = rwy->headingDeg();
821
azimuth = heading + 180.0;
822
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
508
double aptElev = apt->getElevation();
824
509
//Runway Threshold
825
geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
826
rwy->lengthM() *0.45,
827
&lat2, &lon2, &az2 );
829
wpt->name = "Threshold"; //wpt_node->getStringValue("name", "END");
830
wpt->latitude = lat2;
831
wpt->longitude = lon2;
832
wpt->altitude = apt->getElevation();
834
wpt->crossat = apt->getElevation();
835
wpt->gear_down = true;
836
wpt->flaps_down= true;
837
wpt->finished = false;
838
wpt->on_ground = true;
510
wpt = createOnGround(ac, "Threshold", rwy->threshold(), aptElev, vTouchdown);
511
wpt->crossat = apt->getElevation();
840
512
waypoints.push_back(wpt);
842
//Full stop at the runway centerpoint
843
geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
844
rwy->lengthFt() *0.45,
845
&lat2, &lon2, &az2 );
847
wpt->name = "Center"; //wpt_node->getStringValue("name", "END");
848
wpt->latitude = rwy->latitude();
849
wpt->longitude = rwy->longitude();
850
wpt->altitude = apt->getElevation();
852
wpt->crossat = -10000;
853
wpt->gear_down = true;
854
wpt->flaps_down= true;
855
wpt->finished = false;
856
wpt->on_ground = true;
515
wpt = createOnGround(ac, "Center", rwy->geod(), aptElev, vTaxi*2);
858
516
waypoints.push_back(wpt);
860
geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading,
861
rwy->lengthM() *0.45,
862
&lat2, &lon2, &az2 );
864
wpt->name = "Threshold"; //wpt_node->getStringValue("name", "END");
865
wpt->latitude = lat2;
866
wpt->longitude = lon2;
867
wpt->altitude = apt->getElevation();
518
SGGeod rollOut = rwy->pointOnCenterline(rwy->lengthM() * 0.9);
519
wpt = createOnGround(ac, "Roll Out", rollOut, aptElev, vTaxi);
869
520
wpt->crossat = apt->getElevation();
870
wpt->gear_down = true;
871
wpt->flaps_down= true;
872
wpt->finished = false;
873
wpt->on_ground = true;
875
521
waypoints.push_back(wpt);