]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/AIFlightPlanCreatePushBack.cxx
compilation fixes for gcc -Wall -Werror
[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 <simgear/math/sg_geodesy.hxx>
26 #include <Airports/runways.hxx>
27 #include <Airports/dynamics.hxx>
28
29 #include <Environment/environment_mgr.hxx>
30 #include <Environment/environment.hxx>
31
32 #include "AIFlightPlan.hxx"
33 #include "AIAircraft.hxx"
34 #include "performancedata.hxx"
35
36
37 // TODO: Use James Turner's createOnGround functions.
38 void FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
39                                     bool firstFlight, FGAirport *dep, 
40                                     double latitude,
41                                     double longitude,
42                                     double radius,
43                                     const string& fltType,
44                                     const string& aircraftType,
45                                     const string& airline)
46 {
47     double lat, lon, heading;
48     double vTaxi = ac->getPerformance()->vTaxi();
49     double vTaxiBackward = vTaxi * (-2.0/3.0);
50     double vTaxiReduced  = vTaxi * (2.0/3.0);
51     FGTaxiRoute *pushBackRoute;
52     // Active runway can be conditionally set by ATC, so at the start of a new flight, this
53     // must be reset.
54     activeRunway.clear();
55
56     if (!(dep->getDynamics()->getGroundNetwork()->exists())) {
57         //cerr << "Push Back fallback" << endl;
58         createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
59                                radius, fltType, aircraftType, airline);
60     } else {
61         if (firstFlight) {
62              
63              if (!(dep->getDynamics()->getAvailableParking(&lat, &lon, 
64                                                            &heading, &gateId, 
65                                                            radius, fltType, 
66                                                            aircraftType, airline))) {
67                     SG_LOG(SG_INPUT, SG_WARN, "Warning: Could not find parking for a " << 
68                                               aircraftType <<
69                                               " of flight type " << fltType << 
70                                               " of airline     " << airline <<
71                                               " at airport     " << dep->getId());
72                     char buffer[10];
73                     snprintf (buffer, 10, "%d", gateId);
74                     //FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
75                     waypoint *wpt;
76                     wpt = new waypoint;
77                     wpt->name      = string(buffer); // fixme: should be the name of the taxiway
78                     wpt->latitude  = lat;
79                     wpt->longitude = lon;
80                     // Elevation is currently disregarded when on_ground is true
81                     // because the AIModel obtains a periodic ground elevation estimate.
82                    wpt->altitude  = dep->getElevation();
83                    wpt->speed = vTaxiBackward;
84                    wpt->crossat   = -10000;
85                    wpt->gear_down = true;
86                    wpt->flaps_down= true;
87                    wpt->finished  = false;
88                    wpt->on_ground = true;
89                    wpt->routeIndex = -1;
90                    waypoints.push_back(wpt);
91             }
92            //cerr << "Success : GateId = " << gateId << endl;
93            SG_LOG(SG_INPUT, SG_WARN, "Warning: Succesfully found a parking for a " << 
94                                               aircraftType <<
95                                               " of flight type " << fltType << 
96                                               " of airline     " << airline <<
97                                               " at airport     " << dep->getId());
98         } else {
99             //cerr << "Push Back follow-up Flight" << endl;
100             dep->getDynamics()->getParking(gateId, &lat, &lon, &heading);
101         }
102         if (gateId < 0) {
103              createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
104                                     radius, fltType, aircraftType, airline);
105              return;
106
107         }
108         //cerr << "getting parking " << gateId;
109         //cerr << " for a " << 
110         //                                      aircraftType <<
111         //                                      " of flight type " << fltType << 
112         //                                      " of airline     " << airline <<
113         //                                      " at airport     " << dep->getId() << endl;
114         FGParking *parking = dep->getDynamics()->getParking(gateId);
115         int pushBackNode = parking->getPushBackPoint();
116
117
118         pushBackRoute = parking->getPushBackRoute();
119         if ((pushBackNode > 0) && (pushBackRoute == 0)) {
120             int node, rte;
121             FGTaxiRoute route;
122             //cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
123             route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
124             parking->setPushBackRoute(new FGTaxiRoute(route));
125             
126
127             pushBackRoute = parking->getPushBackRoute();
128             int size = pushBackRoute->size();
129             if (size < 2) {
130                 SG_LOG(SG_GENERAL, SG_WARN, "Push back route from gate " << gateId << " has only " << size << " nodes.");
131                 SG_LOG(SG_GENERAL, SG_WARN, "Using  " << pushBackNode);
132             }
133             pushBackRoute->first();
134             waypoint *wpt;
135             while(pushBackRoute->next(&node, &rte))
136               {
137                 //FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findSegment(node)->getEnd();
138                 char buffer[10];
139                 snprintf (buffer, 10, "%d", node);
140                 FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
141                 //ids.pop_back();  
142                 wpt = new waypoint;
143                 wpt->name      = string(buffer); // fixme: should be the name of the taxiway
144                 wpt->latitude  = tn->getLatitude();
145                 wpt->longitude = tn->getLongitude();
146                 // Elevation is currently disregarded when on_ground is true
147                 // because the AIModel obtains a periodic ground elevation estimate.
148                 wpt->altitude  = dep->getElevation();
149                 wpt->speed = vTaxiBackward;
150                 wpt->crossat   = -10000;
151                 wpt->gear_down = true;
152                 wpt->flaps_down= true;
153                 wpt->finished  = false;
154                 wpt->on_ground = true;
155                 wpt->routeIndex = rte;
156                 waypoints.push_back(wpt);
157               }
158               // some special considerations for the last point:
159               wpt->name = string("PushBackPoint");
160               wpt->speed = vTaxi;
161               //for (wpt_vector_iterator i = waypoints.begin(); i != waypoints.end(); i++) {
162               //    cerr << "Waypoint Name: " << (*i)->name << endl;
163               //}
164         } else {
165            //cerr << "Creating direct forward departure route fragment" << endl;
166            double lat2 = 0.0, lon2 = 0.0, az2 = 0.0;
167            waypoint *wpt;
168            geo_direct_wgs_84 ( 0, lat, lon, heading, 
169                                2, &lat2, &lon2, &az2 );
170            wpt = new waypoint;
171            wpt->name      = "park2";
172            wpt->latitude  = lat2;
173            wpt->longitude = lon2;
174            wpt->altitude  = dep->getElevation();
175            wpt->speed     = vTaxiReduced; 
176            wpt->crossat   = -10000;
177            wpt->gear_down = true;
178            wpt->flaps_down= true;
179            wpt->finished  = false;
180            wpt->on_ground = true;
181            wpt->routeIndex = 0;
182            waypoints.push_back(wpt); 
183
184            geo_direct_wgs_84 ( 0, lat, lon, heading, 
185                                4, &lat2, &lon2, &az2 );
186            wpt = new waypoint;
187            wpt->name      = "name";
188            wpt->latitude  = lat2;
189            wpt->longitude = lon2;
190            wpt->altitude  = dep->getElevation();
191            wpt->speed     = vTaxiReduced; 
192            wpt->crossat   = -10000;
193            wpt->gear_down = true;
194            wpt->flaps_down= true;
195            wpt->finished  = false;
196            wpt->on_ground = true;
197            wpt->routeIndex = 0;
198            waypoints.push_back(wpt);
199
200            //cerr << "Creating final push forward point for gate " << gateId << endl;
201            FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
202            FGTaxiSegmentVectorIterator ts = tn->getBeginRoute();
203            FGTaxiSegmentVectorIterator te = tn->getEndRoute();
204            if (ts == te) {
205                SG_LOG(SG_GENERAL, SG_ALERT, "Gate " << gateId << "doesn't seem to have routes associated with it.");
206                //exit(1);
207            }
208            tn = (*ts)->getEnd();
209            lastNodeVisited = tn->getIndex();
210            if (tn == NULL) {
211                SG_LOG(SG_GENERAL, SG_ALERT, "No valid taxinode found");
212                exit(1);
213            }
214            wpt = new waypoint;
215            wpt->name      = "PushBackPoint";
216            wpt->latitude  = tn->getLatitude();
217            wpt->longitude = tn->getLongitude();
218            wpt->altitude  = dep->getElevation();
219            wpt->speed     = vTaxiReduced; 
220            wpt->crossat   = -10000;
221            wpt->gear_down = true;
222            wpt->flaps_down= true;
223            wpt->finished  = false;
224            wpt->on_ground = true;
225            wpt->routeIndex = (*ts)->getIndex();
226            waypoints.push_back(wpt);
227
228
229         }
230
231     }
232 }
233 /*******************************************************************
234  * createPushBackFallBack
235  * This is the backup function for airports that don't have a 
236  * network yet. 
237  ******************************************************************/
238 void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight, FGAirport *dep, 
239                                     double latitude,
240                                     double longitude,
241                                     double radius,
242                                     const string& fltType,
243                                     const string& aircraftType,
244                                     const string& airline)
245 {
246   double heading;
247   double lat;
248   double lon;
249   double lat2 = 0.0;
250   double lon2 = 0.0;
251   double az2 = 0.0;
252
253   double vTaxi = ac->getPerformance()->vTaxi();
254   double vTaxiBackward = vTaxi * (-2.0/3.0);
255   double vTaxiReduced  = vTaxi * (2.0/3.0);
256
257
258
259   dep->getDynamics()->getParking(-1, &lat, &lon, &heading);
260
261   heading += 180.0;
262   if (heading > 360)
263     heading -= 360;
264   waypoint *wpt = new waypoint;
265   wpt->name      = "park";
266   wpt->latitude  = lat;
267   wpt->longitude = lon;
268   wpt->altitude  = dep->getElevation();
269   wpt->speed     = vTaxiBackward; 
270   wpt->crossat   = -10000;
271   wpt->gear_down = true;
272   wpt->flaps_down= true;
273   wpt->finished  = false;
274   wpt->on_ground = true;
275
276   waypoints.push_back(wpt); 
277
278   geo_direct_wgs_84 ( 0, lat, lon, heading, 
279                       10, 
280                       &lat2, &lon2, &az2 );
281   wpt = new waypoint;
282   wpt->name      = "park2";
283   wpt->latitude  = lat2;
284   wpt->longitude = lon2;
285   wpt->altitude  = dep->getElevation();
286   wpt->speed     = vTaxiBackward; 
287   wpt->crossat   = -10000;
288   wpt->gear_down = true;
289   wpt->flaps_down= true;
290   wpt->finished  = false;
291   wpt->on_ground = true;
292   wpt->routeIndex = 0;
293   waypoints.push_back(wpt); 
294   geo_direct_wgs_84 ( 0, lat, lon, heading, 
295                       2.2*radius,           
296                       &lat2, &lon2, &az2 );
297   wpt = new waypoint;
298   wpt->name      = "taxiStart";
299   wpt->latitude  = lat2;
300   wpt->longitude = lon2;
301   wpt->altitude  = dep->getElevation();
302   wpt->speed     = vTaxiReduced; 
303   wpt->crossat   = -10000;
304   wpt->gear_down = true;
305   wpt->flaps_down= true;
306   wpt->finished  = false;
307   wpt->on_ground = true;
308   wpt->routeIndex = 0;
309   waypoints.push_back(wpt);
310 }