]> git.mxchange.org Git - flightgear.git/blobdiff - src/AIModel/AIAircraft.cxx
* A new algorithm for determining hold position instructions. This version still...
[flightgear.git] / src / AIModel / AIAircraft.cxx
index 30b7cf9d3be6f2dbe7781e2f28867b91af66c093..98d2782f564b564d6315593e5dcd18870cd60cbe 100644 (file)
@@ -1,4 +1,4 @@
-// // FGAIAircraft - FGAIBase-derived class creates an AI airplane
+// FGAIAircraft - FGAIBase-derived class creates an AI airplane
 //
 // Written by David Culp, started October 2003.
 //
@@ -48,6 +48,8 @@ using std::string;
 #include "performancedata.hxx"
 #include "performancedb.hxx"
 
+
+#define TGT_VS_CUTOFF 10000
 //#include <Airports/trafficcontroller.hxx>
 
 static string tempReg;
@@ -65,9 +67,10 @@ FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
     else
         groundOffset = 0;
 
-    fp = 0;
-    controller = 0;
-    prevController = 0;
+    fp              = 0;
+    controller      = 0;
+    prevController  = 0;
+    towerController = 0;
     dt_count = 0;
     dt_elev_count = 0;
     use_perf_vs = true;
@@ -92,6 +95,7 @@ FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
 
     _performance = 0; //TODO initialize to JET_TRANSPORT from PerformanceDB
     dt = 0;
+    takeOffStatus = 0;
 }
 
 
@@ -153,6 +157,7 @@ void FGAIAircraft::setPerformance(const std::string& acclass) {
 
 
  void FGAIAircraft::Run(double dt) {
+      
       FGAIAircraft::dt = dt;
     
      bool outOfSight = false, 
@@ -353,9 +358,14 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
             tgt_altitude_ft = prev->getAltitude();
             if (curr->getCrossat() > -1000.0) {
                 use_perf_vs = false;
-                tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
-                         / 6076.0 / speed*60.0);
-                checkTcas();
+//                 tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
+//                          / 6076.0 / speed*60.0);
+//                 if (fabs(tgt_vs) > TGT_VS_CUTOFF) { SG_LOG(SG_GENERAL, SG_ALERT, "Rediculously high vertical speed caculated at " << SG_ORIGIN << ". Corresponding to " << (tgt_vs * .005) << "degrees of pitch angle" << prev->getName()); };
+//                 if (tgt_vs < -1500)
+//                     tgt_vs = -1500;
+//                 if (tgt_vs > 1500) 
+//                     tgt_vs = 1500;
+//                 checkTcas();
                 tgt_altitude_ft = curr->getCrossat();
             } else {
                 use_perf_vs = true;
@@ -495,6 +505,7 @@ void FGAIAircraft::getGroundElev(double dt) {
 
 
 void FGAIAircraft::doGroundAltitude() {
+
     if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)||
         (isStationary()))
         altitude_ft = (tgt_altitude_ft + groundOffset);
@@ -555,6 +566,26 @@ void FGAIAircraft::announcePositionToController() {
     }
 }
 
+void FGAIAircraft::scheduleForATCTowerDepartureControl(int state) {
+    if (!takeOffStatus) {
+        int leg = fp->getLeg();
+        if (trafficRef) {
+            if (trafficRef->getDepartureAirport()->getDynamics()) {
+                towerController = trafficRef->getDepartureAirport()->getDynamics()->getTowerController();
+            } else {
+                cerr << "Error: Could not find Dynamics at airport : " << trafficRef->getDepartureAirport()->getId() << endl;
+            }
+            if (towerController) {
+                towerController->announcePosition(getID(), fp, fp->getCurrentWaypoint()->getRouteIndex(),
+                                                   _getLatitude(), _getLongitude(), hdg, speed, altitude_ft,
+                                                    trafficRef->getRadius(), leg, this);
+                //cerr << "Scheduling " << trafficRef->getCallSign() << " for takeoff " << endl;
+            }
+        }
+    }
+    takeOffStatus = state;
+}
+
 // Process ATC instructions and report back
 
 void FGAIAircraft::processATC(FGATCInstruction instruction) {
@@ -654,10 +685,11 @@ void FGAIAircraft::handleFirstWaypoint() {
     if (curr->getCrossat() > -1000.0) //use a calculated descent/climb rate
     {
         use_perf_vs = false;
-        tgt_vs = (curr->getCrossat() - prev->getAltitude())
+/*        tgt_vs = (curr->getCrossat() - prev->getAltitude())
                  / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
                     / 6076.0 / prev->getSpeed()*60.0);
-        checkTcas();
+        if (fabs(tgt_vs) > TGT_VS_CUTOFF) { SG_LOG(SG_GENERAL, SG_ALERT, "Rediculously high vertical speed caculated at " << SG_ORIGIN); };
+        checkTcas();*/
         tgt_altitude_ft = curr->getCrossat();
     } else {
         use_perf_vs = true;
@@ -741,10 +773,10 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
     } 
     if (trafficRef) {
          //cerr << "Tracking callsign : \"" << fgGetString("/ai/track-callsign") << "\"" << endl;
-/*         if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
+         if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
               cerr << trafficRef->getCallSign() << " " << tgt_altitude_ft << " " << _getSpeed() << " " 
-                   << _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->name << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << endl; 
-         }*/
+                   << _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->getName() << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << " " << invisible << endl; 
+         }
      }
     if ((dist_to_go < lead_dist) || (bearing > (minBearing * 1.1))) {
         minBearing = 360;
@@ -783,14 +815,19 @@ bool FGAIAircraft::handleAirportEndPoints(FGAIWaypoint* prev, time_t now) {
     // This waypoint marks the fact that the aircraft has passed the initial taxi
     // departure waypoint, so it can release the parking.
     //cerr << trafficRef->getCallSign() << " has passed waypoint " << prev->name << " at speed " << speed << endl;
+    //cerr << "Passing waypoint : " << prev->getName() << endl;
     if (prev->contains("PushBackPoint")) {
         dep->getDynamics()->releaseParking(fp->getGate());
         AccelTo(0.0);
-        setTaxiClearanceRequest(true);
+        //setTaxiClearanceRequest(true);
     }
     if (prev->contains("legend")) {
         fp->incrementLeg();
     }
+    if (prev->contains(string("DepartureHold"))) {
+        //cerr << "Passing point DepartureHold" << endl;
+        scheduleForATCTowerDepartureControl(2);
+    }
 
     // This is the last taxi waypoint, and marks the the end of the flight plan
     // so, the schedule should update and wait for the next departure time.
@@ -800,7 +837,7 @@ bool FGAIAircraft::handleAirportEndPoints(FGAIWaypoint* prev, time_t now) {
         if (nextDeparture < (now+1200)) {
             nextDeparture = now + 1200;
         }
-        fp->setTime(nextDeparture); // should be "next departure"
+        fp->setTime(nextDeparture);
     }
 
     return true;
@@ -1186,20 +1223,20 @@ bool FGAIAircraft::reachedEndOfCruise(double &distance) {
         double distanceCovered   = descentSpeed * descentTimeNeeded; 
 
         //cerr << "Tracking  : " << fgGetString("/ai/track-callsign");
-        if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
-            cerr << "Checking for end of cruise stage for :" << trafficRef->getCallSign() << endl;
-            cerr << "Descent rate      : " << descentRate << endl;
-            cerr << "Descent speed     : " << descentSpeed << endl;
-            cerr << "VerticalDistance  : " << verticalDistance << ". Altitude : " << altitude_ft << ". Elevation " << trafficRef->getArrivalAirport()->getElevation() << endl;
-            cerr << "DecentTimeNeeded  : " << descentTimeNeeded << endl;
-            cerr << "DistanceCovered   : " << distanceCovered   << endl;
-        }
+//         if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
+//             cerr << "Checking for end of cruise stage for :" << trafficRef->getCallSign() << endl;
+//             cerr << "Descent rate      : " << descentRate << endl;
+//             cerr << "Descent speed     : " << descentSpeed << endl;
+//             cerr << "VerticalDistance  : " << verticalDistance << ". Altitude : " << altitude_ft << ". Elevation " << trafficRef->getArrivalAirport()->getElevation() << endl;
+//             cerr << "DecentTimeNeeded  : " << descentTimeNeeded << endl;
+//             cerr << "DistanceCovered   : " << distanceCovered   << endl;
+//         }
         //cerr << "Distance = " << distance << endl;
         distance = distanceCovered;
         if (dist < distanceCovered) {
-              if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
-                   //exit(1);
-              }
+//               if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
+//                    //exit(1);
+//               }
               return true;
         } else {
               return false;
@@ -1253,8 +1290,8 @@ time_t FGAIAircraft::checkForArrivalTime(string wptName) {
      
      time_t ete = tracklength / ((speed * SG_NM_TO_METER) / 3600.0); 
      time_t secondsToGo = arrivalTime - now;
-     if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {    
-          cerr << "Checking arrival time: ete " << ete << ". Time to go : " << secondsToGo << ". Track length = " << tracklength << endl;
-     }
+//      if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {    
+//           cerr << "Checking arrival time: ete " << ete << ". Time to go : " << secondsToGo << ". Track length = " << tracklength << endl;
+//      }
      return (ete - secondsToGo); // Positive when we're too slow...
 }