1 /******************************************************************************
2 * AIFlightPlanCreate.cxx
3 * Written by Durk Talsma, started May, 2004.
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 **************************************************************************/
25 #include "AIFlightPlan.hxx"
26 #include <simgear/math/sg_geodesy.hxx>
27 #include <Airports/runways.hxx>
28 #include <Airports/dynamics.hxx>
30 #include <Environment/environment_mgr.hxx>
31 #include <Environment/environment.hxx>
34 /* FGAIFlightPlan::create()
35 * dynamically create a flight plan for AI traffic, based on data provided by the
36 * Traffic Manager, when reading a filed flightplan failes. (DT, 2004/07/10)
38 * This is the top-level function, and the only one that is publicly available.
43 // Check lat/lon values during initialization;
44 void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, int legNr,
45 double alt, double speed, double latitude,
46 double longitude, bool firstFlight,double radius,
47 const string& fltType, const string& aircraftType,
48 const string& airline)
50 int currWpt = wpt_iterator - waypoints.begin();
54 createPushBack(firstFlight,dep, latitude, longitude,
55 radius, fltType, aircraftType, airline);
58 createTaxi(firstFlight, 1, dep, latitude, longitude,
59 radius, fltType, aircraftType, airline);
62 createTakeOff(firstFlight, dep, speed, fltType);
65 createClimb(firstFlight, dep, speed, alt, fltType);
68 createCruise(firstFlight, dep,arr, latitude, longitude, speed, alt, fltType);
71 createDecent(arr, fltType);
77 createTaxi(false, 2, arr, latitude, longitude, radius,
78 fltType, aircraftType, airline);
81 createParking(arr, radius);
85 SG_LOG(SG_INPUT, SG_ALERT, "AIFlightPlan::create() attempting to create unknown leg"
86 " this is probably an internal program error");
88 wpt_iterator = waypoints.begin()+currWpt;
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);
485 /*******************************************************************
487 * initialize the Aircraft at the parking location
488 ******************************************************************/
489 void FGAIFlightPlan::createTakeOff(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
502 string rwyClass = getRunwayClassFromTrafficType(fltType);
503 apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
504 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);
617 /*******************************************************************
619 * initialize the Aircraft at the parking location
620 ******************************************************************/
621 void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed, double alt, const string &fltType)
625 double lat2, lon2, az2;
633 string rwyClass = getRunwayClassFromTrafficType(fltType);
634 apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
635 rwy = apt->getRunwayByIdent(activeRunway);
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);
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);
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 /*******************************************************************
746 * initialize the Aircraft at the parking location
747 ******************************************************************/
748 void FGAIFlightPlan::createDecent(FGAirport *apt, const string &fltType)
751 // Ten thousand ft. Slowing down to 240 kts
754 double lat2, lon2, az2;
759 //Beginning of Decent
761 // allow "mil" and "gen" as well
762 string rwyClass = getRunwayClassFromTrafficType(fltType);
763 apt->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway);
764 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();
779 wpt->crossat = 10000;
780 wpt->gear_down = false;
781 wpt->flaps_down= false;
782 wpt->finished = false;
783 wpt->on_ground = false;
785 waypoints.push_back(wpt);
787 // 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();
798 wpt->gear_down = true;
799 wpt->flaps_down= true;
800 wpt->finished = false;
801 wpt->on_ground = false;
803 waypoints.push_back(wpt);
805 /*******************************************************************
807 * initialize the Aircraft at the parking location
808 ******************************************************************/
809 void FGAIFlightPlan::createLanding(FGAirport *apt)
811 // Ten thousand ft. Slowing down to 150 kts
814 double lat2, lon2, az2;
820 heading = rwy->headingDeg();
821 azimuth = heading + 180.0;
822 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
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;
840 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;
858 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();
869 wpt->crossat = apt->getElevation();
870 wpt->gear_down = true;
871 wpt->flaps_down= true;
872 wpt->finished = false;
873 wpt->on_ground = true;
875 waypoints.push_back(wpt);
878 /*******************************************************************
880 * initialize the Aircraft at the parking location
881 ******************************************************************/
882 void FGAIFlightPlan::createParking(FGAirport *apt, double radius)
889 apt->getDynamics()->getParking(gateId, &lat, &lon, &heading);
893 geo_direct_wgs_84 ( 0, lat, lon, heading,
895 &lat2, &lon2, &az2 );
897 wpt->name = "taxiStart";
898 wpt->latitude = lat2;
899 wpt->longitude = lon2;
900 wpt->altitude = apt->getElevation();
902 wpt->crossat = -10000;
903 wpt->gear_down = true;
904 wpt->flaps_down= true;
905 wpt->finished = false;
906 wpt->on_ground = true;
908 waypoints.push_back(wpt);
909 geo_direct_wgs_84 ( 0, lat, lon, heading,
911 &lat2, &lon2, &az2 );
913 wpt->name = "taxiStart";
914 wpt->latitude = lat2;
915 wpt->longitude = lon2;
916 wpt->altitude = apt->getElevation();
918 wpt->crossat = -10000;
919 wpt->gear_down = true;
920 wpt->flaps_down= true;
921 wpt->finished = false;
922 wpt->on_ground = true;
924 waypoints.push_back(wpt);
927 wpt->name = "END"; //wpt_node->getStringValue("name", "END");
929 wpt->longitude = lon;
930 wpt->altitude = apt->getElevation();
932 wpt->crossat = -10000;
933 wpt->gear_down = true;
934 wpt->flaps_down= true;
935 wpt->finished = false;
936 wpt->on_ground = true;
938 waypoints.push_back(wpt);
943 * @param fltType a string describing the type of
944 * traffic, normally used for gate assignments
945 * @return a converted string that gives the runway
946 * preference schedule to be used at aircraft having
947 * a preferential runway schedule implemented (i.e.
948 * having a rwyprefs.xml file
950 * Currently valid traffic types for gate assignment:
951 * - gate (commercial gate)
952 * - cargo (commercial gargo),
953 * - ga (general aviation) ,
955 * - mil-fighter (military - fighter),
956 * - mil-transport (military - transport)
958 * Valid runway classes:
959 * - com (commercial traffic: jetliners, passenger and cargo)
960 * - gen (general aviation)
961 * - ul (ultralight: I can imagine that these may share a runway with ga on some airports)
962 * - mil (all military traffic)
964 string FGAIFlightPlan::getRunwayClassFromTrafficType(string fltType)
966 if ((fltType == "gate") || (fltType == "cargo")) {
967 return string("com");
969 if (fltType == "ga") {
970 return string ("gen");
972 if (fltType == "ul") {
975 if ((fltType == "mil-fighter") || (fltType == "mil-transport")) {
976 return string("mil");
978 return string("com");