bool FGAIAircraft::init() {
//refuel_node = fgGetNode("systems/refuel/contact", true);
- return FGAIBase::init();
+ return FGAIBase::init(true);
}
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
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);
}
}
-
-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);
}
setDie(false);
-
return true;
}
&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));
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");
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
*/
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();
}