]> git.mxchange.org Git - flightgear.git/commitdiff
Maik Justus,
authordurk <durk>
Sat, 13 Jan 2007 09:04:07 +0000 (09:04 +0000)
committerdurk <durk>
Sat, 13 Jan 2007 09:04:07 +0000 (09:04 +0000)
Here is a patch for two bugs in the AI/multiplayer part:

1. Cannot find model file *.ac error message (was only a false message,
anything worked correctly, the model was loaded from the correct path
afterwards).

2. Often many multiplayer aircrafts are missing in the property-tree.
(but I need them for aerotowing). There is still another bug: The
property in some circumstances seems not to be cleaned up after logout
of a multiplayer. I have added a workaround for this, but I don't now,
if it 100% works (should have no side effects, just aerotow would not
work sometimes). For testing I need more traffic on the mp-server.

src/AIModel/AIAircraft.cxx
src/AIModel/AIBase.cxx
src/AIModel/AIBase.hxx
src/AIModel/AIManager.cxx
src/AIModel/AIMultiplayer.cxx
src/AIModel/AIStatic.cxx

index 98d95fb5c95ab98dccb1558fc6457b8eae291fb9..b56a7893a3f50b0cb296ce6e8d1360c4e9fff66d 100644 (file)
@@ -120,7 +120,7 @@ void FGAIAircraft::readFromScenario(SGPropertyNode* scFileNode) {
 
 bool FGAIAircraft::init() {
     //refuel_node = fgGetNode("systems/refuel/contact", true);
-    return FGAIBase::init();
+    return FGAIBase::init(true);
 }
 
 
@@ -647,7 +647,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
       no_roll = prev->on_ground;
       if (no_roll) {
        Transform();         // make sure aip is initialized.
-       getGroundElev(60.1); // make sure it's exectuted first time around, so force a large dt value
+       getGroundElev(60.1); // make sure it's executed first time around, so force a large dt value
        doGroundAltitude(); 
       }
       // Make sure to announce the aircraft's position 
@@ -655,16 +655,19 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
       prevSpeed = 0;
       return;
     } // end of initialization
-    
-    ///////////////////////////////////////////////////////////////////////////
-    // Check Execution time (currently once every 100 ms
+     ///////////////////////////////////////////////////////////////////////////
+    // Check Execution time (currently once every 100 ms) 
+    // Add a bit of randomization to prevent the execution of all flight plans
+    // in synchrony, which can add significant periodic framerate flutter.
     ///////////////////////////////////////////////////////////////////////////
-    if ((dt_count < 0.1) || (now < fp->getStartTime())) {
+    double rand_exec_time = (rand() % 100) / 100;
+    if ((dt_count < (0.1+rand_exec_time)) || (now < fp->getStartTime())) {
       //cerr  << "done fp dt" << endl;
       return;
     } else {
       dt_count = 0;
     }
+
     // check to see if we've reached the lead point for our next turn
     double dist_to_go = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
 
index 27cc00eb96ed9f87a893241e1c227f7bdfa26e89..ebf34e94db7911eb7f25d055f28566a0a442c4dc 100644 (file)
@@ -125,27 +125,28 @@ void FGAIBase::Transform() {
     }
 }
 
-
-bool FGAIBase::init() {
-
-   if (!model_path.empty()) {
-     SGPath ai_path("AI");
-     ai_path.append(model_path);
-     try {
-       model = load3DModel( globals->get_fg_root(), ai_path.str(), props,
+bool FGAIBase::init(bool search_in_AI_path) {
+    if (!model_path.empty()) {
+     if ( (search_in_AI_path)
+          &&(model_path.substr(model_path.size() - 4, 4) == ".xml")) {
+       SGPath ai_path("AI");
+       ai_path.append(model_path);
+       try {
+         model = load3DModel( globals->get_fg_root(), ai_path.str(), props,
                         globals->get_sim_time_sec() );
-     } catch (const sg_exception &) {
-       model = NULL;
-     }
+       } catch (const sg_exception &e) {
+         model = NULL;
+       }
+     } else model = NULL;
      if (!model) {
        try {
          model = load3DModel( globals->get_fg_root(), model_path, props,
                         globals->get_sim_time_sec() );
-       } catch (const sg_exception &) {
+       } catch (const sg_exception &e) {
          model = NULL;
        }
-     }
-   }
+      }
+    }
    if (model.get()) {
      aip.init( model.get() );
      aip.setVisible(true);
@@ -161,7 +162,6 @@ bool FGAIBase::init() {
    }
 
    setDie(false);
-
    return true;
 }
 
@@ -207,6 +207,19 @@ void FGAIBase::bind() {
                                          &FGAIBase::_getLongitude,
                                          &FGAIBase::_setLongitude));
 
+   props->tie("position/global-x",
+               SGRawValueMethods<FGAIBase,double>(*this,
+                                         &FGAIBase::_getCartPosX,
+                                         0));
+   props->tie("position/global-y",
+               SGRawValueMethods<FGAIBase,double>(*this,
+                                         &FGAIBase::_getCartPosY,
+                                         0));
+   props->tie("position/global-z",
+               SGRawValueMethods<FGAIBase,double>(*this,
+                                         &FGAIBase::_getCartPosZ,
+                                         0));
+
    props->tie("orientation/pitch-deg",   SGRawValuePointer<double>(&pitch));
    props->tie("orientation/roll-deg",    SGRawValuePointer<double>(&roll));
    props->tie("orientation/true-heading-deg", SGRawValuePointer<double>(&hdg));
@@ -248,6 +261,9 @@ void FGAIBase::unbind() {
     props->untie("position/altitude-ft");
     props->untie("position/latitude-deg");
     props->untie("position/longitude-deg");
+    props->untie("position/global-x");
+    props->untie("position/global-y");
+    props->untie("position/global-z");
 
     props->untie("orientation/pitch-deg");
     props->untie("orientation/roll-deg");
@@ -386,6 +402,42 @@ FGAIBase::getCartPosAt(const SGVec3d& _off) const
   return cartPos + off;
 }
 
+SGVec3d
+FGAIBase::getCartPos() const
+{
+  // Transform that one to the horizontal local coordinate system.
+  
+  SGQuatd hlTrans = SGQuatd::fromLonLat(pos);
+  // and postrotate the orientation of the AIModel wrt the horizontal
+  // local frame
+  hlTrans *= SGQuatd::fromYawPitchRollDeg(hdg, pitch, roll);
+
+  SGVec3d cartPos = SGVec3d::fromGeod(pos);
+
+  return cartPos;
+}
+
+double
+FGAIBase::_getCartPosX() const
+{
+    SGVec3d cartPos = getCartPos();
+    return cartPos.x();
+}
+
+double
+FGAIBase::_getCartPosY() const
+{
+    SGVec3d cartPos = getCartPos();
+    return cartPos.y();
+}
+
+double
+FGAIBase::_getCartPosZ() const
+{
+    SGVec3d cartPos = getCartPos();
+    return cartPos.z();
+}
+
 /*
  * getters and Setters
  */
index 2fa960ace3cb4eb6ea9073ddb399d183d4210f4c..1af25d080266df5f713c73e07c9e7cc07b856513 100644 (file)
@@ -51,7 +51,7 @@ public:
 
     virtual void readFromScenario(SGPropertyNode* scFileNode);
 
-    virtual bool init();
+    virtual bool init(bool search_in_AI_path=false);
     virtual void update(double dt);
     virtual void bind();
     virtual void unbind();
@@ -76,6 +76,10 @@ public:
     bool getDie();
 
     SGVec3d getCartPosAt(const SGVec3d& off) const;
+    SGVec3d getCartPos() const;
+    double _getCartPosX() const;
+    double _getCartPosY() const;
+    double _getCartPosZ() const;
 
 protected:
 
index 1b6bf324d0038d29e5d2e88a193248d075063b0e..72f592a1eec4b2ac0cfd884cceab66b57e2190b7 100644 (file)
@@ -136,12 +136,27 @@ FGAIManager::attach(SGSharedPtr<FGAIBase> model)
   unsigned idx = mNumAiTypeModels[model->getType()];
   const char* typeString = model->getTypeString();
   SGPropertyNode* root = globals->get_props()->getNode("ai/models", true);
-  SGPropertyNode* p = root->getNode(typeString, idx, true);
+  SGPropertyNode* p;
+  int i;
+  for (i=0;i<10000;i++) //find free index in the property tree, if we have
+      //more than 10000 mp-aircrafts in the property tree we should optimize the mp-server
+  {
+    p = root->getNode(typeString, i, false);
+    if (!p) break;
+    if (p->getIntValue("id",-1)==model->getID())
+    {
+        p->setStringValue("callsign","***invalid node***"); //debug only, should never set!
+                                              
+    }
+  }
+  p = root->getNode(typeString, i, true);
   model->setManager(this, p);
   ai_list.push_back(model);
   ++mNumAiModels;
   ++(mNumAiTypeModels[model->getType()]);
-  model->init();
+  model->init(model->getType()==FGAIBase::otAircraft
+      || model->getType()==FGAIBase::otMultiplayer
+      || model->getType()==FGAIBase::otStatic);
   model->bind();
 }
 
index 9a0e80e6f5de8005e3891128e373c20a80cf5e8c..9888d58efaeb54e1417bf6ca0757a3876be1edc0 100755 (executable)
@@ -57,7 +57,7 @@ bool FGAIMultiplayer::init() {
         isTanker = true;
         //        cout << "isTanker " << isTanker << " " << mCallSign <<endl;
     }
-   return FGAIBase::init();
+   return FGAIBase::init(true);
 }
 
 void FGAIMultiplayer::bind() {
index 3c01079874c17723e5ac7f4cc3baeb8900839960..ce8806e5501f1f54a9ca43a8d395ce10db12c63e 100644 (file)
@@ -42,7 +42,7 @@ FGAIStatic::~FGAIStatic() {
 }
 
 bool FGAIStatic::init() {
-   return FGAIBase::init();
+   return FGAIBase::init(true);
 }
 
 void FGAIStatic::bind() {