]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/AIFlightPlanCreate.cxx
f800f52ca9fcdfd0335ea638a018d0a6dabe9301
[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, string fltType, string aircraftType, 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, 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, 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                                     string fltType,
100                                     string aircraftType,
101                                     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->getAvailableParking(&lat, &lon, &heading, &gateId, radius, fltType, aircraftType, airline)))
119         {
120           cerr << "Could not find parking " << endl;
121         }
122     }
123   else
124     {
125       dep->getParking(gateId, &lat, &lon, &heading);
126       //lat     = latitude;
127       //lon     = longitude;
128       //heading = getHeading();
129     }
130   heading += 180.0;
131   if (heading > 360)
132     heading -= 360;
133   waypoint *wpt = new waypoint;
134   wpt->name      = "park";
135   wpt->latitude  = lat;
136   wpt->longitude = lon;
137   wpt->altitude  = dep->getElevation();
138   wpt->speed     = -10; 
139   wpt->crossat   = -10000;
140   wpt->gear_down = true;
141   wpt->flaps_down= true;
142   wpt->finished  = false;
143   wpt->on_ground = true;
144   waypoints.push_back(wpt); 
145   
146   // Add park twice, because it uses park once for initialization and once
147   // to trigger the departure ATC message 
148   geo_direct_wgs_84 ( 0, lat, lon, heading, 
149                       10, 
150                       &lat2, &lon2, &az2 );
151   wpt = new waypoint;
152   wpt->name      = "park2";
153   wpt->latitude  = lat2;
154   wpt->longitude = lon2;
155   wpt->altitude  = dep->getElevation();
156   wpt->speed     = -10; 
157   wpt->crossat   = -10000;
158   wpt->gear_down = true;
159   wpt->flaps_down= true;
160   wpt->finished  = false;
161   wpt->on_ground = true;
162   waypoints.push_back(wpt); 
163   geo_direct_wgs_84 ( 0, lat, lon, heading, 
164                       100, 
165                       &lat2, &lon2, &az2 );
166   wpt = new waypoint;
167   wpt->name      = "taxiStart";
168   wpt->latitude  = lat2;
169   wpt->longitude = lon2;
170   wpt->altitude  = dep->getElevation();
171   wpt->speed     = 10; 
172   wpt->crossat   = -10000;
173   wpt->gear_down = true;
174   wpt->flaps_down= true;
175   wpt->finished  = false;
176   wpt->on_ground = true;
177   waypoints.push_back(wpt); 
178
179   //wpt = new waypoint;
180   //wpt->name = "END";
181   //wpt->finished = false;
182   //waypoints.push_back(wpt);  // add one more to prevent a segfault.  
183   //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
184   //wpt_iterator = waypoints.begin();
185   //if (!firstFlight)
186   //  wpt_iterator++;
187   //wpt_iterator = waypoints.begin()+currWpt;
188 }
189
190 /*******************************************************************
191  * createCreate Taxi. 
192  * initialize the Aircraft at the parking location
193  ******************************************************************/
194 void FGAIFlightPlan::createTaxi(bool firstFlight, int direction, FGAirport *apt, double radius, string fltType, string acType, string airline)
195 {
196   double wind_speed;
197   double wind_heading;
198   double heading;
199   //FGRunway rwy;
200   double lat, lon, az;
201   double lat2, lon2, az2;
202   //int direction;
203   waypoint *wpt;
204
205   // Erase all existing waypoints.
206   //   wpt_vector_iterator i= waypoints.begin();
207   //resetWaypoints();
208   //int currWpt = wpt_iterator - waypoints.begin();
209   if (direction == 1)
210     {
211       
212       
213
214      
215       // Get the current active runway, based on code from David Luff
216       // This should actually be unified and extended to include 
217       // Preferential runway use schema's 
218       //FGEnvironment 
219       //stationweather = ((FGEnvironmentMgr *) globals->get_subsystem("environment"))
220       //->getEnvironment(apt->getLatitude(), apt->getLongitude(), apt->getElevation());
221       
222       //wind_speed = stationweather.get_wind_speed_kt();
223       //wind_heading = stationweather.get_wind_from_heading_deg();
224       //if (wind_speed == 0) {
225       //wind_heading = 270;     // This forces West-facing rwys to be used in no-wind situations
226         // which is consistent with Flightgear's initial setup.
227       //}
228       
229       //string rwy_no = globals->get_runways()->search(apt->getId(), int(wind_heading));
230       string name;
231       apt->getActiveRunway("com", 1, &name);
232       if (!(globals->get_runways()->search(apt->getId(), 
233                                             name, 
234                                             &rwy)))
235         {
236           cout << "Failed to find runway for " << apt->getId() << endl;
237           // Hmm, how do we handle a potential error like this?
238           exit(1);
239         }
240       //string test;
241       //apt->getActiveRunway(string("com"), 1, &test);
242       //exit(1);
243       
244       heading = rwy._heading;
245       double azimuth = heading + 180.0;
246       while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
247       geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
248                           rwy._length * SG_FEET_TO_METER * 0.5 - 5.0,
249                           &lat2, &lon2, &az2 );
250       
251       //Add the runway startpoint;
252       wpt = new waypoint;
253       wpt->name      = "Airport Center";
254       wpt->latitude  = apt->getLatitude();
255       wpt->longitude = apt->getLongitude();
256       wpt->altitude  = apt->getElevation();
257       wpt->speed     = 15; 
258       wpt->crossat   = -10000;
259       wpt->gear_down = true;
260       wpt->flaps_down= true;
261       wpt->finished  = false;
262       wpt->on_ground = true;
263       waypoints.push_back(wpt);
264        
265       //Add the runway startpoint;
266       wpt = new waypoint;
267       wpt->name      = "Runway Takeoff";
268       wpt->latitude  = lat2;
269       wpt->longitude = lon2;
270       wpt->altitude  = apt->getElevation();
271       wpt->speed     = 15; 
272       wpt->crossat   = -10000;
273       wpt->gear_down = true;
274       wpt->flaps_down= true;
275       wpt->finished  = false;
276       wpt->on_ground = true;
277       waypoints.push_back(wpt);
278       //wpt = new waypoint;
279       //wpt->finished = false;
280       //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
281     }
282   else
283     {
284       //direction = (rand() % 360);
285       //geo_direct_wgs_84 ( 0, arr->getLatitude(), arr->getLongitude(), direction, 
286       //100,
287       //&lat2, &lon2, &az2 );
288       
289       // This next statement really requires the flight plan to be
290       // split up into smaller sections, because 
291       // gate assignments will typically not be known until minutes before 
292       // landing, and certainly not at the start of a 10 hour flight.
293       apt->getAvailableParking(&lat, &lon, &heading, &gateId, radius, fltType, acType, airline);
294       heading += 180.0;
295       if (heading > 360)
296         heading -= 360;
297       geo_direct_wgs_84 ( 0, lat, lon, heading, 
298                           100,
299                           &lat2, &lon2, &az2 );
300       //Add the runway center
301       wpt = new waypoint;
302       wpt->name      = "Airport Center";
303       wpt->latitude  = apt->getLatitude();
304       wpt->longitude = apt->getLongitude();
305       wpt->altitude  = apt->getElevation();
306       wpt->speed     = 15; 
307       wpt->crossat   = -10000;
308       wpt->gear_down = true;
309       wpt->flaps_down= true;
310       wpt->finished  = false;
311       wpt->on_ground = true;
312       waypoints.push_back(wpt);
313
314       // Add the final destination waypoint
315       wpt = new waypoint;
316       wpt->name      = "Begin Parkingg"; //apt->getId(); //wpt_node->getStringValue("name", "END");
317       wpt->latitude  = lat2;
318       wpt->longitude = lon2;
319       wpt->altitude  = apt->getElevation();
320       wpt->speed     = 15; 
321       wpt->crossat   = -10000;
322       wpt->gear_down = true;
323       wpt->flaps_down= true;
324       wpt->finished  = false;
325       wpt->on_ground = true;
326       waypoints.push_back(wpt); 
327
328      
329     }
330   // wpt_iterator = waypoints.begin();
331   //if (!firstFlight)
332   // wpt_iterator++; 
333   //wpt_iterator = waypoints.begin()+currWpt;
334 }
335
336 /*******************************************************************
337  * CreateTakeOff 
338  * initialize the Aircraft at the parking location
339  ******************************************************************/
340 void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double speed)
341 {
342   double wind_speed;
343   double wind_heading;
344   double heading;
345   //FGRunway rwy;
346   double lat, lon, az;
347   double lat2, lon2, az2;
348   //int direction;
349   waypoint *wpt;
350   
351   
352   // Erase all existing waypoints.
353   // wpt_vector_iterator i= waypoints.begin();
354   //while(waypoints.begin() != waypoints.end())
355   //  {      
356   //    delete *(i);
357   //    waypoints.erase(i);
358   //  }
359   //resetWaypoints();
360   
361   
362   // Get the current active runway, based on code from David Luff
363   // This should actually be unified and extended to include 
364   // Preferential runway use schema's 
365   if (firstFlight)
366     {
367       string name;
368       apt->getActiveRunway("com", 1, &name);
369         if (!(globals->get_runways()->search(apt->getId(), 
370                                               name, 
371                                               &rwy)))
372           {
373             cout << "Failed to find runway for " << apt->getId() << endl;
374             // Hmm, how do we handle a potential error like this?
375             exit(1);
376           }
377         //string test;
378       //apt->getActiveRunway(string("com"), 1, &test);
379       //exit(1);
380     }
381   
382   heading = rwy._heading;
383   double azimuth = heading + 180.0;
384   while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
385   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
386                       rwy._length * SG_FEET_TO_METER * 0.5 - 105.0,
387                       &lat2, &lon2, &az2 );
388   wpt = new waypoint; 
389   wpt->name      = "accel"; 
390   wpt->latitude  = lat2; 
391   wpt->longitude = lon2; 
392   wpt->altitude  = apt->getElevation();
393   wpt->speed     = speed;  
394   wpt->crossat   = -10000;
395   wpt->gear_down = true;
396   wpt->flaps_down= true;
397   wpt->finished  = false;
398   wpt->on_ground = true;
399   waypoints.push_back(wpt); 
400   
401   lat = lat2;
402   lon = lon2;
403   az  = az2;
404   
405   //Next: the Start of Climb
406   geo_direct_wgs_84 ( 0, lat, lon, heading, 
407   2560 * SG_FEET_TO_METER,
408   &lat2, &lon2, &az2 );
409   
410   wpt = new waypoint;
411   wpt->name      = "SOC";
412   wpt->latitude  = lat2;
413   wpt->longitude = lon2;
414   wpt->altitude  = apt->getElevation()+3000;
415   wpt->speed     = speed; 
416   wpt->crossat   = -10000;
417   wpt->gear_down = true;
418   wpt->flaps_down= true;
419   wpt->finished  = false;
420   wpt->on_ground = false;
421   waypoints.push_back(wpt);
422   //  waypoints.push_back(wpt);
423   //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
424   // wpt_iterator = waypoints.begin();
425   //if (!firstFlight)
426   // wpt_iterator++;
427 }
428  
429 /*******************************************************************
430  * CreateClimb
431  * initialize the Aircraft at the parking location
432  ******************************************************************/
433 void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed, double alt)
434 {
435   double wind_speed;
436   double wind_heading;
437   double heading;
438   //FGRunway rwy;
439   double lat, lon, az;
440   double lat2, lon2, az2;
441   //int direction;
442   waypoint *wpt;
443
444   // Erase all existing waypoints.
445   // wpt_vector_iterator i= waypoints.begin();
446   //while(waypoints.begin() != waypoints.end())
447   //  {      
448   //    delete *(i);
449   //    waypoints.erase(i);
450   //  }
451   //resetWaypoints();
452   
453   
454   // Get the current active runway, based on code from David Luff
455   // This should actually be unified and extended to include 
456   // Preferential runway use schema's 
457   if (firstFlight)
458     {
459       string name;
460       apt->getActiveRunway("com", 1, &name);
461         if (!(globals->get_runways()->search(apt->getId(), 
462                                               name, 
463                                               &rwy)))
464           {
465             cout << "Failed to find runway for " << apt->getId() << endl;
466             // Hmm, how do we handle a potential error like this?
467             exit(1);
468           }
469         //string test;
470         //apt->getActiveRunway(string("com"), 1, &test);
471       //exit(1);
472     }
473   
474   
475   heading = rwy._heading;
476   double azimuth = heading + 180.0;
477   while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
478   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, 
479                       10*SG_NM_TO_METER,
480                       &lat2, &lon2, &az2 );
481   wpt = new waypoint;
482   wpt->name      = "10000ft climb";
483   wpt->latitude  = lat2;
484   wpt->longitude = lon2;
485   wpt->altitude  = 10000;
486   wpt->speed     = speed; 
487   wpt->crossat   = -10000;
488   wpt->gear_down = true;
489   wpt->flaps_down= true;
490   wpt->finished  = false;
491   wpt->on_ground = false;
492   waypoints.push_back(wpt); 
493   
494
495   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, 
496                       20*SG_NM_TO_METER,
497                       &lat2, &lon2, &az2 );
498   wpt = new waypoint;
499   wpt->name      = "18000ft climb";
500   wpt->latitude  = lat2;
501   wpt->longitude = lon2;
502   wpt->altitude  = 18000;
503   wpt->speed     = speed; 
504   wpt->crossat   = -10000;
505   wpt->gear_down = true;
506   wpt->flaps_down= true;
507   wpt->finished  = false;
508   wpt->on_ground = false;
509   waypoints.push_back(wpt); 
510   //waypoints.push_back(wpt); 
511   //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
512   // wpt_iterator = waypoints.begin();
513   //if (!firstFlight)
514   // wpt_iterator++;
515 }
516
517
518 /*******************************************************************
519  * CreateCruise
520  * initialize the Aircraft at the parking location
521  ******************************************************************/
522 void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep, FGAirport *arr, double latitude, double longitude, double speed, double alt)
523 {
524   double wind_speed;
525   double wind_heading;
526   double heading;
527   //FGRunway rwy;
528   double lat, lon, az;
529   double lat2, lon2, az2;
530   double azimuth;
531   //int direction;
532   waypoint *wpt;
533
534   // Erase all existing waypoints.
535   // wpt_vector_iterator i= waypoints.begin();
536   //while(waypoints.begin() != waypoints.end())
537   //  {      
538   //    delete *(i);
539   //    waypoints.erase(i);
540   //  }
541   //resetWaypoints();
542
543   wpt = new waypoint;
544   wpt->name      = "Cruise"; //wpt_node->getStringValue("name", "END");
545   wpt->latitude  = latitude;
546   wpt->longitude = longitude;
547   wpt->altitude  = alt;
548   wpt->speed     = speed; 
549   wpt->crossat   = -10000;
550   wpt->gear_down = false;
551   wpt->flaps_down= false;
552   wpt->finished  = false;
553   wpt->on_ground = false;
554   waypoints.push_back(wpt); 
555   //Beginning of Decent
556  
557   string name;
558   arr->getActiveRunway("com", 2, &name);
559   if (!(globals->get_runways()->search(arr->getId(), 
560                                        name, 
561                                        &rwy)))
562     {
563       cout << "Failed to find runway for " << arr->getId() << endl;
564       // Hmm, how do we handle a potential error like this?
565       exit(1);
566     }
567   //string test;
568   //arr->getActiveRunway(string("com"), 1, &test);
569   //exit(1);
570   
571   //cerr << "Altitude = " << alt << endl;
572   //cerr << "Done" << endl;
573   //if (arr->getId() == "EHAM")
574   //  {
575   //    cerr << "Creating cruise to EHAM " << latitude << " " << longitude << endl;
576   //  }
577   heading = rwy._heading;
578   azimuth = heading + 180.0;
579   while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
580   
581   
582   // Note: This places us at the location of the active 
583   // runway during initial cruise. This needs to be 
584   // fixed later. 
585   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
586                       110000,
587                       &lat2, &lon2, &az2 );
588   wpt = new waypoint;
589   wpt->name      = "BOD"; //wpt_node->getStringValue("name", "END");
590   wpt->latitude  = lat2;
591   wpt->longitude = lon2;
592   wpt->altitude  = alt;
593   wpt->speed     = speed; 
594   wpt->crossat   = alt;
595   wpt->gear_down = false;
596   wpt->flaps_down= false;
597   wpt->finished  = false;
598   wpt->on_ground = false;
599   waypoints.push_back(wpt); 
600   //waypoints.push_back(wpt);
601   //waypoints.push_back(wpt);  // add one more to prevent a segfault.  
602   //wpt_iterator = waypoints.begin();
603   //if (!firstFlight)
604   // wpt_iterator++;
605 }
606
607 /*******************************************************************
608  * CreateDecent
609  * initialize the Aircraft at the parking location
610  ******************************************************************/
611 void FGAIFlightPlan::createDecent(FGAirport *apt)
612 {
613
614   // Ten thousand ft. Slowing down to 240 kts
615   double wind_speed;
616   double wind_heading;
617   double heading;
618   //FGRunway rwy;
619   double lat, lon, az;
620   double lat2, lon2, az2;
621   double azimuth;
622   //int direction;
623   waypoint *wpt;
624
625   //// Erase all existing waypoints.
626   // wpt_vector_iterator i= waypoints.begin();
627   //while(waypoints.begin() != waypoints.end())
628   //  {      
629   //    delete *(i);
630   //    waypoints.erase(i);
631   //  }
632   //resetWaypoints();
633
634   //Beginning of Decent
635   string name;
636   apt->getActiveRunway("com", 2, &name);
637     if (!(globals->get_runways()->search(apt->getId(), 
638                                           name, 
639                                           &rwy)))
640       {
641         cout << "Failed to find runway for " << apt->getId() << endl;
642         // Hmm, how do we handle a potential error like this?
643         exit(1);
644       }
645     //string test;
646     //apt->getActiveRunway(string("com"), 1, &test);
647   //exit(1);
648
649   //cerr << "Done" << endl;
650   heading = rwy._heading;
651   azimuth = heading + 180.0;
652   while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
653   
654   
655   
656   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
657                       100000,
658                       &lat2, &lon2, &az2 );
659   
660   wpt = new waypoint;
661   wpt->name      = "Dec 10000ft"; //wpt_node->getStringValue("name", "END");
662   wpt->latitude  = lat2;
663   wpt->longitude = lon2;
664   wpt->altitude  = apt->getElevation();
665   wpt->speed     = 240; 
666   wpt->crossat   = 10000;
667   wpt->gear_down = false;
668   wpt->flaps_down= false;
669   wpt->finished  = false;
670   wpt->on_ground = false;
671   waypoints.push_back(wpt);  
672
673   // Three thousand ft. Slowing down to 160 kts
674   geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
675                      8*SG_NM_TO_METER,
676                      &lat2, &lon2, &az2 );
677   wpt = new waypoint;
678   wpt->name      = "DEC 3000ft"; //wpt_node->getStringValue("name", "END");
679   wpt->latitude  = lat2;
680   wpt->longitude = lon2;
681   wpt->altitude  = apt->getElevation();
682   wpt->speed     = 160; 
683   wpt->crossat   = 3000;
684   wpt->gear_down = true;
685   wpt->flaps_down= true;
686   wpt->finished  = false;
687   wpt->on_ground = false;
688   waypoints.push_back(wpt);
689   //waypoints.push_back(wpt);
690   //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
691   //wpt_iterator = waypoints.begin();
692   //wpt_iterator++;
693   //if (apt->getId() == "EHAM")
694   //  {
695   //    cerr << "Created Decend to EHAM " << lat2 << " " << lon2 << ": Runway = " << rwy._rwy_no 
696   //       << "heading " << heading << endl;
697   //  }
698 }
699 /*******************************************************************
700  * CreateLanding
701  * initialize the Aircraft at the parking location
702  ******************************************************************/
703 void FGAIFlightPlan::createLanding(FGAirport *apt)
704 {
705   // Ten thousand ft. Slowing down to 240 kts
706   double wind_speed;
707   double wind_heading;
708   double heading;
709   //FGRunway rwy;
710   double lat, lon, az;
711   double lat2, lon2, az2;
712   double azimuth;
713   //int direction;
714   waypoint *wpt;
715
716   
717   heading = rwy._heading;
718   azimuth = heading + 180.0;
719   while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
720
721   //Runway Threshold
722  geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
723                      rwy._length*0.45 * SG_FEET_TO_METER,
724                      &lat2, &lon2, &az2 );
725   wpt = new waypoint;
726   wpt->name      = "Threshold"; //wpt_node->getStringValue("name", "END");
727   wpt->latitude  = lat2;
728   wpt->longitude = lon2;
729   wpt->altitude  = apt->getElevation();
730   wpt->speed     = 150; 
731   wpt->crossat   = apt->getElevation();
732   wpt->gear_down = true;
733   wpt->flaps_down= true;
734   wpt->finished  = false;
735   wpt->on_ground = true;
736   waypoints.push_back(wpt); 
737
738  //Full stop at the runway centerpoint
739  geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
740                      rwy._length*0.45,
741                       &lat2, &lon2, &az2 );
742   wpt = new waypoint;
743   wpt->name      = "Center"; //wpt_node->getStringValue("name", "END");
744   wpt->latitude  = rwy._lat;
745   wpt->longitude = rwy._lon;
746   wpt->altitude  = apt->getElevation();
747   wpt->speed     = 30; 
748   wpt->crossat   = -10000;
749   wpt->gear_down = true;
750   wpt->flaps_down= true;
751   wpt->finished  = false;
752   wpt->on_ground = true;
753   waypoints.push_back(wpt);
754
755  geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading, 
756                      rwy._length*0.45 * SG_FEET_TO_METER,
757                      &lat2, &lon2, &az2 );
758   wpt = new waypoint;
759   wpt->name      = "Threshold"; //wpt_node->getStringValue("name", "END");
760   wpt->latitude  = lat2;
761   wpt->longitude = lon2;
762   wpt->altitude  = apt->getElevation();
763   wpt->speed     = 15; 
764   wpt->crossat   = apt->getElevation();
765   wpt->gear_down = true;
766   wpt->flaps_down= true;
767   wpt->finished  = false;
768   wpt->on_ground = true;
769   waypoints.push_back(wpt); 
770   //waypoints.push_back(wpt); 
771   //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
772   //wpt_iterator = waypoints.begin();
773   //wpt_iterator++;
774
775   //if (apt->getId() == "EHAM")
776   //{
777   //  cerr << "Created Landing to EHAM " << lat2 << " " << lon2 << ": Runway = " << rwy._rwy_no 
778   //     << "heading " << heading << endl;
779   //}
780 }
781
782 /*******************************************************************
783  * CreateParking
784  * initialize the Aircraft at the parking location
785  ******************************************************************/
786 void FGAIFlightPlan::createParking(FGAirport *apt)
787 {
788   waypoint* wpt;
789   double lat;
790   double lon;
791   double heading;
792   apt->getParking(gateId, &lat, &lon, &heading);
793   heading += 180.0;
794   if (heading > 360)
795     heading -= 360; 
796
797   // Erase all existing waypoints.
798   // wpt_vector_iterator i= waypoints.begin();
799   //while(waypoints.begin() != waypoints.end())
800   //  {      
801   //    delete *(i);
802   //    waypoints.erase(i);
803   //  }
804   //resetWaypoints();
805   // And finally one more named "END"
806   wpt = new waypoint;
807   wpt->name      = "END"; //wpt_node->getStringValue("name", "END");
808   wpt->latitude  = lat;
809   wpt->longitude = lon;
810   wpt->altitude  = 19;
811   wpt->speed     = 15; 
812   wpt->crossat   = -10000;
813   wpt->gear_down = true;
814   wpt->flaps_down= true;
815   wpt->finished  = false;
816   wpt->on_ground = true;
817   waypoints.push_back(wpt);
818   //waypoints.push_back(wpt);
819   //waypoints.push_back(wpt);  // add one more to prevent a segfault. 
820   //wpt_iterator = waypoints.begin();
821   //wpt_iterator++;
822 }