]> git.mxchange.org Git - flightgear.git/commitdiff
Durk Talsma:
authorehofman <ehofman>
Mon, 29 Nov 2004 09:41:43 +0000 (09:41 +0000)
committerehofman <ehofman>
Mon, 29 Nov 2004 09:41:43 +0000 (09:41 +0000)
Okay, here's the latest update to the tarffic manager/AI Manager. AITraffic
can now fly multiple routes and be initialized while sitting statically at
airports.

13 files changed:
src/AIModel/AIAircraft.cxx
src/AIModel/AIAircraft.hxx
src/AIModel/AIBase.cxx
src/AIModel/AIBase.hxx
src/AIModel/AIFlightPlan.cxx
src/AIModel/AIFlightPlan.hxx
src/AIModel/AIManager.cxx
src/AIModel/AIManager.hxx
src/Airports/runways.cxx
src/Traffic/Schedule.cxx
src/Traffic/Schedule.hxx
src/Traffic/TrafficMgr.cxx
src/Traffic/TrafficMgr.hxx

index 295394342c20695a282fc06f317fd7f4c41c4ae9..07bf254d65ecd8af5c497ce3a2c1793d9727842b 100644 (file)
@@ -51,7 +51,8 @@ const FGAIAircraft::PERF_STRUCT FGAIAircraft::settings[] = {
 };
 
 
-FGAIAircraft::FGAIAircraft(FGAIManager* mgr) {
+FGAIAircraft::FGAIAircraft(FGAIManager* mgr, FGAISchedule *ref) {
+  trafficRef = ref;
    manager = mgr;   
    _type_str = "aircraft";
    _otype = otAircraft;
@@ -114,7 +115,14 @@ void FGAIAircraft::Run(double dt) {
 
    FGAIAircraft::dt = dt;
 
-   if (fp) ProcessFlightPlan(dt);
+   if (fp) 
+     {
+       ProcessFlightPlan(dt);
+       time_t now = time(NULL) + fgGetLong("/sim/time/warp");
+       if (now < fp->getStartTime())
+        return;
+       //ProcessFlightPlan(dt);
+     }
        
    double turn_radius_ft;
    double turn_circum_ft;
@@ -295,6 +303,8 @@ void FGAIAircraft::SetFlightPlan(FGAIFlightPlan *f) {
 }
 
 void FGAIAircraft::ProcessFlightPlan( double dt ) {
+
   FGAIFlightPlan::waypoint* prev = 0; // the one behind you
   FGAIFlightPlan::waypoint* curr = 0; // the one ahead
   FGAIFlightPlan::waypoint* next = 0; // the next plus 1
@@ -348,10 +358,35 @@ void FGAIAircraft::ProcessFlightPlan( double dt ) {
 
     if ( dist_to_go < lead_dist ) {
       if (curr->finished) {  //end of the flight plan, so terminate
-        setDie(true);
-        return;
+         if (trafficRef)
+           {
+             delete fp;
+             //time_t now = time(NULL) + fgGetLong("/sim/time/warp");
+             trafficRef->next();
+
+             FGAIModelEntity entity;
+              entity.m_class = "jet_transport";
+              //entity.path = modelPath.c_str();
+              entity.flightplan = "none";
+              entity.latitude = _getLatitude();
+              entity.longitude = _getLongitude();
+              entity.altitude = trafficRef->getCruiseAlt() * 100; // convert from FL to feet
+              entity.speed = 450;
+             //entity.fp = new FGAIFlightPlan(&entity, courseToDest, i->getDepartureTime(), dep, arr);
+             entity.fp = new FGAIFlightPlan(&entity, 
+                                            999,  // A hack
+                                            trafficRef->getDepartureTime(), 
+                                            trafficRef->getDepartureAirport(), 
+                                            trafficRef->getArrivalAirport());
+             SetFlightPlan(entity.fp);
+           }
+         else 
+           {
+             setDie(true);
+             return;
+           }
       }
-      // we've reached the lead-point for the waypoint ahead 
+       // we've reached the lead-point for the waypoint ahead 
       if (next) tgt_heading = fp->getBearing(curr, next);  
       fp->IncrementWaypoint();
       prev = fp->getPreviousWaypoint();
@@ -386,6 +421,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt ) {
 
 }
 
+
 bool FGAIAircraft::_getGearDown() const {
    return ((props->getFloatValue("position/altitude-agl-ft") < 900.0)
             && (props->getFloatValue("velocities/airspeed-kt")
index 33cf99e5e4e402c5964def17eec688fb7bd11cf2..f22ce44fee68e256aad59bfc7e08f0955aa8a429 100644 (file)
@@ -24,6 +24,9 @@
 #include "AIManager.hxx"
 #include "AIBase.hxx"
 
+#include <Traffic/SchedFlight.hxx>
+#include <Traffic/Schedule.hxx>
+
 #include <string>
 SG_USING_STD(string);
 
@@ -49,7 +52,7 @@ public:
         enum aircraft_e {LIGHT=0, WW2_FIGHTER, JET_TRANSPORT, JET_FIGHTER, TANKER};
         static const PERF_STRUCT settings[];
        
-       FGAIAircraft(FGAIManager* mgr);
+       FGAIAircraft(FGAIManager* mgr,   FGAISchedule *ref=0);
        ~FGAIAircraft();
        
        bool init();
@@ -70,7 +73,8 @@ public:
         inline void SetTanker(bool setting) { isTanker = setting; };
 
 private:
-
+   FGAISchedule *trafficRef;
+  
         bool hdg_lock;
         bool alt_lock;
         double dt_count;  
index cadc6af63ffe4044dc8c82fbe2c3c8682837cf4c..b5459a38f2ffd8245a56ce7b29acb91ab0b5a63e 100644 (file)
@@ -136,7 +136,7 @@ bool FGAIBase::init() {
    props = root->getNode(_type_str.c_str(), index, true);
 
    if (model_path != "") {
-      model = sgLoad3DModel( globals->get_fg_root(),
+      model = load3DModel( globals->get_fg_root(),
                             model_path.c_str(),
                              props,
                             globals->get_sim_time_sec() );
@@ -157,6 +157,36 @@ bool FGAIBase::init() {
    return true;
 }
 
+
+ssgBranch * FGAIBase::load3DModel(const string& fg_root, 
+                                 const string &path,
+                                 SGPropertyNode *prop_root, 
+                                 double sim_time_sec)
+{
+  // some more code here to check whether a model with this name has already been loaded
+  // if not load it, otherwise, get the memory pointer and do something like 
+  // SetModel as in ATC/AIEntity.cxx
+  //SSGBranch *model;
+  model = manager->getModel(path);
+  if (!(model))
+    {
+      model = sgLoad3DModel(fg_root,
+                           path,
+                           prop_root,
+                           sim_time_sec);
+      manager->setModel(path, model);
+      model->ref();
+    }
+  //else
+  //  {
+  //    model->ref();
+  //    aip.init(model);
+  //    aip.setVisible(false);
+  //    globals->get_scenery()->get_scene_graph()->addKid(aip.getSceneGraph());
+  // do some setModel stuff.
+  return model;
+}
+
 bool FGAIBase::isa( object_type otype ) {
  if ( otype == _otype ) { return true; }
  else { return false; } 
index bca2aea11cc8983622dc838e07fcd42c7359a324..bc8b2e48a51f2b965966bf6f55a0979063dae8ef 100644 (file)
@@ -202,6 +202,10 @@ public:
     int _getID() const;
 
     inline double _getRange() { return range; };
+  ssgBranch * load3DModel(const string& fg_root, 
+                         const string &path,
+                         SGPropertyNode *prop_root, 
+                         double sim_time_sec);
 
     static bool _isNight();
 };
index a0faa6028f9d208dd6a96266c6f23d89637bd5a3..6369c3cd31d690e89e848e1895c875f571242dd0 100644 (file)
@@ -44,6 +44,7 @@
 FGAIFlightPlan::FGAIFlightPlan(string filename)
 {
   int i;
+  start_time = 0;
   SGPath path( globals->get_fg_root() );
   path.append( ("/Data/AI/FlightPlans/" + filename).c_str() );
   SGPropertyNode root;
@@ -90,16 +91,30 @@ FGAIFlightPlan::FGAIFlightPlan(string filename)
 // as setting speeds and altitude computed by the
 // traffic manager. 
 FGAIFlightPlan::FGAIFlightPlan(FGAIModelEntity *entity,
-                              double course, 
+                              double course,
+                              time_t start,
                               FGAirport *dep,
                               FGAirport *arr)
 {
+  start_time = start;
   bool useInitialWayPoint = true;
   bool useCurrentWayPoint = false;
   SGPath path( globals->get_fg_root() );
   path.append( "/Data/AI/FlightPlans" );
   path.append( entity->path );
   SGPropertyNode root;
+  
+  // This is a bit of a hack:
+  // Normally the value of course will be used to evaluate whether
+  // or not a waypoint will be used for midair initialization of 
+  // an AI aircraft. However, if a course value of 999 will be passed
+  // when an update request is received, which will by definition always be
+  // on the ground and should include all waypoints.
+  if (course == 999) 
+    {
+      useInitialWayPoint = false;
+      useCurrentWayPoint = true;
+    }
 
   try {
     readProperties(path.str(), &root);
@@ -160,7 +175,7 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIModelEntity *entity,
                       (*i)->altitude);
       double crse, crsDiff;
       double dist;
-      first.CourseAndDistance(curr, &crse, &dist);
+      curr.CourseAndDistance(first, &crse, &dist);
       
       dist *= SG_METER_TO_NM;
       
@@ -182,8 +197,8 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIModelEntity *entity,
          // so once is the useWpt flag is set to true, we cannot reset it to false.
          //cerr << "Discarding waypoint: " << (*i)->name 
          //   << ": Course difference = " << crsDiff
-         //   << "Course = " << course
-         //   << "crse   = " << crse << endl;
+         //  << "Course = " << course
+         // << "crse   = " << crse << endl;
        }
       else
        useCurrentWayPoint = true;
@@ -192,10 +207,14 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIModelEntity *entity,
        {
          if ((dist > 100.0) && (useInitialWayPoint))
            {
-             //waypoints.push_back(init_waypoint);
+             //waypoints.push_back(init_waypoint);;
              waypoints.insert(i, init_waypoint);
              //cerr << "Using waypoint : " << init_waypoint->name <<  endl;
            }
+         //if (useInitialWayPoint)
+         // {
+         //    (*i)->speed = dist; // A hack
+         //  }
          //waypoints.push_back( wpt );
          //cerr << "Using waypoint : " << (*i)->name 
          //  << ": course diff : " << crsDiff 
@@ -342,26 +361,35 @@ double FGAIFlightPlan::getBearing(double lat, double lon, waypoint* wp){
  */ 
 void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, double alt, double speed)
 {
-  double wind_speed;
+double wind_speed;
   double wind_heading;
   FGRunway rwy;
+  double lat, lon, az;
+  double lat2, lon2, az2;
+  int direction;
   
   //waypoints.push_back(wpt);
   // Create the outbound taxi leg, for now simplified as a 
   // Direct route from the airport center point to the start
   // of the runway.
   ///////////////////////////////////////////////////////////
-      //cerr << "Cruise Alt << " << alt << endl;
+    //cerr << "Cruise Alt << " << alt << endl;
+    // Temporary code to add some small random variation to aircraft parking positions;
+  direction = (rand() % 360);
+geo_direct_wgs_84 ( 0, dep->latitude, dep->longitude, direction, 
+      100,
+      &lat2, &lon2, &az2 );
   waypoint *wpt = new waypoint;
   wpt->name      = dep->id; //wpt_node->getStringValue("name", "END");
-  wpt->latitude  = dep->latitude;
-  wpt->longitude = dep->longitude;
+  wpt->latitude  = lat2;
+  wpt->longitude = lon2;
   wpt->altitude  = dep->elevation + 19; // probably need to add some model height to it
   wpt->speed     = 15; 
   wpt->crossat   = -10000;
   wpt->gear_down = true;
   wpt->flaps_down= true;
   wpt->finished  = false;
+  wpt->on_ground = true;
   waypoints.push_back(wpt);
   
   // Get the current active runway, based on code from David Luff
@@ -384,8 +412,7 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, double alt, double s
       exit(1);
     }
 
-  double lat, lon, az;
-  double lat2, lon2, az2;
   double heading = rwy.heading;
   double azimuth = heading + 180.0;
   while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
@@ -546,7 +573,7 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, double alt, double s
   waypoints.push_back(wpt); 
   //Runway Threshold
  geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth, 
-                    rwy.length*0.45,
+                    rwy.length*0.45 * SG_FEET_TO_METER,
                     &lat2, &lon2, &az2 );
   wpt = new waypoint;
   wpt->name      = "Threshold"; //wpt_node->getStringValue("name", "END");
@@ -575,28 +602,33 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, double alt, double s
   wpt->gear_down = true;
   wpt->flaps_down= true;
   wpt->finished  = false;
-  wpt->on_ground = false;
+  wpt->on_ground = true;
   waypoints.push_back(wpt); 
 
+direction = (rand() % 360);
+geo_direct_wgs_84 ( 0, arr->latitude, arr->longitude, direction, 
+  100,
+  &lat2, &lon2, &az2 );
+
   // Add the final destination waypoint
   wpt = new waypoint;
   wpt->name      = arr->id; //wpt_node->getStringValue("name", "END");
-  wpt->latitude  = arr->latitude;
-  wpt->longitude = arr->longitude;
+  wpt->latitude  = lat2;
+  wpt->longitude = lon2;
   wpt->altitude  = arr->elevation+19;
   wpt->speed     = 15; 
   wpt->crossat   = -10000;
   wpt->gear_down = true;
   wpt->flaps_down= true;
   wpt->finished  = false;
-  wpt->on_ground = false;
+  wpt->on_ground = true;
   waypoints.push_back(wpt); 
 
   // And finally one more named "END"
   wpt = new waypoint;
   wpt->name      = "END"; //wpt_node->getStringValue("name", "END");
-  wpt->latitude  = arr->latitude;
-  wpt->longitude = arr->longitude;
+  wpt->latitude  = lat2;
+  wpt->longitude = lon2;
   wpt->altitude  = 19;
   wpt->speed     = 15; 
   wpt->crossat   = -10000;
@@ -609,14 +641,14 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, double alt, double s
  // And finally one more named "EOF"
   wpt = new waypoint;
   wpt->name      = "EOF"; //wpt_node->getStringValue("name", "END");
-  wpt->latitude  = arr->latitude;
-  wpt->longitude = arr->longitude;
+  wpt->latitude  = lat2;
+  wpt->longitude = lon2;
   wpt->altitude  = 19;
   wpt->speed     = 15; 
   wpt->crossat   = -10000;
   wpt->gear_down = true;
   wpt->flaps_down= true;
   wpt->finished  = true;
-  wpt->finished  = true;
+  wpt->on_ground  = true;
   waypoints.push_back(wpt);
 }
index 8cc6bb888238c9faba99e32146e2d041217a5619..bc4e21b90def720ee00cf1b6a7fd7e66a888866d 100644 (file)
@@ -51,6 +51,7 @@ public:
    FGAIFlightPlan(string filename);
   FGAIFlightPlan(FGAIModelEntity *entity,
                 double course,
+                time_t start,
                 FGAirport *dep,
                 FGAirport *arr);
    ~FGAIFlightPlan();
@@ -66,6 +67,7 @@ public:
    double getLeadDistance( void ) const {return lead_distance;}
    double getBearing(waypoint* previous, waypoint* next);
    double getBearing(double lat, double lon, waypoint* next);
+  time_t getStartTime() { return start_time; }; 
 
   void    create(FGAirport *dep, FGAirport *arr, double alt, double speed);
 
@@ -79,6 +81,7 @@ private:
 
     double distance_to_go;
     double lead_distance;
+    time_t start_time;
 
 };    
 
index 04919f7d347bec792af38f6d09e82fe51f7549ad..2a4b7dde591b8514d4cf6b2f75154c4d7a724e0a 100644 (file)
 #include <Main/fg_props.hxx>
 #include <Main/globals.hxx>
 
+#include <Airports/simple.hxx>
+#include <Traffic/SchedFlight.hxx>
+#include <Traffic/Schedule.hxx>
+#include <Traffic/TrafficMgr.hxx>
+
 #include <list>
 
 #include "AIManager.hxx"
@@ -53,6 +58,11 @@ FGAIManager::~FGAIManager() {
       ++ai_list_itr;
     }
   ai_list.clear();
+  ModelVecIterator i = loadedModels.begin();
+  while (i != loadedModels.end())
+    {
+      i->getModelId()->deRef();
+    }
 }
 
 
@@ -88,6 +98,7 @@ void FGAIManager::update(double dt) {
         // initialize these for finding nearest thermals
         range_nearest = 10000.0;
         strength = 0.0;
+       FGTrafficManager *tmgr = (FGTrafficManager*) globals->get_subsystem("Traffic Manager");
 
         if (!enabled)
             return;
@@ -97,6 +108,7 @@ void FGAIManager::update(double dt) {
         ai_list_itr = ai_list.begin();
         while(ai_list_itr != ai_list.end()) {
                 if ((*ai_list_itr)->getDie()) {      
+                 tmgr->release((*ai_list_itr)->getID());
                    --numObjects[(*ai_list_itr)->getType()];
                    --numObjects[0];
                    (*ai_list_itr)->unbind();
@@ -124,9 +136,9 @@ void FGAIManager::update(double dt) {
 
 
 void*
-FGAIManager::createAircraft( FGAIModelEntity *entity ) {
+FGAIManager::createAircraft( FGAIModelEntity *entity,   FGAISchedule *ref) {
      
-        FGAIAircraft* ai_plane = new FGAIAircraft(this);
+        FGAIAircraft* ai_plane = new FGAIAircraft(this, ref);
         ai_list.push_back(ai_plane);
         ++numObjects[0];
         ++numObjects[FGAIBase::otAircraft];
@@ -352,4 +364,25 @@ void FGAIManager::processScenario( string &filename ) {
   delete s;
 }
 
+// This code keeps track of models that have already been loaded
+// Eventually we'd prbably need to find a way to keep track of models
+// that are unloaded again
+ssgBranch * FGAIManager::getModel(const string& path)
+{
+  ModelVecIterator i = loadedModels.begin();
+  while (i != loadedModels.end())
+    {
+      if (i->getPath() == path)
+       return i->getModelId();
+      i++;
+    }
+  return 0;
+}
+
+void FGAIManager::setModel(const string& path, ssgBranch *model)
+{
+  loadedModels.push_back(FGModelID(path,model));
+}
+
+
 //end AIManager.cxx
index 59b879b1f5d4f50638fe0966a2a5604bdd4c28cf..4dfe74932d16018dd5bb505521caa4e0289f4279 100644 (file)
 #include <AIModel/AIScenario.hxx>
 #include <AIModel/AIFlightPlan.hxx>
 
+#include <Traffic/SchedFlight.hxx>
+#include <Traffic/Schedule.hxx>
+
 SG_USING_STD(list);
+SG_USING_STD(vector);
+
+class FGModelID
+{
+private:
+  ssgBranch * model;
+  string path;
+public:
+  FGModelID(const string& pth, ssgBranch * mdl) { path =pth; model=mdl;};
+  ssgBranch *getModelId() { return model;};
+  const string & getPath() { return path;};
+};
+
+typedef vector<FGModelID> ModelVec;
+typedef vector<FGModelID>::iterator ModelVecIterator;
+
 class FGAIThermal;
 
 
@@ -51,6 +70,7 @@ private:
     // on the heap and ***DELETED WHEN REMOVED!!!!!***
     ai_list_type ai_list;
     ai_list_iterator ai_list_itr;
+  ModelVec loadedModels;
 
 public:
 
@@ -63,7 +83,7 @@ public:
     void update(double dt);
 
     void* createBallistic( FGAIModelEntity *entity );
-    void* createAircraft( FGAIModelEntity *entity );
+    void* createAircraft( FGAIModelEntity *entity,   FGAISchedule *ref=0 );
     void* createThermal( FGAIModelEntity *entity );
     void* createStorm( FGAIModelEntity *entity );
     void* createShip( FGAIModelEntity *entity );
@@ -85,6 +105,9 @@ public:
 
     void processScenario( string &filename );
 
+  ssgBranch * getModel(const string& path);
+  void setModel(const string& path, ssgBranch *model);
+
 private:
 
     bool initDone;
index d9c5d2a3c5093c9f525b5aaca8f8621552844dfc..e437dda08c4f444a13bde16a419be65a4e3c2547 100644 (file)
@@ -167,7 +167,6 @@ bool FGRunwayList::search( const string& aptid, const string& rwyno,
         }
         revrwyno = GetReverseRunwayNo(runwayno);
     }
-
     runway_map_iterator pos;
     for ( pos = runways.lower_bound( aptid );
           pos != runways.upper_bound( aptid ); ++pos)
index dbe0e2845cb995a3aa2676e8195e4639d2602dae..29bd9a743bdfda52b97fddd4fb85ea0685da6f09 100644 (file)
@@ -155,6 +155,14 @@ void FGAISchedule::update(time_t now)
   // of the first listed flight. 
   sort(flights.begin(), flights.end());
   FGScheduledFlightVecIterator i = flights.begin();
+  if (AIManagerRef)
+    {
+      // Check if this aircraft has been released. 
+      FGTrafficManager *tmgr = (FGTrafficManager *) globals->get_subsystem("Traffic Manager");
+      if (tmgr->isReleased(AIManagerRef))
+       AIManagerRef = 0;
+    }
+
   if (!AIManagerRef)
     {
       userLatitude  = fgGetDouble("/position/latitude-deg");
@@ -173,7 +181,11 @@ void FGAISchedule::update(time_t now)
       // This flight is in progress, so we need to calculate it's
       // approximate position and -if in range- create an AIAircraft
       // object for it. 
-      if ((i->getDepartureTime() < now) && (i->getArrivalTime() > now))
+      //if ((i->getDepartureTime() < now) && (i->getArrivalTime() > now))
+      
+
+      // Part of this flight is in the future.
+      if (i->getArrivalTime() > now)
        {
          dep = i->getDepartureAirport();
          arr = i->getArrivalAirport  ();
@@ -205,6 +217,7 @@ void FGAISchedule::update(time_t now)
          // arrival airport, in degrees. From here we can interpolate the
          // position of the aircraft by calculating the ratio between 
          // total time enroute and elapsed time enroute. 
          totalTimeEnroute     = i->getArrivalTime() - i->getDepartureTime();
          elapsedTimeEnroute   = now - i->getDepartureTime();
          remainingTimeEnroute = i->getArrivalTime()   - now;  
@@ -226,8 +239,20 @@ void FGAISchedule::update(time_t now)
 
          temp = sgCartToPolar3d(Point3D(newPos[0], newPos[1],newPos[2]));
 
-         lat = temp.lat() * SG_RADIANS_TO_DEGREES;
-         lon = temp.lon() * SG_RADIANS_TO_DEGREES;
+         if (now > i->getDepartureTime())
+           {
+             //cerr << "Lat = " << lat << ", lon = " << lon << endl;
+             //cerr << "Time diff: " << now-i->getDepartureTime() << endl;
+             lat = temp.lat() * SG_RADIANS_TO_DEGREES;
+             lon = temp.lon() * SG_RADIANS_TO_DEGREES; 
+             //err << "Lat = " << lat << ", lon = " << lon << endl;
+             //cerr << "Time diff: " << now-i->getDepartureTime() << endl;
+           }
+         else
+           {
+             lat = dep->latitude;
+             lon = dep->longitude;
+           }
          
          SGWayPoint current  (lon,
                               lat,
@@ -240,8 +265,8 @@ void FGAISchedule::update(time_t now)
                              i->getCruiseAlt());
          // We really only need distance to user
          // and course to destination 
-         current.CourseAndDistance(user, &courseToUser, &distanceToUser);
-         current.CourseAndDistance(dest, &courseToDest, &distanceToDest);
+         user.CourseAndDistance(current, &courseToUser, &distanceToUser);
+         dest.CourseAndDistance(current, &courseToDest, &distanceToDest);
          speed =  (distanceToDest*SG_METER_TO_NM) / 
            ((double) remainingTimeEnroute/3600.0);
          
@@ -257,6 +282,15 @@ void FGAISchedule::update(time_t now)
            {
              string flightPlanName = dep->id + string("-") + arr->id + 
                string(".xml");
+             int alt;
+             //if  ((i->getDepartureTime() < now))
+             //{
+             //          alt = i->getCruiseAlt() *100;
+             //        }
+             //else
+             //{
+             //          alt = dep->elevation+19;
+             //        }
 
               FGAIModelEntity entity;
 
@@ -265,13 +299,13 @@ void FGAISchedule::update(time_t now)
               entity.flightplan = flightPlanName.c_str();
               entity.latitude = lat;
               entity.longitude = lon;
-              entity.altitude = i->getCruiseAlt() * 100; // convert from FL to feet
+              entity.altitude = i->getCruiseAlt() *100; // convert from FL to feet
               entity.speed = 450;
-             entity.fp = new FGAIFlightPlan(&entity, courseToDest, dep, arr);
+             entity.fp = new FGAIFlightPlan(&entity, courseToDest, i->getDepartureTime(), dep, arr);
 
              // Fixme: A non-existent model path results in an
              // abort, due to an unhandled exeption, in fg main loop.
-             AIManagerRef = aimgr->createAircraft( &entity );
+             AIManagerRef = aimgr->createAircraft( &entity, this);
              //cerr << "Created: " << AIManagerRef << endl;
            }
          return;
@@ -279,7 +313,7 @@ void FGAISchedule::update(time_t now)
 
       // Both departure and arrival time are in the future, so this
       // the aircraft is parked at the departure airport.
-      // Currently this status is mostly ignored, but in furture
+      // Currently this status is mostly ignored, but in future
       // versions, code should go here that -if within user range-
       // positions these aircraft at parking locations at the airport.
       if ((i->getDepartureTime() > now) && (i->getArrivalTime() > now))
@@ -289,3 +323,11 @@ void FGAISchedule::update(time_t now)
        } 
     }
 }
+
+
+void FGAISchedule::next()
+{
+  flights.begin()->update();
+  sort(flights.begin(), flights.end());
+}
+
index 0664e36be4a9cf3c6158b05b9b98df28246e85c4..a919a7a5b4bc5292967868272244308017dbcb0c 100644 (file)
@@ -30,6 +30,7 @@
 #define _FGSCHEDULE_HXX_
 
 
+
 class FGAISchedule
 {
  private:
@@ -43,6 +44,7 @@ class FGAISchedule
   void* AIManagerRef;
   bool firstRun;
 
+
  public:
   FGAISchedule();                                           // constructor
   FGAISchedule(string, string, string, bool, FGScheduledFlightVec);  // construct & init
@@ -51,6 +53,12 @@ class FGAISchedule
   ~FGAISchedule(); //destructor
 
   void update(time_t now);
+  void next();   // forces the schedule to move on to the next flight.
+
+  time_t      getDepartureTime    () { return flights.begin()->getDepartureTime   (); };
+  FGAirport * getDepartureAirport () { return flights.begin()->getDepartureAirport(); };
+  FGAirport * getArrivalAirport   () { return flights.begin()->getArrivalAirport  (); };
+  int         getCruiseAlt        () { return flights.begin()->getCruiseAlt       (); };
   // More member functions follow later
 
 };
index dda17c06bdf8be601c2bb3ec25496a70840092da..ca663a8d2b00153c6d8902c4482f49182a437428 100644 (file)
@@ -89,6 +89,26 @@ void FGTrafficManager::update(double something)
     currAircraft++;
 }
 
+void FGTrafficManager::release(void *id)
+{
+  releaseList.push_back(id);
+}
+
+bool FGTrafficManager::isReleased(void *id)
+{
+  IdListIterator i = releaseList.begin();
+  while (i != releaseList.end())
+    {
+      if ((*i) == id)
+       {
+         releaseList.erase(i);
+         return true;
+       }
+      i++;
+    }
+  return false;
+}
+
 void  FGTrafficManager::startXML () {
   //cout << "Start XML" << endl;
 }
index 1521111f14344a90617236db16456aa38516d951..ab39afcf732c82e262ddbdd5003fa45cc65246f5 100644 (file)
 #include "Schedule.hxx"
 
 
+typedef vector<void *> IdList;
+typedef vector<void *>::iterator IdListIterator;
+
+
 class FGTrafficManager : public SGSubsystem, public XMLVisitor
 {
 private:
@@ -46,6 +50,8 @@ private:
     repeat;
   int cruiseAlt;
   bool heavy;
+
+  IdList releaseList;
     
   FGScheduledFlightVec flights;
 
@@ -54,6 +60,8 @@ public:
   
   void init();
   void update(double time);
+  void release(void *ref);
+  bool isReleased(void *id);
 
   // Some overloaded virtual XMLVisitor members
   virtual void startXML ();