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->headingDeg();
145 double azimuth = heading + 180.0;
146 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
147 geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
148 rwy->lengthM() * 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->headingDeg();
503 double azimuth = heading + 180.0;
504 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
505 geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
506 rwy->lengthM() * 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->latitude();
536 wpt->longitude = rwy->longitude();
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->latitude(), rwy->longitude(), heading,
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->latitude(), rwy->longitude(), 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);
588 //cerr << "Created takeoff plan : " << endl;
589 //for (wpt_vector_iterator i = waypoints.begin(); i != waypoints.end(); i++) {
590 // cerr << "Waypoint Name: " << (*i)->name << ". Speed = " << (*i)->speed << endl;
594 // geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading,
596 // &lat2, &lon2, &az2 );
597 // wpt = new waypoint;
598 // wpt->name = "5100 ft";
599 // wpt->latitude = lat2;
600 // wpt->longitude = lon2;
601 // wpt->altitude = apt->getElevation()+5100;
602 // wpt->speed = speed;
603 // wpt->crossat = -10000;
604 // wpt->gear_down = true;
605 // wpt->flaps_down= true;
606 // wpt->finished = false;
607 // wpt->on_ground = false;
608 // wpt->routeIndex = 0;
609 // waypoints.push_back(wpt);
612 /*******************************************************************
614 * initialize the Aircraft at the parking location
615 ******************************************************************/
616 void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed, double alt, const string &fltType)
620 double lat2, lon2, az2;
628 string rwyClass = getRunwayClassFromTrafficType(fltType);
629 apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway);
630 rwy = apt->getRunwayByIdent(activeRunway);
634 heading = rwy->headingDeg();
635 double azimuth = heading + 180.0;
636 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
637 //cerr << "Creating climb at : " << rwy._id << " " << rwy._rwy_no << endl;
638 geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading,
640 &lat2, &lon2, &az2 );
642 wpt->name = "10000ft climb";
643 wpt->latitude = lat2;
644 wpt->longitude = lon2;
645 wpt->altitude = 10000;
647 wpt->crossat = -10000;
648 wpt->gear_down = true;
649 wpt->flaps_down= true;
650 wpt->finished = false;
651 wpt->on_ground = false;
653 waypoints.push_back(wpt);
656 geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading,
658 &lat2, &lon2, &az2 );
660 wpt->name = "18000ft climb";
661 wpt->latitude = lat2;
662 wpt->longitude = lon2;
663 wpt->altitude = 18000;
665 wpt->crossat = -10000;
666 wpt->gear_down = true;
667 wpt->flaps_down= true;
668 wpt->finished = false;
669 wpt->on_ground = false;
671 waypoints.push_back(wpt);
675 // /*******************************************************************
677 // * initialize the Aircraft at the parking location
678 // ******************************************************************/
679 // void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep,
680 // FGAirport *arr, double latitude,
681 // double longitude, double speed,
684 // double wind_speed;
685 // double wind_heading;
687 // double lat, lon, az;
688 // double lat2, lon2, az2;
692 // wpt = new waypoint;
693 // wpt->name = "Cruise"; //wpt_node->getStringValue("name", "END");
694 // wpt->latitude = latitude;
695 // wpt->longitude = longitude;
696 // wpt->altitude = alt;
697 // wpt->speed = speed;
698 // wpt->crossat = -10000;
699 // wpt->gear_down = false;
700 // wpt->flaps_down= false;
701 // wpt->finished = false;
702 // wpt->on_ground = false;
703 // waypoints.push_back(wpt);
706 // // should be changed dynamically to allow "gen" and "mil"
707 // arr->getDynamics()->getActiveRunway("com", 2, activeRunway);
708 // if (!(globals->get_runways()->search(arr->getId(),
712 // SG_LOG(SG_INPUT, SG_ALERT, "Failed to find runway " <<
714 // " at airport " << arr->getId());
717 // heading = rwy->headingDeg();
718 // azimuth = heading + 180.0;
719 // while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
722 // geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
724 // &lat2, &lon2, &az2 );
725 // wpt = new waypoint;
726 // wpt->name = "BOD";
727 // wpt->latitude = lat2;
728 // wpt->longitude = lon2;
729 // wpt->altitude = alt;
730 // wpt->speed = speed;
731 // wpt->crossat = alt;
732 // wpt->gear_down = false;
733 // wpt->flaps_down= false;
734 // wpt->finished = false;
735 // wpt->on_ground = false;
736 // waypoints.push_back(wpt);
739 /*******************************************************************
741 * initialize the Aircraft at the parking location
742 ******************************************************************/
743 void FGAIFlightPlan::createDecent(FGAirport *apt, const string &fltType)
746 // Ten thousand ft. Slowing down to 240 kts
749 double lat2, lon2, az2;
754 //Beginning of Decent
756 // allow "mil" and "gen" as well
757 string rwyClass = getRunwayClassFromTrafficType(fltType);
758 apt->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway);
759 rwy = apt->getRunwayByIdent(activeRunway);
761 heading = rwy->headingDeg();
762 azimuth = heading + 180.0;
763 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
764 geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
766 &lat2, &lon2, &az2 );
769 wpt->name = "Dec 10000ft"; //wpt_node->getStringValue("name", "END");
770 wpt->latitude = lat2;
771 wpt->longitude = lon2;
772 wpt->altitude = apt->getElevation();
774 wpt->crossat = 10000;
775 wpt->gear_down = false;
776 wpt->flaps_down= false;
777 wpt->finished = false;
778 wpt->on_ground = false;
780 waypoints.push_back(wpt);
782 // Three thousand ft. Slowing down to 160 kts
783 geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
785 &lat2, &lon2, &az2 );
787 wpt->name = "DEC 3000ft"; //wpt_node->getStringValue("name", "END");
788 wpt->latitude = lat2;
789 wpt->longitude = lon2;
790 wpt->altitude = apt->getElevation();
793 wpt->gear_down = true;
794 wpt->flaps_down= true;
795 wpt->finished = false;
796 wpt->on_ground = false;
798 waypoints.push_back(wpt);
800 /*******************************************************************
802 * initialize the Aircraft at the parking location
803 ******************************************************************/
804 void FGAIFlightPlan::createLanding(FGAirport *apt)
806 // Ten thousand ft. Slowing down to 150 kts
809 double lat2, lon2, az2;
815 heading = rwy->headingDeg();
816 azimuth = heading + 180.0;
817 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
820 geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
821 rwy->lengthM() *0.45,
822 &lat2, &lon2, &az2 );
824 wpt->name = "Threshold"; //wpt_node->getStringValue("name", "END");
825 wpt->latitude = lat2;
826 wpt->longitude = lon2;
827 wpt->altitude = apt->getElevation();
829 wpt->crossat = apt->getElevation();
830 wpt->gear_down = true;
831 wpt->flaps_down= true;
832 wpt->finished = false;
833 wpt->on_ground = true;
835 waypoints.push_back(wpt);
837 //Full stop at the runway centerpoint
838 geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), azimuth,
839 rwy->lengthFt() *0.45,
840 &lat2, &lon2, &az2 );
842 wpt->name = "Center"; //wpt_node->getStringValue("name", "END");
843 wpt->latitude = rwy->latitude();
844 wpt->longitude = rwy->longitude();
845 wpt->altitude = apt->getElevation();
847 wpt->crossat = -10000;
848 wpt->gear_down = true;
849 wpt->flaps_down= true;
850 wpt->finished = false;
851 wpt->on_ground = true;
853 waypoints.push_back(wpt);
855 geo_direct_wgs_84 ( 0, rwy->latitude(), rwy->longitude(), heading,
856 rwy->lengthM() *0.45,
857 &lat2, &lon2, &az2 );
859 wpt->name = "Threshold"; //wpt_node->getStringValue("name", "END");
860 wpt->latitude = lat2;
861 wpt->longitude = lon2;
862 wpt->altitude = apt->getElevation();
864 wpt->crossat = apt->getElevation();
865 wpt->gear_down = true;
866 wpt->flaps_down= true;
867 wpt->finished = false;
868 wpt->on_ground = true;
870 waypoints.push_back(wpt);
873 /*******************************************************************
875 * initialize the Aircraft at the parking location
876 ******************************************************************/
877 void FGAIFlightPlan::createParking(FGAirport *apt, double radius)
884 apt->getDynamics()->getParking(gateId, &lat, &lon, &heading);
888 geo_direct_wgs_84 ( 0, lat, lon, heading,
890 &lat2, &lon2, &az2 );
892 wpt->name = "taxiStart";
893 wpt->latitude = lat2;
894 wpt->longitude = lon2;
895 wpt->altitude = apt->getElevation();
897 wpt->crossat = -10000;
898 wpt->gear_down = true;
899 wpt->flaps_down= true;
900 wpt->finished = false;
901 wpt->on_ground = true;
903 waypoints.push_back(wpt);
904 geo_direct_wgs_84 ( 0, lat, lon, heading,
906 &lat2, &lon2, &az2 );
908 wpt->name = "taxiStart";
909 wpt->latitude = lat2;
910 wpt->longitude = lon2;
911 wpt->altitude = apt->getElevation();
913 wpt->crossat = -10000;
914 wpt->gear_down = true;
915 wpt->flaps_down= true;
916 wpt->finished = false;
917 wpt->on_ground = true;
919 waypoints.push_back(wpt);
922 wpt->name = "END"; //wpt_node->getStringValue("name", "END");
924 wpt->longitude = lon;
925 wpt->altitude = apt->getElevation();
927 wpt->crossat = -10000;
928 wpt->gear_down = true;
929 wpt->flaps_down= true;
930 wpt->finished = false;
931 wpt->on_ground = true;
933 waypoints.push_back(wpt);
938 * @param fltType a string describing the type of
939 * traffic, normally used for gate assignments
940 * @return a converted string that gives the runway
941 * preference schedule to be used at aircraft having
942 * a preferential runway schedule implemented (i.e.
943 * having a rwyprefs.xml file
945 * Currently valid traffic types for gate assignment:
946 * - gate (commercial gate)
947 * - cargo (commercial gargo),
948 * - ga (general aviation) ,
950 * - mil-fighter (military - fighter),
951 * - mil-transport (military - transport)
953 * Valid runway classes:
954 * - com (commercial traffic: jetliners, passenger and cargo)
955 * - gen (general aviation)
956 * - ul (ultralight: I can imagine that these may share a runway with ga on some airports)
957 * - mil (all military traffic)
959 string FGAIFlightPlan::getRunwayClassFromTrafficType(string fltType)
961 if ((fltType == "gate") || (fltType == "cargo")) {
962 return string("com");
964 if (fltType == "ga") {
965 return string ("gen");
967 if (fltType == "ul") {
970 if ((fltType == "mil-fighter") || (fltType == "mil-transport")) {
971 return string("mil");
973 return string("com");