]> git.mxchange.org Git - flightgear.git/blobdiff - src/AIModel/AIFlightPlanCreatePushBack.cxx
AIManager cleanups, no functionality change.
[flightgear.git] / src / AIModel / AIFlightPlanCreatePushBack.cxx
index bf256bac94b29ec3cdc05c7b3156adf3f1346b19..976463ccf74867e0396afe658fd41495627a4677 100644 (file)
 // TODO: Use James Turner's createOnGround functions.
 bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
                                     bool firstFlight, FGAirport *dep,
-                                    double latitude,
-                                    double longitude,
                                     double radius,
                                     const string& fltType,
                                     const string& aircraftType,
                                     const string& airline)
 {
-    double lat, lon, heading;
     double vTaxi = ac->getPerformance()->vTaxi();
     double vTaxiBackward = vTaxi * (-2.0/3.0);
     double vTaxiReduced  = vTaxi * (2.0/3.0);
-    FGTaxiRoute *pushBackRoute;
     // Active runway can be conditionally set by ATC, so at the start of a new flight, this
     // must be reset.
     activeRunway.clear();
 
     if (!(dep->getDynamics()->getGroundNetwork()->exists())) {
         //cerr << "Push Back fallback" << endl;
-        createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
+        createPushBackFallBack(ac, firstFlight, dep,
                                radius, fltType, aircraftType, airline);
-    } else {
-        if (firstFlight) {
-
-            if (!(dep->getDynamics()->getAvailableParking(&lat, &lon,
-                    &heading, &gateId,
-                    radius, fltType,
-                    aircraftType, airline))) {
-                SG_LOG(SG_AI, SG_WARN, "Warning: Could not find parking for a " <<
-                       aircraftType <<
-                       " of flight type " << fltType <<
-                       " of airline     " << airline <<
-                       " at airport     " << dep->getId());
-                return false;
-                char buffer[10];
-                snprintf (buffer, 10, "%d", gateId);
-                SGGeod coord = coord.fromDeg(lon, lat);
-                //FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
-                FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
-                wpt->setRouteIndex(-1);
-                pushBackWaypoint(wpt);
-            }
-            //cerr << "Success : GateId = " << gateId << endl;
-            SG_LOG(SG_AI, SG_WARN, "Warning: Successfully found a parking for a " <<
-                   aircraftType <<
-                   " of flight type " << fltType <<
-                   " of airline     " << airline <<
-                   " at airport     " << dep->getId());
-        } else {
-            //cerr << "Push Back follow-up Flight" << endl;
-            dep->getDynamics()->getParking(gateId, &lat, &lon, &heading);
-        }
-        if (gateId < 0) {
-            createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
-                                   radius, fltType, aircraftType, airline);
-            return true;
+      return true;
+    }
+  
+  // establish the parking position / gate if required
+    if (firstFlight) {
+      gate = dep->getDynamics()->getAvailableParking(radius, fltType,
+                                                       aircraftType, airline);
+      if (!gate.isValid()) {
+        SG_LOG(SG_AI, SG_WARN, "Warning: Could not find parking for a " <<
+               aircraftType <<
+               " of flight type " << fltType <<
+               " of airline     " << airline <<
+               " at airport     " << dep->getId());
+        return false;
+      }
+    }
+  
+    if (!gate.isValid()) {
+        createPushBackFallBack(ac, firstFlight, dep,
+                               radius, fltType, aircraftType, airline);
+        return true;
 
+    }
+  
+    FGGroundNetwork* groundNet = dep->getDynamics()->getGroundNetwork();
+    FGParking *parking = gate.parking();
+    if (parking && parking->getPushBackPoint() > 0) {
+        FGTaxiRoute route = groundNet->findShortestRoute(parking->guid(), parking->getPushBackPoint(), false);
+      
+        int size = route.size();
+        if (size < 2) {
+            SG_LOG(SG_AI, SG_ALERT, "Push back route from gate " << parking->ident() << " has only " << size << " nodes.");
+            SG_LOG(SG_AI, SG_ALERT, "Using  " << parking->getPushBackPoint());
         }
-        //cerr << "getting parking " << gateId;
-        //cerr << " for a " <<
-        //                                      aircraftType <<
-        //                                      " of flight type " << fltType <<
-        //                                      " of airline     " << airline <<
-        //                                      " at airport     " << dep->getId() << endl;
-        FGParking *parking = dep->getDynamics()->getParking(gateId);
-        int pushBackNode = parking->getPushBackPoint();
-
-
-        pushBackRoute = parking->getPushBackRoute();
-        if ((pushBackNode > 0) && (pushBackRoute == 0)) {  // Load the already established route for this gate
-            int node, rte;
-            FGTaxiRoute route;
-            //cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
-            route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
-            parking->setPushBackRoute(new FGTaxiRoute(route));
-
-
-            pushBackRoute = parking->getPushBackRoute();
-            int size = pushBackRoute->size();
-            if (size < 2) {
-                SG_LOG(SG_AI, SG_ALERT, "Push back route from gate " << gateId << " has only " << size << " nodes.");
-                SG_LOG(SG_AI, SG_ALERT, "Using  " << pushBackNode);
-            }
-            pushBackRoute->first();
-            while (pushBackRoute->next(&node, &rte))
-            {
-                //FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findSegment(node)->getEnd();
-                char buffer[10];
-                snprintf (buffer, 10, "%d", node);
-                FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
-                //ids.pop_back();
-                //wpt = new waypoint;
-                SGGeod coord = coord.fromDeg(tn->getLongitude(), tn->getLatitude());
-                FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
-
-                wpt->setRouteIndex(rte);
-                pushBackWaypoint(wpt);
-            }
-            // some special considerations for the last point:
-            waypoints.back()->setName(string("PushBackPoint"));
-            waypoints.back()->setSpeed(vTaxi);
-            ac->setTaxiClearanceRequest(true);
-        } else {  // In case of a push forward departure...
-            ac->setTaxiClearanceRequest(false);
-            double lat2 = 0.0, lon2 = 0.0, az2 = 0.0;
-
-            //cerr << "Creating final push forward point for gate " << gateId << endl;
-            FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
-            FGTaxiSegmentVectorIterator ts = tn->getBeginRoute();
-            FGTaxiSegmentVectorIterator te = tn->getEndRoute();
-            // if the starting node equals the ending node, then there aren't any routes for this parking.
-            // in cases like these we should flag the gate as being inoperative and return false
-            if (ts == te) {
-                SG_LOG(SG_AI, SG_ALERT, "Gate " << gateId << "doesn't seem to have routes associated with it.");
-                parking->setAvailable(false);
-                return false;
+        
+        route.first();
+        PositionedID node, previous= 0;
+      
+        while (route.next(&node))
+        {
+            char buffer[10];
+            snprintf (buffer, 10, "%lld", node);
+            FGTaxiNode *tn = groundNet->findNode(node);
+            FGAIWaypoint *wpt = createOnGround(ac, string(buffer), tn->geod(), dep->getElevation(), vTaxiBackward);
+          
+            if (previous) {
+              FGTaxiSegment* segment = groundNet->findSegment(previous, node);
+              wpt->setRouteIndex(segment->getIndex());
+            } else {
+              // not on the route yet, make up a unique segment ID
+              int x = (int) tn->guid();
+              wpt->setRouteIndex(x);
             }
-            tn = (*ts)->getEnd();
-            lastNodeVisited = tn->getIndex();
-            if (tn == NULL) {
-                SG_LOG(SG_AI, SG_ALERT, "No valid taxinode found");
-                exit(1);
-            }
-            double distance = (*ts)->getLength();
-            //cerr << "Length of push forward route = " << distance << " and heading is " << heading << endl;
-            lat2 =  tn->getLatitude();
-            lon2 =  tn->getLongitude();
-
-            for (int i = 1; i < 10; i++) {
-                geo_direct_wgs_84 ( 0, lat, lon, heading,
-                                    ((i / 10.0) * distance), &lat2, &lon2, &az2 );
-                char buffer[16];
-                snprintf(buffer, 16, "pushback-%02d", i);
-                SGGeod coord = coord.fromDeg(lon2, lat2);
-                //cerr << i << endl;
-                FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiReduced);
-
-                wpt->setRouteIndex((*ts)->getIndex());
-                pushBackWaypoint(wpt);
-            }
-            // cerr << "Done " << endl;
-            waypoints.back()->setName(string("PushBackPoint"));
-            // cerr << "Done assinging new name" << endl;
+          
+            pushBackWaypoint(wpt);
+            previous = node;
         }
+        // some special considerations for the last point:
+        waypoints.back()->setName(string("PushBackPoint"));
+        waypoints.back()->setSpeed(vTaxi);
+        ac->setTaxiClearanceRequest(true);
+    } else {  // In case of a push forward departure...
+        ac->setTaxiClearanceRequest(false);
+        double az2 = 0.0;
+
+      FGTaxiSegment* pushForwardSegment = dep->getDynamics()->getGroundNetwork()->findSegment(parking->guid(), 0);
+      // there aren't any routes for this parking.
+      if (!pushForwardSegment) {
+          SG_LOG(SG_AI, SG_ALERT, "Gate " << parking->ident() << "doesn't seem to have routes associated with it.");
+          return false;
+      }
+
+      lastNodeVisited = pushForwardSegment->getEnd()->getIndex();
+      double distance = pushForwardSegment->getLength();
+
+      double parkingHeading = parking->getHeading();
+    
+      for (int i = 1; i < 10; i++) {
+          SGGeod pushForwardPt;
+          SGGeodesy::direct(parking->geod(), parkingHeading,
+                            ((i / 10.0) * distance), pushForwardPt, az2);
+          char buffer[16];
+          snprintf(buffer, 16, "pushback-%02d", i);
+          FGAIWaypoint *wpt = createOnGround(ac, string(buffer), pushForwardPt, dep->getElevation(), vTaxiReduced);
+
+          wpt->setRouteIndex(pushForwardSegment->getIndex());
+          pushBackWaypoint(wpt);
+      }
+
+      waypoints.back()->setName(string("PushBackPoint"));
+      // cerr << "Done assinging new name" << endl;
     }
+
     return true;
 }
 /*******************************************************************
@@ -193,49 +158,29 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
 * network yet.
 ******************************************************************/
 void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight, FGAirport *dep,
-        double latitude,
-        double longitude,
         double radius,
         const string& fltType,
         const string& aircraftType,
         const string& airline)
 {
-    double heading;
-    double lat;
-    double lon;
-    double lat2 = 0.0;
-    double lon2 = 0.0;
     double az2 = 0.0;
 
     double vTaxi = ac->getPerformance()->vTaxi();
     double vTaxiBackward = vTaxi * (-2.0/3.0);
     double vTaxiReduced  = vTaxi * (2.0/3.0);
 
-
-
-    dep->getDynamics()->getParking(-1, &lat, &lon, &heading);
-
-    heading += 180.0;
-    if (heading > 360)
-        heading -= 360;
-
-    SGGeod coord = coord.fromDeg(lon, lat);
-    FGAIWaypoint *wpt = createOnGround(ac, string("park"), coord, dep->getElevation(), vTaxiBackward);
+    double heading = 180.0; // this is a completely arbitrary heading!
+    FGAIWaypoint *wpt = createOnGround(ac, string("park"), dep->geod(), dep->getElevation(), vTaxiBackward);
 
     pushBackWaypoint(wpt);
 
-    geo_direct_wgs_84 ( 0, lat, lon, heading,
-                        10,
-                        &lat2, &lon2, &az2 );
-    coord = coord.fromDeg(lon2, lat2);
+    SGGeod coord;
+    SGGeodesy::direct(dep->geod(), heading, 10, coord, az2);
     wpt = createOnGround(ac, string("park2"), coord, dep->getElevation(), vTaxiBackward);
 
     pushBackWaypoint(wpt);
-
-    geo_direct_wgs_84 ( 0, lat, lon, heading,
-                        2.2*radius,
-                        &lat2, &lon2, &az2 );
-    coord = coord.fromDeg(lon2, lat2);
+  
+    SGGeodesy::direct(dep->geod(), heading, 2.2 * radius, coord, az2);
     wpt = createOnGround(ac, string("taxiStart"), coord, dep->getElevation(), vTaxiReduced);
     pushBackWaypoint(wpt);