]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/AIFlightPlanCreate.cxx
Fix line endings
[flightgear.git] / src / AIModel / AIFlightPlanCreate.cxx
1 /******************************************************************************
2  * AIFlightPlanCreate.cxx
3  * Written by Durk Talsma, started May, 2004.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *
19  *
20  **************************************************************************/
21 #include "AIFlightPlan.hxx"
22 #include <simgear/math/sg_geodesy.hxx>
23 #include <Airports/runways.hxx>
24
25 #include <Environment/environment_mgr.hxx>
26 #include <Environment/environment.hxx>
27
28
29 /* FGAIFlightPlan::create()
30  * dynamically create a flight plan for AI traffic, based on data provided by the
31  * Traffic Manager, when reading a filed flightplan failes. (DT, 2004/07/10) 
32  *
33  * This is the top-level function, and the only one that publicly available.
34  *
35  */ 
36
37
38 // Check lat/lon values during initialization;
39 void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, int legNr, double alt, double speed, 
40                             double latitude, double longitude, bool firstFlight,
41                             double radius, const string& fltType, const string& aircraftType, const string& airline)
42
43   int currWpt = wpt_iterator - waypoints.begin();
44   switch(legNr)
45     {
46     case 1:
47       //cerr << "Creating Push_Back" << endl;
48       createPushBack(firstFlight,dep, latitude, longitude, radius, fltType, aircraftType, airline);
49       //cerr << "Done" << endl;
50       break;
51     case 2: 
52       //cerr << "Creating Taxi" << endl;
53       createTaxi(firstFlight, 1, dep, latitude, longitude, radius, fltType, aircraftType, airline);
54       break;
55     case 3: 
56       //cerr << "Creating TAkeoff" << endl;
57       createTakeOff(firstFlight, dep, speed);
58       break;
59     case 4: 
60       //cerr << "Creating Climb" << endl;
61       createClimb(firstFlight, dep, speed, alt);
62       break;
63     case 5: 
64       //cerr << "Creating Cruise" << endl;
65       createCruise(firstFlight, dep,arr, latitude, longitude, speed, alt);
66       break;
67     case 6: 
68       //cerr << "Creating Decent" << endl;
69       createDecent(arr);
70       break;
71     case 7: 
72       //cerr << "Creating Landing" << endl;
73       createLanding(arr);
74       break;
75     case 8: 
76       //cerr << "Creating Taxi 2" << endl;
77       createTaxi(false, 2, arr, latitude, longitude, radius, fltType, aircraftType, airline);
78       break;
79     case 9: 
80       //cerr << "Creating Parking" << endl;
81       createParking(arr);
82       break;
83     default:
84       //exit(1);
85       cerr << "Unknown case: " << legNr << endl;
86     }
87   wpt_iterator = waypoints.begin()+currWpt;
88   leg++;
89 }
90
91 /*******************************************************************
92  * createPushBack
93  * initialize the Aircraft at the parking location
94  ******************************************************************/
95 void FGAIFlightPlan::createPushBack(bool firstFlight, FGAirport *dep, 
96                                     double latitude,
97                                     double longitude,
98                                     double radius,
99                                     const string& fltType,
100                                     const string& aircraftType,
101                                     const string& airline)
102 {
103   double heading;
104   double lat;
105   double lon;
106   double lat2;
107   double lon2;
108   double az2;
109   
110   //int currWpt = wpt_iterator - waypoints.begin();
111   // Erase all existing waypoints.
112   //resetWaypoints();
113   
114   // We only need to get a valid parking if this is the first leg. 
115   // Otherwise use the current aircraft position.
116   if (firstFlight)
117     {
118       if (!(dep->getDynamics()->getAvailableParking(&lat, &lon, 
119                                                     &heading, &gateId, 
120                                                     radius, fltType, 
121                                                     aircraftType, airline)))
122         {
123           cerr << "Could not find parking " << endl;
124         }
125     }
126   else
127     {
128       dep->getDynamics()->getParking(gateId, &lat, &lon, &heading);
129       //lat     = latitude;
130       //lon     = longitude;
131       //heading = getHeading();
132     }
133   heading += 180.0;
134   if (heading > 360)
135     heading -= 360;
136   waypoint *wpt = new waypoint;
137   wpt->name      = "park";
138   wpt->latitude  = lat;
139   wpt->longitude = lon;
140   wpt->altitude  = dep->getElevation();
141   wpt->speed     = -10; 
142   wpt->crossat   = -10000;
143   wpt->gear_down = true;
144   wpt->flaps_down= true;
145   wpt->finished  = false;
146   wpt->on_ground = true;
147   waypoints.push_back(wpt); 
148   
149   // Add park twice, because it uses park once for initialization and once
150   // to trigger the departure ATC message 
151   geo_direct_wgs_84 ( 0, lat, lon, heading, 
152                       10, 
153                       &lat2, &lon2, &az2 );
154   wpt = new waypoint;
155   wpt->name      = "park2";
156   wpt->latitude  = lat2;
157   wpt->longitude = lon2;
158   wpt->altitude  = dep->getElevation();
159   wpt->speed     = -10; 
160   wpt->crossat   = -10000;
161   wpt->gear_down = true;
162   wpt->flaps_down= true;
163   wpt->finished  = false;
164   wpt->on_ground = true;
165   waypoints.push_back(wpt); 
166   geo_direct_wgs_84 ( 0, lat, lon, heading, 
167                       radius,                 // push back one entire aircraft radius
168                       &lat2, &lon2, &az2 );
169   wpt = new waypoint;
170   wpt->name      = "taxiStart";
171   wpt->latitude  = lat2;
172   wpt->longitude = lon2;
173   wpt->altitude  = dep->getElevation();
174   wpt->speed     = 10; 
175   wpt->crossat   = -10000;
176   wpt->gear_down = true;
177   wpt->flaps_down= true;
178   wpt->finished  = false;
179   wpt->on_ground = true;
180   waypoints.push_back(wpt); 
181
182   
183 }
184
185 /*******************************************************************
186  * createCreate Taxi. 
187  * initialize the Aircraft at the parking location
188  ******************************************************************/
189 void FGAIFlightPlan::createTaxi(bool firstFlight, int direction, FGAirport *apt, double latitude, double longitude, double radius, const string& fltType, const string& acType, const string& airline)
190 {
191   double wind_speed;
192   double wind_heading;
193   double heading;
194   //FGRunway rwy;
195   double lat, lon, az;
196   double lat2, lon2, az2;
197   //int direction;
198   waypoint *wpt;
199
200   // Erase all existing waypoints.
201   //   wpt_vector_iterator i= waypoints.begin();
202   //resetWaypoints();
203   //int currWpt = wpt_iterator - waypoints.begin();
204   if (direction == 1)
205     {
206       //string name;
207       // "NOTE: this is currently fixed to "com" for commercial traffic
208       // Should be changed to be used dynamically to allow "gen" and "mil"
209       // as well
210       apt->getDynamics()->getActiveRunway("com", 1, activeRunway);
211       if (!(globals->get_runways()->search(apt->getId(), 
212                                             activeRunway, 
213                                             &rwy)))
214         {
215           cout << "Failed to find runway for " << apt->getId() << endl;
216           // Hmm, how do we handle a potential error like this?
217           exit(1);
218         }
219       //string test;
220       //apt->getActiveRunway(string("com"), 1, test);
221       //exit(1);
222       
223       heading = rwy._heading;
224       double azimuth = heading + 180.0;
225       while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
226       geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
227                           rwy._length * SG_FEET_TO_METER * 0.5 - 5.0,
228                           &lat2, &lon2, &az2 );
229       if (apt->getDynamics()->getGroundNetwork()->exists())
230         {
231           intVec ids;
232           int runwayId = apt->getDynamics()->getGroundNetwork()->findNearestNode(lat2, lon2);
233           //int currId   = apt->getGroundNetwork()->findNearestNode(latitude,longitude);
234           //exit(1);
235           
236           // A negative gateId indicates an overflow parking, use a
237           // fallback mechanism for this. 
238           // Starting from gate 0 is a bit of a hack...
239           FGTaxiRoute route;
240           if (gateId >= 0)
241             route = apt->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, runwayId);
242           else
243             route = apt->getDynamics()->getGroundNetwork()->findShortestRoute(0, runwayId);
244           intVecIterator i;
245           //cerr << "creating route : ";
246           // No route found: go from gate directly to runway
247           if (route.empty()) {
248             //Add the runway startpoint;
249             wpt = new waypoint;
250             wpt->name      = "Airport Center";
251             wpt->latitude  = latitude;
252             wpt->longitude = longitude;
253             wpt->altitude  = apt->getElevation();
254             wpt->speed     = 15; 
255             wpt->crossat   = -10000;
256             wpt->gear_down = true;
257             wpt->flaps_down= true;
258             wpt->finished  = false;
259             wpt->on_ground = true;
260             waypoints.push_back(wpt);
261             
262             //Add the runway startpoint;
263             wpt = new waypoint;
264             wpt->name      = "Runway Takeoff";
265             wpt->latitude  = lat2;
266             wpt->longitude = lon2;
267             wpt->altitude  = apt->getElevation();
268             wpt->speed     = 15; 
269             wpt->crossat   = -10000;
270             wpt->gear_down = true;
271             wpt->flaps_down= true;
272             wpt->finished  = false;
273             wpt->on_ground = true;
274             waypoints.push_back(wpt);   
275           } else {
276             int node;
277             route.first();
278             while(route.next(&node))
279               {
280                 //i = ids.end()-1;
281                 //cerr << "Creating Node: " << node << endl;
282                 FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
283                 //ids.pop_back();  
284                 wpt = new waypoint;
285                 wpt->name      = "taxiway"; // fixme: should be the name of the taxiway
286                 wpt->latitude  = tn->getLatitude();
287                 wpt->longitude = tn->getLongitude();
288                 wpt->altitude  = apt->getElevation(); // should maybe be tn->elev too
289                 wpt->speed     = 15; 
290                 wpt->crossat   = -10000;
291                 wpt->gear_down = true;
292                 wpt->flaps_down= true;
293                 wpt->finished  = false;
294                 wpt->on_ground = true;
295                 waypoints.push_back(wpt);
296               }
297             cerr << endl;
298           }
299           //exit(1);
300         }
301       else 
302         {
303           //Add the runway startpoint;
304           wpt = new waypoint;
305           wpt->name      = "Airport Center";
306           wpt->latitude  = apt->getLatitude();
307           wpt->longitude = apt->getLongitude();
308           wpt->altitude  = apt->getElevation();
309           wpt->speed     = 15; 
310           wpt->crossat   = -10000;
311           wpt->gear_down = true;
312           wpt->flaps_down= true;
313           wpt->finished  = false;
314           wpt->on_ground = true;
315           waypoints.push_back(wpt);
316           
317           //Add the runway startpoint;
318           wpt = new waypoint;
319           wpt->name      = "Runway Takeoff";
320           wpt->latitude  = lat2;
321           wpt->longitude = lon2;
322           wpt->altitude  = apt->getElevation();
323           wpt->speed     = 15; 
324           wpt->crossat   = -10000;
325           wpt->gear_down = true;
326           wpt->flaps_down= true;
327           wpt->finished  = false;
328           wpt->on_ground = true;
329           waypoints.push_back(wpt);
330           //wpt = new waypoint;
331           //wpt->finished = false;
332           //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
333         }
334     }
335   else  // Landing taxi
336     {
337       //string name;
338       // "NOTE: this is currently fixed to "com" for commercial traffic
339       // Should be changed to be used dynamically to allow "gen" and "mil"
340       // as well
341       //apt->getActiveRunway("com", 1, name);
342       //if (!(globals->get_runways()->search(apt->getId(), 
343       //                                    name, 
344       //                            &rwy)))
345       //{//
346       //cout << "Failed to find runway for " << apt->getId() << endl;
347       // Hmm, how do we handle a potential error like this?
348       // exit(1);
349       //        }
350       //string test;
351       //apt->getActiveRunway(string("com"), 1, test);
352       //exit(1);
353       
354       //heading = rwy._heading;
355       //double azimuth = heading + 180.0;
356       //while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
357       //geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
358       //                  rwy._length * SG_FEET_TO_METER * 0.5 - 5.0,
359       //                  &lat2, &lon2, &az2 );
360       apt->getDynamics()->getAvailableParking(&lat, &lon, &heading, &gateId, radius, fltType, acType, airline);
361       heading += 180.0;
362       if (heading > 360)
363         heading -= 360;
364       geo_direct_wgs_84 ( 0, lat, lon, heading, 
365                           100,
366                           &lat2, &lon2, &az2 );
367       double lat3 = (*(waypoints.end()-1))->latitude;
368       double lon3 = (*(waypoints.end()-1))->longitude;
369       cerr << (*(waypoints.end()-1))->name << endl;
370       if (apt->getDynamics()->getGroundNetwork()->exists())
371         {
372           intVec ids;
373           int runwayId = apt->getDynamics()->getGroundNetwork()->findNearestNode(lat3, lon3);
374           //int currId   = apt->getGroundNetwork()->findNearestNode(latitude,longitude);
375           //exit(1);
376           
377           // A negative gateId indicates an overflow parking, use a
378           // fallback mechanism for this. 
379           // Starting from gate 0 is a bit of a hack...
380           FGTaxiRoute route;
381           if (gateId >= 0)
382             route = apt->getDynamics()->getGroundNetwork()->findShortestRoute(runwayId, gateId);
383           else
384             route = apt->getDynamics()->getGroundNetwork()->findShortestRoute(runwayId, 0);
385           intVecIterator i;
386           //cerr << "creating route : ";
387           // No route found: go from gate directly to runway
388           if (route.empty()) {
389             //Add the runway startpoint;
390             wpt = new waypoint;
391             wpt->name      = "Airport Center";
392             wpt->latitude  = latitude;
393             wpt->longitude = longitude;
394             wpt->altitude  = apt->getElevation();
395             wpt->speed     = 15; 
396             wpt->crossat   = -10000;
397             wpt->gear_down = true;
398             wpt->flaps_down= true;
399             wpt->finished  = false;
400             wpt->on_ground = true;
401             waypoints.push_back(wpt);
402             
403             //Add the runway startpoint;
404             wpt = new waypoint;
405             wpt->name      = "Runway Takeoff";
406             wpt->latitude  = lat2;
407             wpt->longitude = lon2;
408             wpt->altitude  = apt->getElevation();
409             wpt->speed     = 15; 
410             wpt->crossat   = -10000;
411             wpt->gear_down = true;
412             wpt->flaps_down= true;
413             wpt->finished  = false;
414             wpt->on_ground = true;
415             waypoints.push_back(wpt);   
416           } else {
417             int node;
418             route.first();
419             while(route.next(&node))
420               {
421                 //i = ids.end()-1;
422                 //cerr << "Creating Node: " << node << endl;
423                 FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
424                 //ids.pop_back();  
425                 wpt = new waypoint;
426                 wpt->name      = "taxiway"; // fixme: should be the name of the taxiway
427                 wpt->latitude  = tn->getLatitude();
428                 wpt->longitude = tn->getLongitude();
429                 wpt->altitude  = apt->getElevation(); // should maybe be tn->elev too
430                 wpt->speed     = 15; 
431                 wpt->crossat   = -10000;
432                 wpt->gear_down = true;
433                 wpt->flaps_down= true;
434                 wpt->finished  = false;
435                 wpt->on_ground = true;
436                 waypoints.push_back(wpt);
437               }
438             cerr << endl;
439           }
440           //exit(1);
441         }
442       else
443         {
444           //Add the runway startpoint;
445           wpt = new waypoint;
446           wpt->name      = "Airport Center";
447           wpt->latitude  = apt->getLatitude();
448           wpt->longitude = apt->getLongitude();
449           wpt->altitude  = apt->getElevation();
450           wpt->speed     = 15; 
451           wpt->crossat   = -10000;
452           wpt->gear_down = true;
453           wpt->flaps_down= true;
454           wpt->finished  = false;
455           wpt->on_ground = true;
456           waypoints.push_back(wpt);
457           
458         }
459
460
461
462
463       // Add the final destination waypoint
464       wpt = new waypoint;
465       wpt->name      = "Begin Parking"; //apt->getId(); //wpt_node->getStringValue("name", "END");
466       wpt->latitude  = lat2;
467       wpt->longitude = lon2;
468       wpt->altitude  = apt->getElevation();
469       wpt->speed     = 15; 
470       wpt->crossat   = -10000;
471       wpt->gear_down = true;
472       wpt->flaps_down= true;
473       wpt->finished  = false;
474       wpt->on_ground = true;
475       waypoints.push_back(wpt); 
476
477      
478     }
479   // wpt_iterator = waypoints.begin();
480   //if (!firstFlight)
481   // wpt_iterator++; 
482   //wpt_iterator = waypoints.begin()+currWpt;
483 }
484
485 /*******************************************************************
486  * CreateTakeOff 
487  * initialize the Aircraft at the parking location
488  ******************************************************************/
489 void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double speed)
490 {
491   double wind_speed;
492   double wind_heading;
493   double heading;
494   //FGRunway rwy;
495   double lat, lon, az;
496   double lat2, lon2, az2;
497   //int direction;
498   waypoint *wpt;
499   
500   
501   // Erase all existing waypoints.
502   // wpt_vector_iterator i= waypoints.begin();
503   //while(waypoints.begin() != waypoints.end())
504   //  {      
505   //    delete *(i);
506   //    waypoints.erase(i);
507   //  }
508   //resetWaypoints();
509   
510   
511   // Get the current active runway, based on code from David Luff
512   // This should actually be unified and extended to include 
513   // Preferential runway use schema's 
514   if (firstFlight)
515     {
516       //string name;
517        // "NOTE: this is currently fixed to "com" for commercial traffic
518       // Should be changed to be used dynamically to allow "gen" and "mil"
519       // as well
520       apt->getDynamics()->getActiveRunway("com", 1, activeRunway);
521         if (!(globals->get_runways()->search(apt->getId(), 
522                                               activeRunway, 
523                                               &rwy)))
524           {
525             cout << "Failed to find runway for " << apt->getId() << endl;
526             // Hmm, how do we handle a potential error like this?
527             exit(1);
528           }
529         //string test;
530       //apt->getActiveRunway(string("com"), 1, test);
531       //exit(1);
532     }
533   
534   heading = rwy._heading;
535   double azimuth = heading + 180.0;
536   while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
537   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
538                       rwy._length * SG_FEET_TO_METER * 0.5 - 105.0,
539                       &lat2, &lon2, &az2 );
540   wpt = new waypoint; 
541   wpt->name      = "accel"; 
542   wpt->latitude  = lat2; 
543   wpt->longitude = lon2; 
544   wpt->altitude  = apt->getElevation();
545   wpt->speed     = speed;  
546   wpt->crossat   = -10000;
547   wpt->gear_down = true;
548   wpt->flaps_down= true;
549   wpt->finished  = false;
550   wpt->on_ground = true;
551   waypoints.push_back(wpt); 
552   
553   lat = lat2;
554   lon = lon2;
555   az  = az2;
556   
557   //Next: the Start of Climb
558   geo_direct_wgs_84 ( 0, lat, lon, heading, 
559   2560 * SG_FEET_TO_METER,
560   &lat2, &lon2, &az2 );
561   
562   wpt = new waypoint;
563   wpt->name      = "SOC";
564   wpt->latitude  = lat2;
565   wpt->longitude = lon2;
566   wpt->altitude  = apt->getElevation()+3000;
567   wpt->speed     = speed; 
568   wpt->crossat   = -10000;
569   wpt->gear_down = true;
570   wpt->flaps_down= true;
571   wpt->finished  = false;
572   wpt->on_ground = false;
573   waypoints.push_back(wpt);
574   //  waypoints.push_back(wpt);
575   //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
576   // wpt_iterator = waypoints.begin();
577   //if (!firstFlight)
578   // wpt_iterator++;
579 }
580  
581 /*******************************************************************
582  * CreateClimb
583  * initialize the Aircraft at the parking location
584  ******************************************************************/
585 void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed, double alt)
586 {
587   double wind_speed;
588   double wind_heading;
589   double heading;
590   //FGRunway rwy;
591   double lat, lon, az;
592   double lat2, lon2, az2;
593   //int direction;
594   waypoint *wpt;
595
596   // Erase all existing waypoints.
597   // wpt_vector_iterator i= waypoints.begin();
598   //while(waypoints.begin() != waypoints.end())
599   //  {      
600   //    delete *(i);
601   //    waypoints.erase(i);
602   //  }
603   //resetWaypoints();
604   
605   
606   // Get the current active runway, based on code from David Luff
607   // This should actually be unified and extended to include 
608   // Preferential runway use schema's 
609   if (firstFlight)
610     {
611       //string name;
612       // "NOTE: this is currently fixed to "com" for commercial traffic
613       // Should be changed to be used dynamically to allow "gen" and "mil"
614       // as well
615       apt->getDynamics()->getActiveRunway("com", 1, activeRunway);
616         if (!(globals->get_runways()->search(apt->getId(), 
617                                               activeRunway, 
618                                               &rwy)))
619           {
620             cout << "Failed to find runway for " << apt->getId() << endl;
621             // Hmm, how do we handle a potential error like this?
622             exit(1);
623           }
624         //string test;
625         //apt->getActiveRunway(string("com"), 1, test);
626       //exit(1);
627     }
628   
629   
630   heading = rwy._heading;
631   double azimuth = heading + 180.0;
632   while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
633   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, 
634                       10*SG_NM_TO_METER,
635                       &lat2, &lon2, &az2 );
636   wpt = new waypoint;
637   wpt->name      = "10000ft climb";
638   wpt->latitude  = lat2;
639   wpt->longitude = lon2;
640   wpt->altitude  = 10000;
641   wpt->speed     = speed; 
642   wpt->crossat   = -10000;
643   wpt->gear_down = true;
644   wpt->flaps_down= true;
645   wpt->finished  = false;
646   wpt->on_ground = false;
647   waypoints.push_back(wpt); 
648   
649
650   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, 
651                       20*SG_NM_TO_METER,
652                       &lat2, &lon2, &az2 );
653   wpt = new waypoint;
654   wpt->name      = "18000ft climb";
655   wpt->latitude  = lat2;
656   wpt->longitude = lon2;
657   wpt->altitude  = 18000;
658   wpt->speed     = speed; 
659   wpt->crossat   = -10000;
660   wpt->gear_down = true;
661   wpt->flaps_down= true;
662   wpt->finished  = false;
663   wpt->on_ground = false;
664   waypoints.push_back(wpt); 
665   //waypoints.push_back(wpt); 
666   //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
667   // wpt_iterator = waypoints.begin();
668   //if (!firstFlight)
669   // wpt_iterator++;
670 }
671
672
673 /*******************************************************************
674  * CreateCruise
675  * initialize the Aircraft at the parking location
676  ******************************************************************/
677 void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep, FGAirport *arr, double latitude, double longitude, double speed, double alt)
678 {
679   double wind_speed;
680   double wind_heading;
681   double heading;
682   //FGRunway rwy;
683   double lat, lon, az;
684   double lat2, lon2, az2;
685   double azimuth;
686   //int direction;
687   waypoint *wpt;
688
689   // Erase all existing waypoints.
690   // wpt_vector_iterator i= waypoints.begin();
691   //while(waypoints.begin() != waypoints.end())
692   //  {      
693   //    delete *(i);
694   //    waypoints.erase(i);
695   //  }
696   //resetWaypoints();
697
698   wpt = new waypoint;
699   wpt->name      = "Cruise"; //wpt_node->getStringValue("name", "END");
700   wpt->latitude  = latitude;
701   wpt->longitude = longitude;
702   wpt->altitude  = alt;
703   wpt->speed     = speed; 
704   wpt->crossat   = -10000;
705   wpt->gear_down = false;
706   wpt->flaps_down= false;
707   wpt->finished  = false;
708   wpt->on_ground = false;
709   waypoints.push_back(wpt); 
710   //Beginning of Decent
711  
712   //string name;
713   // should be changed dynamically to allow "gen" and "mil"
714   arr->getDynamics()->getActiveRunway("com", 2, activeRunway);
715   if (!(globals->get_runways()->search(arr->getId(), 
716                                        activeRunway, 
717                                        &rwy)))
718     {
719       cout << "Failed to find runway for " << arr->getId() << endl;
720       // Hmm, how do we handle a potential error like this?
721       exit(1);
722     }
723   //string test;
724   //arr->getActiveRunway(string("com"), 1, test);
725   //exit(1);
726   
727   //cerr << "Altitude = " << alt << endl;
728   //cerr << "Done" << endl;
729   //if (arr->getId() == "EHAM")
730   //  {
731   //    cerr << "Creating cruise to EHAM " << latitude << " " << longitude << endl;
732   //  }
733   heading = rwy._heading;
734   azimuth = heading + 180.0;
735   while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
736   
737   
738   // Note: This places us at the location of the active 
739   // runway during initial cruise. This needs to be 
740   // fixed later. 
741   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
742                       110000,
743                       &lat2, &lon2, &az2 );
744   wpt = new waypoint;
745   wpt->name      = "BOD"; //wpt_node->getStringValue("name", "END");
746   wpt->latitude  = lat2;
747   wpt->longitude = lon2;
748   wpt->altitude  = alt;
749   wpt->speed     = speed; 
750   wpt->crossat   = alt;
751   wpt->gear_down = false;
752   wpt->flaps_down= false;
753   wpt->finished  = false;
754   wpt->on_ground = false;
755   waypoints.push_back(wpt); 
756   //waypoints.push_back(wpt);
757   //waypoints.push_back(wpt);  // add one more to prevent a segfault.  
758   //wpt_iterator = waypoints.begin();
759   //if (!firstFlight)
760   // wpt_iterator++;
761 }
762
763 /*******************************************************************
764  * CreateDecent
765  * initialize the Aircraft at the parking location
766  ******************************************************************/
767 void FGAIFlightPlan::createDecent(FGAirport *apt)
768 {
769
770   // Ten thousand ft. Slowing down to 240 kts
771   double wind_speed;
772   double wind_heading;
773   double heading;
774   //FGRunway rwy;
775   double lat, lon, az;
776   double lat2, lon2, az2;
777   double azimuth;
778   //int direction;
779   waypoint *wpt;
780
781   //// Erase all existing waypoints.
782   // wpt_vector_iterator i= waypoints.begin();
783   //while(waypoints.begin() != waypoints.end())
784   //  {      
785   //    delete *(i);
786   //    waypoints.erase(i);
787   //  }
788   //resetWaypoints();
789
790   //Beginning of Decent
791   //string name;
792   // allow "mil" and "gen" as well
793   apt->getDynamics()->getActiveRunway("com", 2, activeRunway);
794     if (!(globals->get_runways()->search(apt->getId(), 
795                                           activeRunway, 
796                                           &rwy)))
797       {
798         cout << "Failed to find runway for " << apt->getId() << endl;
799         // Hmm, how do we handle a potential error like this?
800         exit(1);
801       }
802     //string test;
803     //apt->getActiveRunway(string("com"), 1, test);
804   //exit(1);
805
806   //cerr << "Done" << endl;
807   heading = rwy._heading;
808   azimuth = heading + 180.0;
809   while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
810   
811   
812   
813   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
814                       100000,
815                       &lat2, &lon2, &az2 );
816   
817   wpt = new waypoint;
818   wpt->name      = "Dec 10000ft"; //wpt_node->getStringValue("name", "END");
819   wpt->latitude  = lat2;
820   wpt->longitude = lon2;
821   wpt->altitude  = apt->getElevation();
822   wpt->speed     = 240; 
823   wpt->crossat   = 10000;
824   wpt->gear_down = false;
825   wpt->flaps_down= false;
826   wpt->finished  = false;
827   wpt->on_ground = false;
828   waypoints.push_back(wpt);  
829
830   // Three thousand ft. Slowing down to 160 kts
831   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
832                      8*SG_NM_TO_METER,
833                      &lat2, &lon2, &az2 );
834   wpt = new waypoint;
835   wpt->name      = "DEC 3000ft"; //wpt_node->getStringValue("name", "END");
836   wpt->latitude  = lat2;
837   wpt->longitude = lon2;
838   wpt->altitude  = apt->getElevation();
839   wpt->speed     = 160; 
840   wpt->crossat   = 3000;
841   wpt->gear_down = true;
842   wpt->flaps_down= true;
843   wpt->finished  = false;
844   wpt->on_ground = false;
845   waypoints.push_back(wpt);
846   //waypoints.push_back(wpt);
847   //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
848   //wpt_iterator = waypoints.begin();
849   //wpt_iterator++;
850   //if (apt->getId() == "EHAM")
851   //  {
852   //    cerr << "Created Decend to EHAM " << lat2 << " " << lon2 << ": Runway = " << rwy._rwy_no 
853   //       << "heading " << heading << endl;
854   //  }
855 }
856 /*******************************************************************
857  * CreateLanding
858  * initialize the Aircraft at the parking location
859  ******************************************************************/
860 void FGAIFlightPlan::createLanding(FGAirport *apt)
861 {
862   // Ten thousand ft. Slowing down to 240 kts
863   double wind_speed;
864   double wind_heading;
865   double heading;
866   //FGRunway rwy;
867   double lat, lon, az;
868   double lat2, lon2, az2;
869   double azimuth;
870   //int direction;
871   waypoint *wpt;
872
873   
874   heading = rwy._heading;
875   azimuth = heading + 180.0;
876   while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
877
878   //Runway Threshold
879  geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
880                      rwy._length*0.45 * SG_FEET_TO_METER,
881                      &lat2, &lon2, &az2 );
882   wpt = new waypoint;
883   wpt->name      = "Threshold"; //wpt_node->getStringValue("name", "END");
884   wpt->latitude  = lat2;
885   wpt->longitude = lon2;
886   wpt->altitude  = apt->getElevation();
887   wpt->speed     = 150; 
888   wpt->crossat   = apt->getElevation();
889   wpt->gear_down = true;
890   wpt->flaps_down= true;
891   wpt->finished  = false;
892   wpt->on_ground = true;
893   waypoints.push_back(wpt); 
894
895  //Full stop at the runway centerpoint
896  geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
897                      rwy._length*0.45,
898                       &lat2, &lon2, &az2 );
899   wpt = new waypoint;
900   wpt->name      = "Center"; //wpt_node->getStringValue("name", "END");
901   wpt->latitude  = rwy._lat;
902   wpt->longitude = rwy._lon;
903   wpt->altitude  = apt->getElevation();
904   wpt->speed     = 30; 
905   wpt->crossat   = -10000;
906   wpt->gear_down = true;
907   wpt->flaps_down= true;
908   wpt->finished  = false;
909   wpt->on_ground = true;
910   waypoints.push_back(wpt);
911
912  geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, 
913                      rwy._length*0.45 * SG_FEET_TO_METER,
914                      &lat2, &lon2, &az2 );
915   wpt = new waypoint;
916   wpt->name      = "Threshold"; //wpt_node->getStringValue("name", "END");
917   wpt->latitude  = lat2;
918   wpt->longitude = lon2;
919   wpt->altitude  = apt->getElevation();
920   wpt->speed     = 15; 
921   wpt->crossat   = apt->getElevation();
922   wpt->gear_down = true;
923   wpt->flaps_down= true;
924   wpt->finished  = false;
925   wpt->on_ground = true;
926   waypoints.push_back(wpt); 
927   //waypoints.push_back(wpt); 
928   //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
929   //wpt_iterator = waypoints.begin();
930   //wpt_iterator++;
931
932   //if (apt->getId() == "EHAM")
933   //{
934   //  cerr << "Created Landing to EHAM " << lat2 << " " << lon2 << ": Runway = " << rwy._rwy_no 
935   //     << "heading " << heading << endl;
936   //}
937 }
938
939 /*******************************************************************
940  * CreateParking
941  * initialize the Aircraft at the parking location
942  ******************************************************************/
943 void FGAIFlightPlan::createParking(FGAirport *apt)
944 {
945   waypoint* wpt;
946   double lat;
947   double lon;
948   double heading;
949   apt->getDynamics()->getParking(gateId, &lat, &lon, &heading);
950   heading += 180.0;
951   if (heading > 360)
952     heading -= 360; 
953
954   // Erase all existing waypoints.
955   // wpt_vector_iterator i= waypoints.begin();
956   //while(waypoints.begin() != waypoints.end())
957   //  {      
958   //    delete *(i);
959   //    waypoints.erase(i);
960   //  }
961   //resetWaypoints();
962   // And finally one more named "END"
963   wpt = new waypoint;
964   wpt->name      = "END"; //wpt_node->getStringValue("name", "END");
965   wpt->latitude  = lat;
966   wpt->longitude = lon;
967   wpt->altitude  = 19;
968   wpt->speed     = 15; 
969   wpt->crossat   = -10000;
970   wpt->gear_down = true;
971   wpt->flaps_down= true;
972   wpt->finished  = false;
973   wpt->on_ground = true;
974   waypoints.push_back(wpt);
975   //waypoints.push_back(wpt);
976   //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
977   //wpt_iterator = waypoints.begin();
978   //wpt_iterator++;
979 }