]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/AIFlightPlanCreatePushBack.cxx
Fix a Clang warning, checking signed char as if it was unsigned.
[flightgear.git] / src / AIModel / AIFlightPlanCreatePushBack.cxx
1 /****************************************************************************
2 * AIFlightPlanCreatePushBack.cxx
3 * Written by Durk Talsma, started August 1, 2007.
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 *
19 **************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #  include <config.h>
23 #endif
24
25 #include <cstdlib>
26
27 #include <simgear/math/sg_geodesy.hxx>
28
29 #include <Airports/simple.hxx>
30 #include <Airports/runways.hxx>
31 #include <Airports/dynamics.hxx>
32
33 #include <Environment/environment_mgr.hxx>
34 #include <Environment/environment.hxx>
35
36 #include "AIFlightPlan.hxx"
37 #include "AIAircraft.hxx"
38 #include "performancedata.hxx"
39
40
41 // TODO: Use James Turner's createOnGround functions.
42 bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
43                                     bool firstFlight, FGAirport *dep,
44                                     double latitude,
45                                     double longitude,
46                                     double radius,
47                                     const string& fltType,
48                                     const string& aircraftType,
49                                     const string& airline)
50 {
51     double lat, lon, heading;
52     double vTaxi = ac->getPerformance()->vTaxi();
53     double vTaxiBackward = vTaxi * (-2.0/3.0);
54     double vTaxiReduced  = vTaxi * (2.0/3.0);
55     FGTaxiRoute *pushBackRoute;
56     // Active runway can be conditionally set by ATC, so at the start of a new flight, this
57     // must be reset.
58     activeRunway.clear();
59
60     if (!(dep->getDynamics()->getGroundNetwork()->exists())) {
61         //cerr << "Push Back fallback" << endl;
62         createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
63                                radius, fltType, aircraftType, airline);
64     } else {
65         if (firstFlight) {
66
67             if (!(dep->getDynamics()->getAvailableParking(&lat, &lon,
68                     &heading, &gateId,
69                     radius, fltType,
70                     aircraftType, airline))) {
71                 SG_LOG(SG_AI, SG_WARN, "Warning: Could not find parking for a " <<
72                        aircraftType <<
73                        " of flight type " << fltType <<
74                        " of airline     " << airline <<
75                        " at airport     " << dep->getId());
76                 return false;
77                 char buffer[10];
78                 snprintf (buffer, 10, "%d", gateId);
79                 SGGeod coord = coord.fromDeg(lon, lat);
80                 //FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
81                 FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
82                 wpt->setRouteIndex(-1);
83                 pushBackWaypoint(wpt);
84             }
85             //cerr << "Success : GateId = " << gateId << endl;
86             SG_LOG(SG_AI, SG_WARN, "Warning: Succesfully found a parking for a " <<
87                    aircraftType <<
88                    " of flight type " << fltType <<
89                    " of airline     " << airline <<
90                    " at airport     " << dep->getId());
91         } else {
92             //cerr << "Push Back follow-up Flight" << endl;
93             dep->getDynamics()->getParking(gateId, &lat, &lon, &heading);
94         }
95         if (gateId < 0) {
96             createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
97                                    radius, fltType, aircraftType, airline);
98             return true;
99
100         }
101         //cerr << "getting parking " << gateId;
102         //cerr << " for a " <<
103         //                                      aircraftType <<
104         //                                      " of flight type " << fltType <<
105         //                                      " of airline     " << airline <<
106         //                                      " at airport     " << dep->getId() << endl;
107         FGParking *parking = dep->getDynamics()->getParking(gateId);
108         int pushBackNode = parking->getPushBackPoint();
109
110
111         pushBackRoute = parking->getPushBackRoute();
112         if ((pushBackNode > 0) && (pushBackRoute == 0)) {  // Load the already established route for this gate
113             int node, rte;
114             FGTaxiRoute route;
115             //cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
116             route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
117             parking->setPushBackRoute(new FGTaxiRoute(route));
118
119
120             pushBackRoute = parking->getPushBackRoute();
121             int size = pushBackRoute->size();
122             if (size < 2) {
123                 SG_LOG(SG_AI, SG_ALERT, "Push back route from gate " << gateId << " has only " << size << " nodes.");
124                 SG_LOG(SG_AI, SG_ALERT, "Using  " << pushBackNode);
125             }
126             pushBackRoute->first();
127             while (pushBackRoute->next(&node, &rte))
128             {
129                 //FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findSegment(node)->getEnd();
130                 char buffer[10];
131                 snprintf (buffer, 10, "%d", node);
132                 FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
133                 //ids.pop_back();
134                 //wpt = new waypoint;
135                 SGGeod coord = coord.fromDeg(tn->getLongitude(), tn->getLatitude());
136                 FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
137
138                 wpt->setRouteIndex(rte);
139                 pushBackWaypoint(wpt);
140             }
141             // some special considerations for the last point:
142             waypoints.back()->setName(string("PushBackPoint"));
143             waypoints.back()->setSpeed(vTaxi);
144             ac->setTaxiClearanceRequest(true);
145         } else {  // In case of a push forward departure...
146             ac->setTaxiClearanceRequest(false);
147             double lat2 = 0.0, lon2 = 0.0, az2 = 0.0;
148
149             //cerr << "Creating final push forward point for gate " << gateId << endl;
150             FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
151             FGTaxiSegmentVectorIterator ts = tn->getBeginRoute();
152             FGTaxiSegmentVectorIterator te = tn->getEndRoute();
153             // if the starting node equals the ending node, then there aren't any routes for this parking.
154             // in cases like these we should flag the gate as being inoperative and return false
155             if (ts == te) {
156                 SG_LOG(SG_AI, SG_ALERT, "Gate " << gateId << "doesn't seem to have routes associated with it.");
157                 parking->setAvailable(false);
158                 return false;
159             }
160             tn = (*ts)->getEnd();
161             lastNodeVisited = tn->getIndex();
162             if (tn == NULL) {
163                 SG_LOG(SG_AI, SG_ALERT, "No valid taxinode found");
164                 exit(1);
165             }
166             double distance = (*ts)->getLength();
167             //cerr << "Length of push forward route = " << distance << " and heading is " << heading << endl;
168             lat2 =  tn->getLatitude();
169             lon2 =  tn->getLongitude();
170
171             for (int i = 1; i < 10; i++) {
172                 geo_direct_wgs_84 ( 0, lat, lon, heading,
173                                     ((i / 10.0) * distance), &lat2, &lon2, &az2 );
174                 char buffer[16];
175                 snprintf(buffer, 16, "pushback-%02d", i);
176                 SGGeod coord = coord.fromDeg(lon2, lat2);
177                 //cerr << i << endl;
178                 FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiReduced);
179
180                 wpt->setRouteIndex((*ts)->getIndex());
181                 pushBackWaypoint(wpt);
182             }
183             // cerr << "Done " << endl;
184             waypoints.back()->setName(string("PushBackPoint"));
185             // cerr << "Done assinging new name" << endl;
186         }
187     }
188     return true;
189 }
190 /*******************************************************************
191 * createPushBackFallBack
192 * This is the backup function for airports that don't have a
193 * network yet.
194 ******************************************************************/
195 void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight, FGAirport *dep,
196         double latitude,
197         double longitude,
198         double radius,
199         const string& fltType,
200         const string& aircraftType,
201         const string& airline)
202 {
203     double heading;
204     double lat;
205     double lon;
206     double lat2 = 0.0;
207     double lon2 = 0.0;
208     double az2 = 0.0;
209
210     double vTaxi = ac->getPerformance()->vTaxi();
211     double vTaxiBackward = vTaxi * (-2.0/3.0);
212     double vTaxiReduced  = vTaxi * (2.0/3.0);
213
214
215
216     dep->getDynamics()->getParking(-1, &lat, &lon, &heading);
217
218     heading += 180.0;
219     if (heading > 360)
220         heading -= 360;
221
222     SGGeod coord = coord.fromDeg(lon, lat);
223     FGAIWaypoint *wpt = createOnGround(ac, string("park"), coord, dep->getElevation(), vTaxiBackward);
224
225     pushBackWaypoint(wpt);
226
227     geo_direct_wgs_84 ( 0, lat, lon, heading,
228                         10,
229                         &lat2, &lon2, &az2 );
230     coord = coord.fromDeg(lon2, lat2);
231     wpt = createOnGround(ac, string("park2"), coord, dep->getElevation(), vTaxiBackward);
232
233     pushBackWaypoint(wpt);
234
235     geo_direct_wgs_84 ( 0, lat, lon, heading,
236                         2.2*radius,
237                         &lat2, &lon2, &az2 );
238     coord = coord.fromDeg(lon2, lat2);
239     wpt = createOnGround(ac, string("taxiStart"), coord, dep->getElevation(), vTaxiReduced);
240     pushBackWaypoint(wpt);
241
242 }