]> git.mxchange.org Git - flightgear.git/blobdiff - src/AIModel/AIAircraft.cxx
merging in topic/makej
[flightgear.git] / src / AIModel / AIAircraft.cxx
index c73919d0a39dbafab322b9ca7c94b620d16df9f4..3f8bb05a871351cf1dbf559baf0e86cead70a246 100644 (file)
 #  include <config.h>
 #endif
 
-#include <simgear/math/point3d.hxx>
 #include <simgear/route/waypoint.hxx>
 #include <Main/fg_props.hxx>
 #include <Main/globals.hxx>
 #include <Main/viewer.hxx>
 #include <Scenery/scenery.hxx>
 #include <Scenery/tilemgr.hxx>
+#include <Airports/dynamics.hxx>
 
 #include <string>
 #include <math.h>
@@ -40,7 +40,7 @@
 #  include <ieeefp.h>
 #endif
 
-SG_USING_STD(string);
+using std::string;
 
 #include "AIAircraft.hxx"
 #include "performancedata.hxx"
@@ -150,15 +150,36 @@ void FGAIAircraft::setPerformance(const std::string& acclass) {
          return;
      }
      catch (FP_Inactive) {
-         return;
+         //return;
+         groundTargetSpeed = 0;
      }
 
      handleATCRequests(); // ATC also has a word to say
      updateSecondaryTargetValues(); // target roll, vertical speed, pitch
      updateActualState(); 
      UpdateRadar(manager);
+     checkVisibility();
   }
 
+void FGAIAircraft::checkVisibility() 
+{
+     double visibility_meters = fgGetDouble("/environment/visibility-m");
+
+     FGViewer* vw = globals->get_current_view();
+     double course, distance;
+
+     SGWayPoint current(pos.getLongitudeDeg(), pos.getLatitudeDeg(), 0);
+     SGWayPoint view (vw->getLongitude_deg(), vw->getLatitude_deg(), 0);
+     view.CourseAndDistance(current, &course, &distance);
+     if (distance > visibility_meters) {
+         //aip.getSGLocation()->set_cur_elev_m(aptElev);
+         //return;
+         invisible = true;
+      } else {
+         invisible = false;
+      }
+}
+
 
 
 void FGAIAircraft::AccelTo(double speed) {
@@ -266,7 +287,10 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
         //TODO let the fp handle this (loading of next leg)
         fp->IncrementWaypoint((bool) trafficRef);
         if (!(fp->getNextWaypoint()) && trafficRef)
-            loadNextLeg();
+            if (!loadNextLeg()) {
+                setDie(true);
+                return;
+            }
 
         prev = fp->getPreviousWaypoint();
         curr = fp->getCurrentWaypoint();
@@ -321,13 +345,14 @@ bool FGAIAircraft::_getGearDown() const {
 }
 
 
-void FGAIAircraft::loadNextLeg() {
+bool FGAIAircraft::loadNextLeg() {
 
     int leg;
     if ((leg = fp->getLeg())  == 10) {
-        trafficRef->next();
+        if (!trafficRef->next()) {
+            return false;
+        }
         setCallSign(trafficRef->getCallSign());
-       //props->setStringValue("callsign", callsign.c_str());
         leg = 1;
         fp->setLeg(leg);
     }
@@ -340,10 +365,11 @@ void FGAIAircraft::loadNextLeg() {
     } else {
         double cruiseAlt = trafficRef->getCruiseAlt() * 100;
 
-        fp->create (dep,
+        fp->create (this,
+                    dep,
                     arr,
                     leg,
-                    cruiseAlt,           //(trafficRef->getCruiseAlt() * 100), // convert from FL to feet
+                    cruiseAlt,
                     trafficRef->getSpeed(),
                     _getLatitude(),
                     _getLongitude(),
@@ -352,7 +378,9 @@ void FGAIAircraft::loadNextLeg() {
                     trafficRef->getFlightType(),
                     acType,
                     company);
+       //cerr << "created  leg " << leg << " for " << trafficRef->getCallSign() << endl;
     }
+    return true;
 }
 
 
@@ -365,7 +393,7 @@ void FGAIAircraft::getGroundElev(double dt) {
     dt_elev_count += dt;
 
     // Update minimally every three secs, but add some randomness
-    // to prevent all IA objects doing this in synchrony
+    // to prevent all AI objects doing this in synchrony
     if (dt_elev_count < (3.0) + (rand() % 10))
         return;
 
@@ -413,10 +441,14 @@ void FGAIAircraft::announcePositionToController() {
     if (trafficRef) {
         int leg = fp->getLeg();
 
-        // Note that leg was been incremented after creating the current leg, so we should use
+        // Note that leg has been incremented after creating the current leg, so we should use
         // leg numbers here that are one higher than the number that is used to create the leg
         //
         switch (leg) {
+          case 2:              // Startup and Push back
+            if (trafficRef->getDepartureAirport()->getDynamics())
+                controller = trafficRef->getDepartureAirport()->getDynamics()->getStartupController();
+            break;
         case 3:              // Taxiing to runway
             if (trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork()->exists())
                 controller = trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork();
@@ -425,12 +457,14 @@ void FGAIAircraft::announcePositionToController() {
             if (trafficRef->getDepartureAirport()->getDynamics()) {
                 controller = trafficRef->getDepartureAirport()->getDynamics()->getTowerController();
                 //if (trafficRef->getDepartureAirport()->getId() == "EHAM") {
-                //cerr << trafficRef->getCallSign() << " at runway " << fp->getRunway() << "Ready for departure "
-                //   << trafficRef->getFlightType() << " to " << trafficRef->getArrivalAirport()->getId() << endl;
+                //string trns = trafficRef->getCallSign() + " at runway " + fp->getRunway() + 
+                //              ". Ready for departure. " + trafficRef->getFlightType() + " to " +
+                //              trafficRef->getArrivalAirport()->getId();
+                //fgSetString("/sim/messages/atc", trns.c_str());
                 //  if (controller == 0) {
                 //cerr << "Error in assigning controller at " << trafficRef->getDepartureAirport()->getId() << endl;
                 //}
-
+                //}
             } else {
                 cerr << "Error: Could not find Dynamics at airport : " << trafficRef->getDepartureAirport()->getId() << endl;
             }
@@ -446,29 +480,17 @@ void FGAIAircraft::announcePositionToController() {
 
         if ((controller != prevController) && (prevController != 0)) {
             prevController->signOff(getID());
-            string callsign =  trafficRef->getCallSign();
-            if ( trafficRef->getHeavy())
-                callsign += "Heavy";
-            switch (leg) {
-            case 3:
-                //cerr << callsign << " ready to taxi to runway " << fp->getRunway() << endl;
-                break;
-            case 4:
-                //cerr << callsign << " at runway " << fp->getRunway() << "Ready for take-off. "
-                //     << trafficRef->getFlightRules() << " to " << trafficRef->getArrivalAirport()->getId()
-                //     << "(" << trafficRef->getArrivalAirport()->getName() << ")."<< endl;
-                break;
-            }
         }
         prevController = controller;
         if (controller) {
             controller->announcePosition(getID(), fp, fp->getCurrentWaypoint()->routeIndex,
                                          _getLatitude(), _getLongitude(), hdg, speed, altitude_ft,
-                                         trafficRef->getRadius(), leg, trafficRef->getCallSign());
+                                         trafficRef->getRadius(), leg, this);
         }
     }
 }
 
+// Process ATC instructions and report back
 
 void FGAIAircraft::processATC(FGATCInstruction instruction) {
     if (instruction.getCheckForCircularWait()) {
@@ -494,7 +516,7 @@ void FGAIAircraft::processATC(FGATCInstruction instruction) {
     } else {
         if (holdPos) {
             //if (trafficRef)
-            // cerr << trafficRef->getCallSign() << " Resuming Taxi " << endl;
+            // cerr << trafficRef->getCallSign() << " Resuming Taxi." << endl;
             holdPos = false;
         }
         // Change speed Instruction. This can only be excecuted when there is no
@@ -539,7 +561,10 @@ void FGAIAircraft::handleFirstWaypoint() {
     //TODO fp should handle this
     fp->IncrementWaypoint(eraseWaypoints);
     if (!(fp->getNextWaypoint()) && trafficRef)
-        loadNextLeg();
+        if (!loadNextLeg()) {
+            setDie(true);
+            return;
+        }
 
     prev = fp->getPreviousWaypoint();   //first waypoint
     curr = fp->getCurrentWaypoint();    //second waypoint
@@ -620,7 +645,11 @@ bool FGAIAircraft::leadPointReached(FGAIFlightPlan::waypoint* curr) {
 
     //prev_dist_to_go = dist_to_go;
     //if (dist_to_go < lead_dist)
-    //    cerr << trafficRef->getCallSign() << " Distance : " << dist_to_go << ": Lead distance " << lead_dist << " " << curr->name << endl;
+    //     cerr << trafficRef->getCallSign() << " Distance : " 
+    //          << dist_to_go << ": Lead distance " 
+    //          << lead_dist << " " << curr->name 
+    //          << " Ground target speed " << groundTargetSpeed << endl;
+         
     return dist_to_go < lead_dist;
 }
 
@@ -635,7 +664,7 @@ bool FGAIAircraft::aiTrafficVisible() {
 
     user.CourseAndDistance(current, &course, &distance);
 
-    return ((distance * SG_METER_TO_NM) <= TRAFFICTOAIDIST);
+    return ((distance * SG_METER_TO_NM) <= TRAFFICTOAIDISTTODIE);
 }
 
 
@@ -658,6 +687,7 @@ bool FGAIAircraft::handleAirportEndPoints(FGAIFlightPlan::waypoint* prev, time_t
 
     // 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;
     if (prev->name == "PushBackPoint") {
         dep->getDynamics()->releaseParking(fp->getGate());
         time_t holdUntil = now + 120;
@@ -760,6 +790,7 @@ void FGAIAircraft::updatePrimaryTargetValues() {
                 throw AI_OutOfSight();
             }
         }
+        timeElapsed = now - fp->getStartTime();
         if (! fp->isActive(now)) { 
             throw FP_Inactive();
         }
@@ -845,7 +876,7 @@ void FGAIAircraft::updateHeading() {
             } else {
                 bank_sense = 1.0;
             }
-            if (trafficRef)
+            //if (trafficRef)
                //cerr << trafficRef->getCallSign() << " Heading " 
                 //     << hdg << ". Target " << tgt_heading <<  ". Diff " << fabs(sum - tgt_heading) << ". Speed " << speed << endl;
             //if (headingDiff > 60) {
@@ -875,7 +906,8 @@ void FGAIAircraft::updateHeading() {
                    else
                        headingChangeRate += dt * sign(roll);
             }
-           hdg += headingChangeRate * dt;
+
+           hdg += headingChangeRate * dt * (fabs(speed) / 15);
             headingError = headingDiff;
         } else {
             if (fabs(speed) > 1.0) {
@@ -979,6 +1011,20 @@ void FGAIAircraft::updatePitchAngleTarget() {
     }
 }
 
+string FGAIAircraft::atGate() {
+     string tmp("");
+     if (fp->getLeg() < 3) {
+         if (trafficRef) {
+             if (fp->getGate() > 0) {
+                 FGParking *park =
+                     trafficRef->getDepartureAirport()->getDynamics()->getParking(fp->getGate());
+                 tmp = park->getName();
+             }
+         }
+     }
+     return tmp;
+}
+
 void FGAIAircraft::handleATCRequests() {
     //TODO implement NullController for having no ATC to save the conditionals
     if (controller) {