]> git.mxchange.org Git - flightgear.git/blobdiff - src/AIModel/AIAircraft.cxx
Don't restore initial screen geometry because there is nothing in fg_os* to resize...
[flightgear.git] / src / AIModel / AIAircraft.cxx
index 80c0879d32b51ef20c8c020c689012ccaaeb3268..736786f62ab71e5f53a10ca61dc47f4ab5d78c34 100644 (file)
@@ -16,7 +16,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
@@ -36,6 +36,8 @@
 #ifdef _MSC_VER
 #  include <float.h>
 #  define finite _finite
+#elif defined(__sun) || defined(sgi)
+#  include <ieeefp.h>
 #endif
 
 SG_USING_STD(string);
@@ -60,15 +62,13 @@ const FGAIAircraft::PERF_STRUCT FGAIAircraft::settings[] = {
 };
 
 
-FGAIAircraft::FGAIAircraft(FGAIManager* mgr, FGAISchedule *ref) {
+FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
+  FGAIBase(otAircraft) {
   trafficRef = ref;
   if (trafficRef)
     groundOffset = trafficRef->getGroundOffset();
   else
     groundOffset = 0;
-   manager = mgr;   
-   _type_str = "aircraft";
-   _otype = otAircraft;
    fp = 0;
    dt_count = 0;
    dt_elev_count = 0;
@@ -84,8 +84,19 @@ FGAIAircraft::FGAIAircraft(FGAIManager* mgr, FGAISchedule *ref) {
 
 
 FGAIAircraft::~FGAIAircraft() {
+  //delete fp;
 }
 
+void FGAIAircraft::readFromScenario(SGPropertyNode* scFileNode) {
+  if (!scFileNode)
+    return;
+
+  FGAIBase::readFromScenario(scFileNode);
+
+  setPerformance(scFileNode->getStringValue("class", "jet_transport"));
+  setFlightPlan(scFileNode->getStringValue("flightplan"),
+                scFileNode->getBoolValue("repeat", false));
+}
 
 bool FGAIAircraft::init() {
    refuel_node = fgGetNode("systems/refuel/contact", true);
@@ -98,19 +109,12 @@ void FGAIAircraft::bind() {
     props->tie("controls/gear/gear-down",
                SGRawValueMethods<FGAIAircraft,bool>(*this,
                                               &FGAIAircraft::_getGearDown));
-#if 0
-    props->getNode("controls/lighting/landing-lights", true)
-           ->alias("controls/gear/gear-down");
-#endif
 }
 
 void FGAIAircraft::unbind() {
     FGAIBase::unbind();
 
     props->untie("controls/gear/gear-down");
-#if 0
-    props->getNode("controls/lighting/landing-lights")->unalias();
-#endif
 }
 
 
@@ -121,6 +125,24 @@ void FGAIAircraft::update(double dt) {
    Transform();
 }
 
+void FGAIAircraft::setPerformance(const std::string& acclass)
+{
+  if (acclass == "light") {
+    SetPerformance(&FGAIAircraft::settings[FGAIAircraft::LIGHT]);
+  } else if (acclass == "ww2_fighter") {
+    SetPerformance(&FGAIAircraft::settings[FGAIAircraft::WW2_FIGHTER]);
+  } else if (acclass ==  "jet_transport") {
+    SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
+  } else if (acclass == "jet_fighter") {
+    SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_FIGHTER]);
+  } else if (acclass ==  "tanker") {
+    SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
+    SetTanker(true);
+  } else {
+    SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
+  }
+}
+
 void FGAIAircraft::SetPerformance(const PERF_STRUCT *ps) {
    
    performance = ps;
@@ -144,8 +166,11 @@ void FGAIAircraft::Run(double dt) {
               Transform();         // make sure aip is initialized.
               getGroundElev(dt); // make sure it's exectuted first time around, so force a large dt value
               //getGroundElev(dt); // Need to do this twice.
-              //cerr << trafficRef->getRegistration() << " Setting altitude to " << tgt_altitude << endl;
-              setAltitude(tgt_altitude);
+              //cerr << trafficRef->getRegistration() << " Setting altitude to " << tgt_altitude;
+              doGroundAltitude();
+              //cerr << " Actual altitude " << altitude << endl;
+              // Transform(); 
+              pos.setelev(altitude * SG_FEET_TO_METER);
             }
           return;
         }
@@ -338,29 +363,32 @@ void FGAIAircraft::Run(double dt) {
    if (no_roll)
      {
        getGroundElev(dt);
+       doGroundAltitude();
      }
-   // find target vertical speed if altitude lock engaged
-   if (alt_lock && use_perf_vs) {
-     if (altitude_ft < tgt_altitude) {
-       tgt_vs = tgt_altitude - altitude_ft;
-       if (tgt_vs > performance->climb_rate)
-         tgt_vs = performance->climb_rate;
-     } else {
-       tgt_vs = tgt_altitude - altitude_ft;
-       if (tgt_vs  < (-performance->descent_rate))
-         tgt_vs = -performance->descent_rate;
+   else
+     {
+       // find target vertical speed if altitude lock engaged
+       if (alt_lock && use_perf_vs) {
+        if (altitude_ft < tgt_altitude) {
+          tgt_vs = tgt_altitude - altitude_ft;
+          if (tgt_vs > performance->climb_rate)
+            tgt_vs = performance->climb_rate;
+        } else {
+          tgt_vs = tgt_altitude - altitude_ft;
+          if (tgt_vs  < (-performance->descent_rate))
+            tgt_vs = -performance->descent_rate;
+        }
+       }
+       
+       if (alt_lock && !use_perf_vs) {
+        double max_vs = 4*(tgt_altitude - altitude);
+        double min_vs = 100;
+        if (tgt_altitude < altitude) min_vs = -100.0;
+        if ((fabs(tgt_altitude - altitude) < 1500.0) && 
+            (fabs(max_vs) < fabs(tgt_vs))) tgt_vs = max_vs;
+        if (fabs(tgt_vs) < fabs(min_vs)) tgt_vs = min_vs;
+       }   
      }
-   }
-
-   if (alt_lock && !use_perf_vs) {
-     double max_vs = 4*(tgt_altitude - altitude);
-     double min_vs = 100;
-     if (tgt_altitude < altitude) min_vs = -100.0;
-     if ((fabs(tgt_altitude - altitude) < 1500.0) && 
-         (fabs(max_vs) < fabs(tgt_vs))) tgt_vs = max_vs;
-     if (fabs(tgt_vs) < fabs(min_vs)) tgt_vs = min_vs;
-   }   
-
    // adjust vertical speed
    double vs_diff = tgt_vs - vs;
    if (fabs(vs_diff) > 10.0) {
@@ -440,7 +468,17 @@ double FGAIAircraft::sign(double x) {
   else { return 1.0; }
 }
 
+void FGAIAircraft::setFlightPlan(const std::string& flightplan, bool repeat)
+{
+  if (!flightplan.empty()){
+    FGAIFlightPlan* fp = new FGAIFlightPlan(flightplan);
+    fp->setRepeat(repeat);
+    SetFlightPlan(fp);
+  }
+}
+
 void FGAIAircraft::SetFlightPlan(FGAIFlightPlan *f) {
+  delete fp;
   fp = f;
 }
 
@@ -514,8 +552,8 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now )
       use_perf_vs = false;
       tgt_vs = (curr->crossat - prev->altitude)/
        (fp->getDistanceToGo(pos.lat(), pos.lon(), curr)/
-        6076.0/prev->speed*60.0);
-        tgt_altitude = curr->crossat;
+          6076.0/prev->speed*60.0);
+      tgt_altitude = curr->crossat;
     } else {
       use_perf_vs = true;
       tgt_altitude = prev->altitude;
@@ -528,7 +566,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now )
        getGroundElev(60.1); // make sure it's exectuted first time around, so force a large dt value
        //getGroundElev(60.1); // Need to do this twice.
        //cerr << trafficRef->getRegistration() << " Setting altitude to " << tgt_altitude << endl;
-       setAltitude(tgt_altitude);
+       doGroundAltitude(); //(tgt_altitude);
       }
     prevSpeed = 0;
     //cout << "First waypoint:  " << prev->name << endl;
@@ -582,7 +620,12 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now )
     // Current waypoint's elevation according to Terrain Elevation
     if (curr->finished) {  //end of the flight plan
       {
-       setDie(true);
+         if (fp->getRepeat()) {
+           fp->restart();
+         } else {   
+         setDie(true);
+         } 
+
        //cerr << "Done die end of fp" << endl;
       }
       return;
@@ -657,21 +700,25 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now )
        //       << arr->getId() <<endl;
        //  }   
        if (prev->name == "park2")
-         dep->releaseParking(fp->getGate());
-       
-       //if ((arr->getId() == string("EHAM")) && (prev->name  == "Center"))
-       //  {
-       //    
-       //    cerr << "Schiphol ground " 
-       //       << trafficRef->getCallSign();
-       //    if (trafficRef->getHeavy())
-       //      cerr << "Heavy";
-       //    cerr << " landed runway " 
-       //       << fp->getRunway()
-       //       << " request taxi to gate " 
-       //       << arr->getParkingName(fp->getGate()) 
-       //       << endl;
-       //  }
+         {
+           dep->getDynamics()->releaseParking(fp->getGate());
+         }
+       // Some debug messages, specific to testing the Logical networks.
+       // if ((arr->getId() == string("EHAM")) && (prev->name  == "Center"))
+//       {
+           
+//         cerr << "Schiphol ground " 
+//              << trafficRef->getRegistration() << " "
+//              << trafficRef->getCallSign();
+//         if (trafficRef->getHeavy())
+//           cerr << "Heavy";
+//         cerr << ", arriving from " << dep->getName() ;
+//         cerr << " landed runway " 
+//              << fp->getRunway()
+//              << " request taxi to gate " 
+//              << arr->getDynamics()->getParkingName(fp->getGate()) 
+//              << endl;
+//       }
        if (prev->name == "END")
          fp->setTime(trafficRef->getDepartureTime());
        //cerr << "5" << endl;
@@ -683,19 +730,22 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now )
        fp->setLeadDistance(speed, tgt_heading, curr, next);
       }
     //cerr << "5.1" << endl;
-    if (curr->crossat > -1000.0) {
-      //cerr << "5.1a" << endl;
-      use_perf_vs = false;
-      tgt_vs = (curr->crossat - altitude)/
-       (fp->getDistanceToGo(pos.lat(), pos.lon(), curr)/6076.0/speed*60.0);
-      //cerr << "5.1b" << endl;
-      tgt_altitude = curr->crossat;
-    } else {
-      //cerr << "5.1c" << endl;
-      use_perf_vs = true;
-      //cerr << "5.1d" << endl;        
+    if (!(prev->on_ground)) { // only update the tgt altitude from flightplan if not on the ground
       tgt_altitude = prev->altitude;
-      //cerr << "Setting target altitude : " <<tgt_altitude << endl;
+      if (curr->crossat > -1000.0) {
+       //cerr << "5.1a" << endl;
+       use_perf_vs = false;
+       tgt_vs = (curr->crossat - altitude)/
+         (fp->getDistanceToGo(pos.lat(), pos.lon(), curr)/6076.0/speed*60.0);
+       //cerr << "5.1b" << endl;
+       tgt_altitude = curr->crossat;
+      } else {
+       //cerr << "5.1c" << endl;
+       use_perf_vs = true;
+       //cerr << "5.1d" << endl;       
+       
+       //cerr << "Setting target altitude : " <<tgt_altitude << endl;
+      }
     }
     //cerr << "6" << endl;
     tgt_speed = prev->speed;
@@ -863,14 +913,14 @@ void FGAIAircraft::loadNextLeg()
 void FGAIAircraft::getGroundElev(double dt) {
   dt_elev_count += dt;
   //return;
-  if (dt_elev_count < (10.0 + (rand() % 100))) // Update minimally every 10 secs, but add some randomness to prevent them all IA objects doing this synced
-    {
-      return;
-    }
-  else
-    {
-      dt_elev_count = 0;
-    }
+  if (dt_elev_count < (3.0) + (rand() % 10)) //Update minimally every three secs, but add some randomness to prevent all IA objects doing this in synchrony
+     {
+       return;
+     }
+   else
+     {
+       dt_elev_count = 0;
+     }
   // It would be nice if we could set the correct tile center here in order to get a correct
   // answer with one call to the function, but what I tried in the two commented-out lines
   // below only intermittently worked, and I haven't quite groked why yet.
@@ -878,78 +928,54 @@ void FGAIAircraft::getGroundElev(double dt) {
   //aip.getSGLocation()->set_tile_center(Point3D(buck.get_center_lon(), buck.get_center_lat(), 0.0));
   
   // Only do the proper hitlist stuff if we are within visible range of the viewer.
-  double visibility_meters = fgGetDouble("/environment/visibility-m"); 
-
-  FGViewer* vw = globals->get_current_view();
-  double 
-    course, 
-    distance;
-
-  //Point3D currView(vw->getLongitude_deg(), 
-  //              vw->getLatitude_deg(), 0.0);
-  SGWayPoint current  (pos.lon(),
-                      pos.lat(),
-                      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;
-  }
-    
-  
-  //globals->get_tile_mgr()->prep_ssg_nodes( acmodel_location,
-  globals->get_tile_mgr()->prep_ssg_nodes( aip.getSGLocation(),        visibility_meters );
-  Point3D scenery_center = globals->get_scenery()->get_center();
-
-  globals->get_tile_mgr()->update( aip.getSGLocation(), 
-                                  visibility_meters, 
-                                  (aip.getSGLocation())->get_absolute_view_pos( scenery_center ) );
-  // save results of update in SGLocation for fdm...
-  
-  //if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
-  //   acmodel_location->
-  //   set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
-  //}
-  
-  // The need for this here means that at least 2 consecutive passes are needed :-(
-  aip.getSGLocation()->set_tile_center( globals->get_scenery()->get_next_center() );
-    globals->get_tile_mgr()->prep_ssg_nodes( aip.getSGLocation(),      visibility_meters );
-    //Point3D scenery_center = globals->get_scenery()->get_center();
-
-  globals->get_tile_mgr()->update( aip.getSGLocation(), 
-                                  visibility_meters, 
-                                  (aip.getSGLocation())->get_absolute_view_pos( scenery_center ) );
-  // save results of update in SGLocation for fdm...
-  
-  //if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
-  //   acmodel_location->
-  //   set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
-  //}
-  
-  // The need for this here means that at least 2 consecutive passes are needed :-(
-  aip.getSGLocation()->set_tile_center( globals->get_scenery()->get_next_center() );
-  //cerr << "Transform Elev is " << globals->get_scenery()->get_cur_elev() << '\n';
-  tgt_altitude = (globals->get_scenery()->get_cur_elev() * SG_METER_TO_FEET) + groundOffset;
+   if (!invisible) {
+     double visibility_meters = fgGetDouble("/environment/visibility-m");      
+     
+     
+     FGViewer* vw = globals->get_current_view();
+     double 
+       course, 
+       distance;
+     
+     //Point3D currView(vw->getLongitude_deg(), 
+     //                   vw->getLatitude_deg(), 0.0);
+     SGWayPoint current  (pos.lon(),
+                         pos.lat(),
+                         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;
+     }
+     
+     // FIXME: make sure the pos.lat/pos.lon values are in degrees ...
+     double range = 500.0;
+     if (!globals->get_tile_mgr()->scenery_available(pos.lat(), pos.lon(), range))
+       {
+        // Try to shedule tiles for that position.
+        globals->get_tile_mgr()->update( aip.getSGLocation(), range );
+       }
+     
+     // FIXME: make sure the pos.lat/pos.lon values are in degrees ...
+     double alt;
+     if (globals->get_scenery()->get_elevation_m(pos.lat(), pos.lon(),
+                                                20000.0, alt))
+       tgt_altitude = alt * SG_METER_TO_FEET; 
+     //cerr << "Target altitude : " << tgt_altitude << endl;
+     // if (globals->get_scenery()->get_elevation_m(pos.lat(), pos.lon(),
+     //                                            20000.0, alt))
+     //    tgt_altitude = alt * SG_METER_TO_FEET;
+     //cerr << "Target altitude : " << tgt_altitude << endl;
+   }
+}
+   
+void FGAIAircraft::doGroundAltitude()
+{
+  if (fabs(altitude - (tgt_altitude+groundOffset)) > 1000.0)
+    altitude = (tgt_altitude + groundOffset);
+  else
+    altitude += 0.1 * ((tgt_altitude+groundOffset) - altitude);
 }
-
-//globals->get_tile_mgr()->prep_ssg_nodes( _aip.getSGLocation(),       visibility_meters );
-//Point3D scenery_center = globals->get_scenery()->get_center();
-//globals->get_tile_mgr()->update(_aip.getSGLocation(), visibility_meters, (_aip.getSGLocation())->get_absolute_view_pos( scenery_center ) );
-// save results of update in SGLocation for fdm...
-
-//if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
-//     acmodel_location->
-//     set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
-//}
-
-// The need for this here means that at least 2 consecutive passes are needed :-(
-//_aip.getSGLocation()->set_tile_center( globals->get_scenery()->get_next_center() );
-
-//cout << "Transform Elev is " << globals->get_scenery()->get_cur_elev() << '\n';
-//_aip.getSGLocation()->set_cur_elev_m(globals->get_scenery()->get_cur_elev());
-//return(globals->get_scenery()->get_cur_elev());
-//}