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 **************************************************************************/
20 #include "AIFlightPlan.hxx"
21 #include <simgear/math/sg_geodesy.hxx>
22 #include <Airports/runways.hxx>
23 #include <Airports/dynamics.hxx>
25 #include <Environment/environment_mgr.hxx>
26 #include <Environment/environment.hxx>
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)
33 * This is the top-level function, and the only one that is publicly available.
38 // Check lat/lon values during initialization;
39 void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, int legNr,
40 double alt, double speed, double latitude,
41 double longitude, bool firstFlight,double radius,
42 const string& fltType, const string& aircraftType,
43 const string& airline)
45 int currWpt = wpt_iterator - waypoints.begin();
49 createPushBack(firstFlight,dep, latitude, longitude,
50 radius, fltType, aircraftType, airline);
53 createTaxi(firstFlight, 1, dep, latitude, longitude,
54 radius, fltType, aircraftType, airline);
57 createTakeOff(firstFlight, dep, speed, fltType);
60 createClimb(firstFlight, dep, speed, alt, fltType);
63 createCruise(firstFlight, dep,arr, latitude, longitude, speed, alt, fltType);
66 createDecent(arr, fltType);
72 createTaxi(false, 2, arr, latitude, longitude, radius,
73 fltType, aircraftType, airline);
76 createParking(arr, radius);
80 SG_LOG(SG_INPUT, SG_ALERT, "AIFlightPlan::create() attempting to create unknown leg"
81 " this is probably an internal program error");
83 wpt_iterator = waypoints.begin()+currWpt;
92 /*******************************************************************
94 * initialize the Aircraft at the parking location
95 ******************************************************************/
96 void FGAIFlightPlan::createTaxi(bool firstFlight, int direction,
97 FGAirport *apt, double latitude, double longitude,
98 double radius, const string& fltType,
99 const string& acType, const string& airline)
103 double lat2, lon2, az2;
106 int nrWaypointsToSkip;
110 // If this function is called during initialization,
111 // make sure we obtain a valid gate ID first
112 // and place the model at the location of the gate.
115 if (!(apt->getDynamics()->getAvailableParking(&lat, &lon,
120 SG_LOG(SG_INPUT, SG_WARN, "Could not find parking for a " <<
122 " of flight type " << fltType <<
123 " of airline " << airline <<
124 " at airport " << apt->getId());
126 //waypoint *wpt = new waypoint;
127 //wpt->name = "park";
128 //wpt->latitude = lat;
129 //wpt->longitude = lon;
130 //wpt->altitude = apt->getElevation();
132 //wpt->crossat = -10000;
133 //wpt->gear_down = true;
134 //wpt->flaps_down= true;
135 //wpt->finished = false;
136 //wpt->on_ground = true;
137 //waypoints.push_back(wpt);
139 string rwyClass = getRunwayClassFromTrafficType(fltType);
140 apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
141 rwy = apt->getRunwayByIdent(activeRunway);
143 // Determine the beginning of he runway
144 heading = rwy._heading;
145 double azimuth = heading + 180.0;
146 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
147 geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
148 rwy._length * SG_FEET_TO_METER * 0.5 - 5.0,
149 &lat2, &lon2, &az2 );
151 if (apt->getDynamics()->getGroundNetwork()->exists())
154 int runwayId = apt->getDynamics()->getGroundNetwork()->findNearestNode(lat2,
158 // A negative gateId indicates an overflow parking, use a
159 // fallback mechanism for this.
160 // Starting from gate 0 in this case is a bit of a hack
161 // which requires a more proper solution later on.
164 taxiRoute = new FGTaxiRoute;
166 // Determine which node to start from.
168 // Find out which node to start from
169 FGParking *park = apt->getDynamics()->getParking(gateId);
171 node = park->getPushBackPoint();
177 // HAndle case where parking doens't have a node
178 if ((node == 0) && park) {
182 node = lastNodeVisited;
186 //cerr << "Using node " << node << endl;
187 *taxiRoute = apt->getDynamics()->getGroundNetwork()->findShortestRoute(node, runwayId);
190 if (taxiRoute->empty()) {
191 //Add the runway startpoint;
193 wpt->name = "Airport Center";
194 wpt->latitude = latitude;
195 wpt->longitude = longitude;
196 wpt->altitude = apt->getElevation();
198 wpt->crossat = -10000;
199 wpt->gear_down = true;
200 wpt->flaps_down= true;
201 wpt->finished = false;
202 wpt->on_ground = true;
204 waypoints.push_back(wpt);
206 //Add the runway startpoint;
208 wpt->name = "Runway Takeoff";
209 wpt->latitude = lat2;
210 wpt->longitude = lon2;
211 wpt->altitude = apt->getElevation();
213 wpt->crossat = -10000;
214 wpt->gear_down = true;
215 wpt->flaps_down= true;
216 wpt->finished = false;
217 wpt->on_ground = true;
219 waypoints.push_back(wpt);
223 //bool isPushBackPoint = false;
226 // If this is called during initialization, randomly
227 // skip a number of waypoints to get a more realistic
229 //isPushBackPoint = true;
230 int nrWaypoints = taxiRoute->size();
231 nrWaypointsToSkip = rand() % nrWaypoints;
232 // but make sure we always keep two active waypoints
233 // to prevent a segmentation fault
234 for (int i = 0; i < nrWaypointsToSkip-2; i++) {
235 //isPushBackPoint = false;
236 taxiRoute->next(&node);
238 apt->getDynamics()->releaseParking(gateId);
240 if (taxiRoute->size() > 1) {
241 taxiRoute->next(&node); // chop off the first waypoint, because that is already the last of the pushback route
245 while(taxiRoute->next(&node, &route))
247 //FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findSegment(node)->getEnd();
249 snprintf (buffer, 10, "%d", node);
250 FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
253 wpt->name = string(buffer); // fixme: should be the name of the taxiway
254 wpt->latitude = tn->getLatitude();
255 wpt->longitude = tn->getLongitude();
256 // Elevation is currently disregarded when on_ground is true
257 // because the AIModel obtains a periodic ground elevation estimate.
258 wpt->altitude = apt->getElevation();
260 wpt->crossat = -10000;
261 wpt->gear_down = true;
262 wpt->flaps_down= true;
263 wpt->finished = false;
264 wpt->on_ground = true;
265 wpt->routeIndex = route;
266 waypoints.push_back(wpt);
270 // finally, rewind the taxiRoute object to the point where we started
271 // generating the Flightplan, for AI use.
272 // This is a bit tricky, because the
275 for (int i = 0; i < nrWaypointsToSkip-1; i++) {
276 taxiRoute->next(&node);
279 int size = taxiRoute->size();
281 //taxiRoute->next(&node);
282 //taxiRoute->next(&node);
283 //taxiRoute->next(&node);
286 } // taxiRoute not empty
290 // This is the fallback mechanism, in case no ground network is available
291 //Add the runway startpoint;
293 wpt->name = "Airport Center";
294 wpt->latitude = apt->getLatitude();
295 wpt->longitude = apt->getLongitude();
296 wpt->altitude = apt->getElevation();
298 wpt->crossat = -10000;
299 wpt->gear_down = true;
300 wpt->flaps_down= true;
301 wpt->finished = false;
302 wpt->on_ground = true;
304 waypoints.push_back(wpt);
306 //Add the runway startpoint;
308 wpt->name = "Runway Takeoff";
309 wpt->latitude = lat2;
310 wpt->longitude = lon2;
311 wpt->altitude = apt->getElevation();
313 wpt->crossat = -10000;
314 wpt->gear_down = true;
315 wpt->flaps_down= true;
316 wpt->finished = false;
317 wpt->on_ground = true;
319 waypoints.push_back(wpt);
324 apt->getDynamics()->getAvailableParking(&lat, &lon, &heading,
325 &gateId, radius, fltType,
328 double lat3 = (*(waypoints.end()-1))->latitude;
329 double lon3 = (*(waypoints.end()-1))->longitude;
330 //cerr << (*(waypoints.end()-1))->name << endl;
332 // Find a route from runway end to parking/gate.
333 if (apt->getDynamics()->getGroundNetwork()->exists())
336 int runwayId = apt->getDynamics()->getGroundNetwork()->findNearestNode(lat3,
338 // A negative gateId indicates an overflow parking, use a
339 // fallback mechanism for this.
340 // Starting from gate 0 is a bit of a hack...
343 taxiRoute = new FGTaxiRoute;
345 *taxiRoute = apt->getDynamics()->getGroundNetwork()->findShortestRoute(runwayId,
348 *taxiRoute = apt->getDynamics()->getGroundNetwork()->findShortestRoute(runwayId, 0);
351 // No route found: go from gate directly to runway
352 if (taxiRoute->empty()) {
353 //Add the runway startpoint;
355 wpt->name = "Airport Center";
356 wpt->latitude = latitude;
357 wpt->longitude = longitude;
358 wpt->altitude = apt->getElevation();
360 wpt->crossat = -10000;
361 wpt->gear_down = true;
362 wpt->flaps_down= true;
363 wpt->finished = false;
364 wpt->on_ground = true;
366 waypoints.push_back(wpt);
368 //Add the runway startpoint;
370 wpt->name = "Runway Takeoff";
371 wpt->latitude = lat3;
372 wpt->longitude = lon3;
373 wpt->altitude = apt->getElevation();
375 wpt->crossat = -10000;
376 wpt->gear_down = true;
377 wpt->flaps_down= true;
378 wpt->finished = false;
379 wpt->on_ground = true;
381 waypoints.push_back(wpt);
385 int size = taxiRoute->size();
386 // Omit the last two waypoints, as
387 // those are created by createParking()
389 for (int i = 0; i < size-2; i++)
391 taxiRoute->next(&node, &route);
393 snprintf (buffer, 10, "%d", node);
394 //FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
395 FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
397 //wpt->name = "taxiway"; // fixme: should be the name of the taxiway
398 wpt->name = string(buffer);// fixme: should be the name of the taxiway
399 wpt->latitude = tn->getLatitude();
400 wpt->longitude = tn->getLongitude();
401 wpt->altitude = apt->getElevation();
403 wpt->crossat = -10000;
404 wpt->gear_down = true;
405 wpt->flaps_down= true;
406 wpt->finished = false;
407 wpt->on_ground = true;
408 wpt->routeIndex = route;
409 waypoints.push_back(wpt);
411 //taxiRoute->first();
412 //taxiRoute->next(&node);
417 // Use a fallback mechanism in case no ground network is available
418 // obtain the location of the gate entrance point
422 geo_direct_wgs_84 ( 0, lat, lon, heading,
424 &lat2, &lon2, &az2 );
426 wpt->name = "Airport Center";
427 wpt->latitude = apt->getLatitude();
428 wpt->longitude = apt->getLongitude();
429 wpt->altitude = apt->getElevation();
431 wpt->crossat = -10000;
432 wpt->gear_down = true;
433 wpt->flaps_down= true;
434 wpt->finished = false;
435 wpt->on_ground = true;
437 waypoints.push_back(wpt);
440 wpt->name = "Begin Parking"; //apt->getId(); //wpt_node->getStringValue("name", "END");
441 wpt->latitude = lat2;
442 wpt->longitude = lon2;
443 wpt->altitude = apt->getElevation();
445 wpt->crossat = -10000;
446 wpt->gear_down = true;
447 wpt->flaps_down= true;
448 wpt->finished = false;
449 wpt->on_ground = true;
451 waypoints.push_back(wpt);
457 apt->getDynamics()->getParking(gateId, &lat, &lon, &heading);
463 wpt->name = "END"; //wpt_node->getStringValue("name", "END");
465 wpt->longitude = lon;
468 wpt->crossat = -10000;
469 wpt->gear_down = true;
470 wpt->flaps_down= true;
471 wpt->finished = false;
472 wpt->on_ground = true;
474 waypoints.push_back(wpt);
480 /*******************************************************************
482 * initialize the Aircraft at the parking location
483 ******************************************************************/
484 void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double speed, const string &fltType)
488 double lat2, lon2, az2;
491 // Get the current active runway, based on code from David Luff
492 // This should actually be unified and extended to include
493 // Preferential runway use schema's
497 string rwyClass = getRunwayClassFromTrafficType(fltType);
498 apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
499 rwy = apt->getRunwayByIdent(activeRunway);
501 // Acceleration point, 105 meters into the runway,
502 heading = rwy._heading;
503 double azimuth = heading + 180.0;
504 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
505 geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
506 rwy._length * SG_FEET_TO_METER * 0.5 - 105.0,
507 &lat2, &lon2, &az2 );
510 wpt->latitude = lat2;
511 wpt->longitude = lon2;
512 wpt->altitude = apt->getElevation();
514 wpt->crossat = -10000;
515 wpt->gear_down = true;
516 wpt->flaps_down= true;
517 wpt->finished = false;
518 wpt->on_ground = true;
520 waypoints.push_back(wpt);
526 //Start Climbing to 3000 ft. Let's do this
527 // at the center of the runway for now:
529 geo_direct_wgs_84 ( 0, lat, lon, heading,
530 2560 * SG_FEET_TO_METER,
531 &lat2, &lon2, &az2 );
535 wpt->latitude = rwy._lat;
536 wpt->longitude = rwy._lon;
537 wpt->altitude = apt->getElevation()+1000;
539 wpt->crossat = -10000;
540 wpt->gear_down = true;
541 wpt->flaps_down= true;
542 wpt->finished = false;
543 wpt->on_ground = false;
545 waypoints.push_back(wpt);
548 geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading,
549 rwy._length * SG_FEET_TO_METER,
550 &lat2, &lon2, &az2 );
553 wpt->name = "3000 ft";
554 wpt->latitude = lat2;
555 wpt->longitude = lon2;
556 wpt->altitude = apt->getElevation()+3000;
558 wpt->crossat = -10000;
559 wpt->gear_down = true;
560 wpt->flaps_down= true;
561 wpt->finished = false;
562 wpt->on_ground = false;
564 waypoints.push_back(wpt);
566 // Finally, add two more waypoints, so that aircraft will remain under
567 // Tower control until they have reached the 3000 ft climb point
570 geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading,
572 &lat2, &lon2, &az2 );
576 wpt->name = "5000 ft";
577 wpt->latitude = lat2;
578 wpt->longitude = lon2;
579 wpt->altitude = apt->getElevation()+5000;
581 wpt->crossat = -10000;
582 wpt->gear_down = true;
583 wpt->flaps_down= true;
584 wpt->finished = false;
585 wpt->on_ground = false;
587 waypoints.push_back(wpt);
589 // geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading,
591 // &lat2, &lon2, &az2 );
592 // wpt = new waypoint;
593 // wpt->name = "5100 ft";
594 // wpt->latitude = lat2;
595 // wpt->longitude = lon2;
596 // wpt->altitude = apt->getElevation()+5100;
597 // wpt->speed = speed;
598 // wpt->crossat = -10000;
599 // wpt->gear_down = true;
600 // wpt->flaps_down= true;
601 // wpt->finished = false;
602 // wpt->on_ground = false;
603 // wpt->routeIndex = 0;
604 // waypoints.push_back(wpt);
607 /*******************************************************************
609 * initialize the Aircraft at the parking location
610 ******************************************************************/
611 void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed, double alt, const string &fltType)
615 double lat2, lon2, az2;
623 string rwyClass = getRunwayClassFromTrafficType(fltType);
624 apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
625 rwy = apt->getRunwayByIdent(activeRunway);
629 heading = rwy._heading;
630 double azimuth = heading + 180.0;
631 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
632 //cerr << "Creating climb at : " << rwy._id << " " << rwy._rwy_no << endl;
633 geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading,
635 &lat2, &lon2, &az2 );
637 wpt->name = "10000ft climb";
638 wpt->latitude = lat2;
639 wpt->longitude = lon2;
640 wpt->altitude = 10000;
642 wpt->crossat = -10000;
643 wpt->gear_down = true;
644 wpt->flaps_down= true;
645 wpt->finished = false;
646 wpt->on_ground = false;
648 waypoints.push_back(wpt);
651 geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading,
653 &lat2, &lon2, &az2 );
655 wpt->name = "18000ft climb";
656 wpt->latitude = lat2;
657 wpt->longitude = lon2;
658 wpt->altitude = 18000;
660 wpt->crossat = -10000;
661 wpt->gear_down = true;
662 wpt->flaps_down= true;
663 wpt->finished = false;
664 wpt->on_ground = false;
666 waypoints.push_back(wpt);
670 // /*******************************************************************
672 // * initialize the Aircraft at the parking location
673 // ******************************************************************/
674 // void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep,
675 // FGAirport *arr, double latitude,
676 // double longitude, double speed,
679 // double wind_speed;
680 // double wind_heading;
682 // double lat, lon, az;
683 // double lat2, lon2, az2;
687 // wpt = new waypoint;
688 // wpt->name = "Cruise"; //wpt_node->getStringValue("name", "END");
689 // wpt->latitude = latitude;
690 // wpt->longitude = longitude;
691 // wpt->altitude = alt;
692 // wpt->speed = speed;
693 // wpt->crossat = -10000;
694 // wpt->gear_down = false;
695 // wpt->flaps_down= false;
696 // wpt->finished = false;
697 // wpt->on_ground = false;
698 // waypoints.push_back(wpt);
701 // // should be changed dynamically to allow "gen" and "mil"
702 // arr->getDynamics()->getActiveRunway("com", 2, activeRunway);
703 // if (!(globals->get_runways()->search(arr->getId(),
707 // SG_LOG(SG_INPUT, SG_ALERT, "Failed to find runway " <<
709 // " at airport " << arr->getId());
712 // heading = rwy._heading;
713 // azimuth = heading + 180.0;
714 // while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
717 // geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
719 // &lat2, &lon2, &az2 );
720 // wpt = new waypoint;
721 // wpt->name = "BOD";
722 // wpt->latitude = lat2;
723 // wpt->longitude = lon2;
724 // wpt->altitude = alt;
725 // wpt->speed = speed;
726 // wpt->crossat = alt;
727 // wpt->gear_down = false;
728 // wpt->flaps_down= false;
729 // wpt->finished = false;
730 // wpt->on_ground = false;
731 // waypoints.push_back(wpt);
734 /*******************************************************************
736 * initialize the Aircraft at the parking location
737 ******************************************************************/
738 void FGAIFlightPlan::createDecent(FGAirport *apt, const string &fltType)
741 // Ten thousand ft. Slowing down to 240 kts
744 double lat2, lon2, az2;
749 //Beginning of Decent
751 // allow "mil" and "gen" as well
752 string rwyClass = getRunwayClassFromTrafficType(fltType);
753 apt->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway);
754 rwy = apt->getRunwayByIdent(activeRunway);
756 heading = rwy._heading;
757 azimuth = heading + 180.0;
758 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
759 geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
761 &lat2, &lon2, &az2 );
764 wpt->name = "Dec 10000ft"; //wpt_node->getStringValue("name", "END");
765 wpt->latitude = lat2;
766 wpt->longitude = lon2;
767 wpt->altitude = apt->getElevation();
769 wpt->crossat = 10000;
770 wpt->gear_down = false;
771 wpt->flaps_down= false;
772 wpt->finished = false;
773 wpt->on_ground = false;
775 waypoints.push_back(wpt);
777 // Three thousand ft. Slowing down to 160 kts
778 geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
780 &lat2, &lon2, &az2 );
782 wpt->name = "DEC 3000ft"; //wpt_node->getStringValue("name", "END");
783 wpt->latitude = lat2;
784 wpt->longitude = lon2;
785 wpt->altitude = apt->getElevation();
788 wpt->gear_down = true;
789 wpt->flaps_down= true;
790 wpt->finished = false;
791 wpt->on_ground = false;
793 waypoints.push_back(wpt);
795 /*******************************************************************
797 * initialize the Aircraft at the parking location
798 ******************************************************************/
799 void FGAIFlightPlan::createLanding(FGAirport *apt)
801 // Ten thousand ft. Slowing down to 150 kts
804 double lat2, lon2, az2;
810 heading = rwy._heading;
811 azimuth = heading + 180.0;
812 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
815 geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
816 rwy._length*0.45 * SG_FEET_TO_METER,
817 &lat2, &lon2, &az2 );
819 wpt->name = "Threshold"; //wpt_node->getStringValue("name", "END");
820 wpt->latitude = lat2;
821 wpt->longitude = lon2;
822 wpt->altitude = apt->getElevation();
824 wpt->crossat = apt->getElevation();
825 wpt->gear_down = true;
826 wpt->flaps_down= true;
827 wpt->finished = false;
828 wpt->on_ground = true;
830 waypoints.push_back(wpt);
832 //Full stop at the runway centerpoint
833 geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
835 &lat2, &lon2, &az2 );
837 wpt->name = "Center"; //wpt_node->getStringValue("name", "END");
838 wpt->latitude = rwy._lat;
839 wpt->longitude = rwy._lon;
840 wpt->altitude = apt->getElevation();
842 wpt->crossat = -10000;
843 wpt->gear_down = true;
844 wpt->flaps_down= true;
845 wpt->finished = false;
846 wpt->on_ground = true;
848 waypoints.push_back(wpt);
850 geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading,
851 rwy._length*0.45 * SG_FEET_TO_METER,
852 &lat2, &lon2, &az2 );
854 wpt->name = "Threshold"; //wpt_node->getStringValue("name", "END");
855 wpt->latitude = lat2;
856 wpt->longitude = lon2;
857 wpt->altitude = apt->getElevation();
859 wpt->crossat = apt->getElevation();
860 wpt->gear_down = true;
861 wpt->flaps_down= true;
862 wpt->finished = false;
863 wpt->on_ground = true;
865 waypoints.push_back(wpt);
868 /*******************************************************************
870 * initialize the Aircraft at the parking location
871 ******************************************************************/
872 void FGAIFlightPlan::createParking(FGAirport *apt, double radius)
879 apt->getDynamics()->getParking(gateId, &lat, &lon, &heading);
883 geo_direct_wgs_84 ( 0, lat, lon, heading,
885 &lat2, &lon2, &az2 );
887 wpt->name = "taxiStart";
888 wpt->latitude = lat2;
889 wpt->longitude = lon2;
890 wpt->altitude = apt->getElevation();
892 wpt->crossat = -10000;
893 wpt->gear_down = true;
894 wpt->flaps_down= true;
895 wpt->finished = false;
896 wpt->on_ground = true;
898 waypoints.push_back(wpt);
899 geo_direct_wgs_84 ( 0, lat, lon, heading,
901 &lat2, &lon2, &az2 );
903 wpt->name = "taxiStart";
904 wpt->latitude = lat2;
905 wpt->longitude = lon2;
906 wpt->altitude = apt->getElevation();
908 wpt->crossat = -10000;
909 wpt->gear_down = true;
910 wpt->flaps_down= true;
911 wpt->finished = false;
912 wpt->on_ground = true;
914 waypoints.push_back(wpt);
917 wpt->name = "END"; //wpt_node->getStringValue("name", "END");
919 wpt->longitude = lon;
920 wpt->altitude = apt->getElevation();
922 wpt->crossat = -10000;
923 wpt->gear_down = true;
924 wpt->flaps_down= true;
925 wpt->finished = false;
926 wpt->on_ground = true;
928 waypoints.push_back(wpt);
933 * @param fltType a string describing the type of
934 * traffic, normally used for gate assignments
935 * @return a converted string that gives the runway
936 * preference schedule to be used at aircraft having
937 * a preferential runway schedule implemented (i.e.
938 * having a rwyprefs.xml file
940 * Currently valid traffic types for gate assignment:
941 * - gate (commercial gate)
942 * - cargo (commercial gargo),
943 * - ga (general aviation) ,
945 * - mil-fighter (military - fighter),
946 * - mil-transport (military - transport)
948 * Valid runway classes:
949 * - com (commercial traffic: jetliners, passenger and cargo)
950 * - gen (general aviation)
951 * - ul (ultralight: I can imagine that these may share a runway with ga on some airports)
952 * - mil (all military traffic)
954 string FGAIFlightPlan::getRunwayClassFromTrafficType(string fltType)
956 if ((fltType == "gate") || (fltType == "cargo")) {
957 return string("com");
959 if (fltType == "ga") {
960 return string ("gen");
962 if (fltType == "ul") {
965 if ((fltType == "mil-fighter") || (fltType == "mil-transport")) {
966 return string("mil");
968 return string("com");