From cab350d7fcfdb81e54c46ee6338c6a5ede445918 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Thu, 5 Apr 2012 21:06:39 +0200
Subject: [PATCH] YASim performance optimization Use stashed property nodes.

---
 src/FDM/YASim/FGFDM.cpp | 215 +++++++++++++++++++++++++---------------
 src/FDM/YASim/FGFDM.hpp |  23 +++++
 src/FDM/YASim/YASim.cxx | 176 +++++++++++++++++++-------------
 src/FDM/YASim/YASim.hxx |  24 +++++
 4 files changed, 291 insertions(+), 147 deletions(-)

diff --git a/src/FDM/YASim/FGFDM.cpp b/src/FDM/YASim/FGFDM.cpp
index 9f4217800..00c818ff8 100644
--- a/src/FDM/YASim/FGFDM.cpp
+++ b/src/FDM/YASim/FGFDM.cpp
@@ -68,25 +68,28 @@ FGFDM::FGFDM()
 
 FGFDM::~FGFDM()
 {
-    int i;
-    for(i=0; i<_axes.size(); i++) {
-	AxisRec* a = (AxisRec*)_axes.get(i);
-	delete[] a->name;
-	delete a;
+    for(int i=0; i<_axes.size(); i++) {
+        AxisRec* a = (AxisRec*)_axes.get(i);
+        delete[] a->name;
+        delete a;
     }
-    for(i=0; i<_thrusters.size(); i++) {
-	EngRec* er = (EngRec*)_thrusters.get(i);
-	delete[] er->prefix;
-	delete er->eng;
-	delete er;
+
+    for(int i=0; i<_thrusters.size(); i++) {
+        EngRec* er = (EngRec*)_thrusters.get(i);
+        delete[] er->prefix;
+        delete er->eng;
+        delete er;
     }
-    for(i=0; i<_weights.size(); i++) {
-	WeightRec* wr = (WeightRec*)_weights.get(i);
-	delete[] wr->prop;
-	delete wr;
+
+    for(int i=0; i<_weights.size(); i++) {
+        WeightRec* wr = (WeightRec*)_weights.get(i);
+        delete[] wr->prop;
+        delete wr;
     }
-    for(i=0; i<_controlProps.size(); i++)
+
+    for(int i=0; i<_controlProps.size(); i++)
         delete (PropOut*)_controlProps.get(i);
+
     delete _turb;
 }
 
@@ -95,22 +98,20 @@ void FGFDM::iterate(float dt)
     getExternalInput(dt);
     _airplane.iterate(dt);
 
-    // Do fuel stuff (FIXME: should stash SGPropertyNode objects here)
-    char buf[256];
+    // Do fuel stuff
     for(int i=0; i<_airplane.numThrusters(); i++) {
         Thruster* t = _airplane.getThruster(i);
 
-        sprintf(buf, "/engines/engine[%d]/out-of-fuel", i);
-        t->setFuelState(!fgGetBool(buf));
+        bool out_of_fuel = _fuel_props[i]._out_of_fuel->getBoolValue();
+        t->setFuelState(!out_of_fuel);
 
-        sprintf(buf, "/engines/engine[%d]/fuel-consumed-lbs", i);
-        double consumed = fgGetDouble(buf) + dt * KG2LBS * t->getFuelFlow();
-        fgSetDouble(buf, consumed);
+        double consumed = _fuel_props[i]._fuel_consumed_lbs->getDoubleValue();
+        _fuel_props[i]._fuel_consumed_lbs->setDoubleValue(
+                consumed + dt * KG2LBS * t->getFuelFlow());
     }
     for(int i=0; i<_airplane.numTanks(); i++) {
-        sprintf(buf, "/consumables/fuel/tank[%d]/level-lbs", i);
-        _airplane.setFuel(i, LBS2KG * fgGetFloat(buf));
-    } 
+        _airplane.setFuel(i, LBS2KG * _tank_level_lbs[i]->getFloatValue());
+    }
     _airplane.calcFuelWeights();
     
     setOutputProperties(dt);
@@ -123,14 +124,72 @@ Airplane* FGFDM::getAirplane()
 
 void FGFDM::init()
 {
+    _turb_magnitude_norm = fgGetNode("/environment/turbulence/magnitude-norm", true);
+    _turb_rate_hz        = fgGetNode("/environment/turbulence/rate-hz", true);
+    _gross_weight_lbs    = fgGetNode("/yasim/gross-weight-lbs", true);
+
     // Allows the user to start with something other than full fuel
     _airplane.setFuelFraction(fgGetFloat("/sim/fuel-fraction", 1));
 
-    // Read out the resulting fuel state
-    char buf[256];
+    // Read out the resulting fuel state and stash engine/thruster properties
+    _thrust_props.clear();
+    for (int i=0; i<_thrusters.size(); i++) {
+        SGPropertyNode_ptr node = fgGetNode("engines/engine", i, true);
+        Thruster* t = ((EngRec*)_thrusters.get(i))->eng;
+
+        ThrusterProps tp;
+        tp._running =       node->getChild("running", 0, true);
+        tp._cranking =      node->getChild("cranking", 0, true);
+        tp._prop_thrust =   node->getChild("prop-thrust", 0, true); // Deprecated name
+        tp._thrust_lbs =    node->getChild("thrust-lbs", 0, true);
+        tp._fuel_flow_gph = node->getChild("fuel-flow-gph", 0, true);
+
+        if(t->getPropEngine())
+        {
+            tp._rpm = node->getChild("rpm", 0, true);
+            tp._torque_ftlb = node->getChild("torque-ftlb", 0, true);
+
+            PropEngine* p = t->getPropEngine();
+            if(p->getEngine()->isPistonEngine())
+            {
+                tp._mp_osi =   node->getChild("mp-osi",   0, true);
+                tp._mp_inhg =  node->getChild("mp-inhg",  0, true);
+                tp._egt_degf = node->getChild("egt-degf", 0, true);
+
+                tp._oil_temperature_degf = node->getChild("oil-temperature-degf", 0, true);
+                tp._boost_gauge_inhg =     node->getChild("boost-gauge-inhg", 0, true);
+            } else if(p->getEngine()->isTurbineEngine()) {
+                tp._n2 = node->getChild("n2", 0, true);
+            }
+        }
+
+        if(t->getJet())
+        {
+            tp._n1 =       node->getChild("n1",       0, true);
+            tp._n2 =       node->getChild("n2",       0, true);
+            tp._epr =      node->getChild("epr",      0, true);
+            tp._egt_degf = node->getChild("egt-degf", 0, true);
+        }
+        _thrust_props.push_back(tp);
+    }
+
+    // stash properties for engines/fuel state
+    _thrust_props.clear();
+    for(int i=0; i<_airplane.numThrusters(); i++) {
+        SGPropertyNode_ptr e = fgGetNode("engines/engine", i, true);
+        FuelProps f;
+        f._out_of_fuel       = e->getChild("out-of-fuel", 0, true);
+        f._fuel_consumed_lbs = e->getChild("fuel-consumed-lbs", 0, true);
+        _fuel_props.push_back(f);
+    }
+
+    // initialize tanks and stash properties for tank level
+    _tank_level_lbs.clear();
     for(int i=0; i<_airplane.numTanks(); i++) {
+        char buf[256];
         sprintf(buf, "/consumables/fuel/tank[%d]/level-lbs", i);
         fgSetDouble(buf, _airplane.getFuel(i) * KG2LBS);
+        _tank_level_lbs.push_back(fgGetNode(buf, true));
 
         double density = _airplane.getFuelDensity(i);
         sprintf(buf, "/consumables/fuel/tank[%d]/density-ppg", i);
@@ -142,7 +201,7 @@ void FGFDM::init()
 
         sprintf(buf, "/consumables/fuel/tank[%d]/capacity-gal_us", i);
         fgSetDouble(buf, CM2GALS * _airplane.getTankCapacity(i)/density);
-    }    
+    }
 
     // This has a nasty habit of being false at startup.  That's not
     // good.
@@ -484,31 +543,31 @@ void FGFDM::getExternalInput(float dt)
 {
     char buf[256];
 
-    _turb->setMagnitude(fgGetFloat("/environment/turbulence/magnitude-norm"));
-    _turb->update(dt, fgGetFloat("/environment/turbulence/rate-hz"));
+    _turb->setMagnitude(_turb_magnitude_norm->getFloatValue());
+    _turb->update(dt, _turb_rate_hz->getFloatValue());
 
     // The control axes
     ControlMap* cm = _airplane.getControlMap();
     cm->reset();
-    int i;
-    for(i=0; i<_axes.size(); i++) {
-	AxisRec* a = (AxisRec*)_axes.get(i);
-	float val = fgGetFloat(a->name, 0);
-	cm->setInput(a->handle, val);
+
+    for(int i=0; i<_axes.size(); i++) {
+        AxisRec* a = (AxisRec*)_axes.get(i);
+        float val = fgGetFloat(a->name, 0);
+        cm->setInput(a->handle, val);
     }
     cm->applyControls(dt);
 
     // Weights
-    for(i=0; i<_weights.size(); i++) {
-	WeightRec* wr = (WeightRec*)_weights.get(i);
-	_airplane.setWeight(wr->handle, LBS2KG * fgGetFloat(wr->prop));
+    for(int i=0; i<_weights.size(); i++) {
+        WeightRec* wr = (WeightRec*)_weights.get(i);
+        _airplane.setWeight(wr->handle, LBS2KG * fgGetFloat(wr->prop));
     }
 
-    for(i=0; i<_thrusters.size(); i++) {
-	EngRec* er = (EngRec*)_thrusters.get(i);
+    for(int i=0; i<_thrusters.size(); i++) {
+        EngRec* er = (EngRec*)_thrusters.get(i);
         Thruster* t = er->eng;
 
-	if(t->getPropEngine()) {
+        if(t->getPropEngine()) {
             PropEngine* p = t->getPropEngine();
             sprintf(buf, "%s/rpm", er->prefix);
             p->setOmega(fgGetFloat(buf, 500) * RPM2RAD);
@@ -530,14 +589,11 @@ static void moveprop(SGPropertyNode* node, const char* prop,
 
 void FGFDM::setOutputProperties(float dt)
 {
-    // char buf[256];
-    int i;
-
     float grossWgt = _airplane.getModel()->getBody()->getTotalMass() * KG2LBS;
-    fgSetFloat("/yasim/gross-weight-lbs", grossWgt);
+    _gross_weight_lbs->setFloatValue(grossWgt);
 
     ControlMap* cm = _airplane.getControlMap();
-    for(i=0; i<_controlProps.size(); i++) {
+    for(int i=0; i<_controlProps.size(); i++) {
         PropOut* p = (PropOut*)_controlProps.get(i);
         float val = (p->left
                      ? cm->getOutput(p->handle)
@@ -549,7 +605,7 @@ void FGFDM::setOutputProperties(float dt)
         p->prop->setFloatValue(val);
     }
 
-    for(i=0; i<_airplane.getRotorgear()->getNumRotors(); i++) {
+    for(int i=0; i<_airplane.getRotorgear()->getNumRotors(); i++) {
         Rotor*r=(Rotor*)_airplane.getRotorgear()->getRotor(i);
         int j = 0;
         float f;
@@ -574,52 +630,54 @@ void FGFDM::setOutputProperties(float dt)
     float fuelDensity = 1.0;
     if(_airplane.numTanks())
         fuelDensity = _airplane.getFuelDensity(0);
-    for(i=0; i<_thrusters.size(); i++) {
-	EngRec* er = (EngRec*)_thrusters.get(i);
+    for(int i=0; i<_thrusters.size(); i++) {
+        EngRec* er = (EngRec*)_thrusters.get(i);
         Thruster* t = er->eng;
         SGPropertyNode * node = fgGetNode("engines/engine", i, true);
 
+        ThrusterProps& tp = _thrust_props[i];
+
         // Set: running, cranking, prop-thrust, max-hp, power-pct
-	node->setBoolValue("running", t->isRunning());
-	node->setBoolValue("cranking", t->isCranking());
+        tp._running->setBoolValue(t->isRunning());
+        tp._cranking->setBoolValue(t->isCranking());
 
         float tmp[3];
         t->getThrust(tmp);
         float lbs = Math::mag3(tmp) * (KG2LBS/9.8);
-	node->setFloatValue("prop-thrust", lbs); // Deprecated name
-	node->setFloatValue("thrust-lbs", lbs);
-        node->setFloatValue("fuel-flow-gph",
-                            (t->getFuelFlow()/fuelDensity) * 3600 * CM2GALS);
+        tp._prop_thrust->setFloatValue(lbs); // Deprecated name
+        tp._thrust_lbs->setFloatValue(lbs);
+        tp._fuel_flow_gph->setFloatValue(
+                (t->getFuelFlow()/fuelDensity) * 3600 * CM2GALS);
 
-	if(t->getPropEngine()) {
+        if(t->getPropEngine()) {
             PropEngine* p = t->getPropEngine();
-            node->setFloatValue("rpm", p->getOmega() * (1/RPM2RAD));
-            node->setFloatValue("torque-ftlb",
-                                p->getEngine()->getTorque() * NM2FTLB);
-        
+            tp._rpm->setFloatValue(p->getOmega() * (1/RPM2RAD));
+            tp._torque_ftlb->setFloatValue(
+                    p->getEngine()->getTorque() * NM2FTLB);
+
             if(p->getEngine()->isPistonEngine()) {
                 PistonEngine* pe = p->getEngine()->isPistonEngine();
-                node->setFloatValue("mp-osi", pe->getMP() * (1/INHG2PA));
-                node->setFloatValue("mp-inhg", pe->getMP() * (1/INHG2PA));
-                node->setFloatValue("egt-degf",
-                                    pe->getEGT() * K2DEGF + K2DEGFOFFSET);
-                node->setFloatValue("oil-temperature-degf",
-                                    pe->getOilTemp() * K2DEGF + K2DEGFOFFSET);
-                node->setFloatValue("boost-gauge-inhg",
-                                    pe->getBoost() * (1/INHG2PA));
+                tp._mp_osi->setFloatValue(pe->getMP() * (1/INHG2PA));
+                tp._mp_inhg->setFloatValue(pe->getMP() * (1/INHG2PA));
+                tp._egt_degf->setFloatValue(
+                        pe->getEGT() * K2DEGF + K2DEGFOFFSET);
+                tp._oil_temperature_degf->setFloatValue(
+                        pe->getOilTemp() * K2DEGF + K2DEGFOFFSET);
+                tp._boost_gauge_inhg->setFloatValue(
+                        pe->getBoost() * (1/INHG2PA));
             } else if(p->getEngine()->isTurbineEngine()) {
                 TurbineEngine* te = p->getEngine()->isTurbineEngine();
-                node->setFloatValue("n2", te->getN2());
+                tp._n2->setFloatValue(te->getN2());
             }
         }
 
         if(t->getJet()) {
             Jet* j = t->getJet();
-            node->setFloatValue("n1", j->getN1());
-            node->setFloatValue("n2", j->getN2());
-            node->setFloatValue("epr", j->getEPR());
-            node->setFloatValue("egt-degf",
-                                j->getEGT() * K2DEGF + K2DEGFOFFSET);
+            tp._n1->setFloatValue(j->getN1());
+            tp._n2->setFloatValue(j->getN2());
+            tp._epr->setFloatValue(j->getEPR());
+            tp._egt_degf->setFloatValue(
+                    j->getEGT() * K2DEGF + K2DEGFOFFSET);
 
             // These are "unmodeled" values that are still needed for
             // many cockpits.  Tie them all to the N1 speed, but
@@ -921,11 +979,10 @@ void FGFDM::parsePropeller(XMLAttributes* a)
 // yet.
 int FGFDM::parseAxis(const char* name)
 {
-    int i;
-    for(i=0; i<_axes.size(); i++) {
-	AxisRec* a = (AxisRec*)_axes.get(i);
-	if(eq(a->name, name))
-	    return a->handle;
+    for(int i=0; i<_axes.size(); i++) {
+        AxisRec* a = (AxisRec*)_axes.get(i);
+        if(eq(a->name, name))
+            return a->handle;
     }
 
     // Not there, make a new one.
diff --git a/src/FDM/YASim/FGFDM.hpp b/src/FDM/YASim/FGFDM.hpp
index 0d5b43e37..25aa1a67c 100644
--- a/src/FDM/YASim/FGFDM.hpp
+++ b/src/FDM/YASim/FGFDM.hpp
@@ -83,6 +83,29 @@ private:
     void* _currObj;
     bool _cruiseCurr;
     int _nextEngine;
+
+    class FuelProps
+    {
+    public:
+        SGPropertyNode_ptr _out_of_fuel;
+        SGPropertyNode_ptr _fuel_consumed_lbs;
+    };
+
+    class ThrusterProps
+    {
+    public:
+        SGPropertyNode_ptr _running, _cranking;
+        SGPropertyNode_ptr _prop_thrust, _thrust_lbs, _fuel_flow_gph;
+        SGPropertyNode_ptr _rpm, _torque_ftlb, _mp_osi, _mp_inhg;
+        SGPropertyNode_ptr _oil_temperature_degf, _boost_gauge_inhg;
+        SGPropertyNode_ptr _n1, _n2, _epr, _egt_degf;
+    };
+
+    SGPropertyNode_ptr _turb_magnitude_norm, _turb_rate_hz;
+    SGPropertyNode_ptr _gross_weight_lbs;
+    vector<SGPropertyNode_ptr> _tank_level_lbs;
+    vector<ThrusterProps> _thrust_props;
+    vector<FuelProps> _fuel_props;
 };
 
 }; // namespace yasim
diff --git a/src/FDM/YASim/YASim.cxx b/src/FDM/YASim/YASim.cxx
index 3cfd050d0..6292656d2 100644
--- a/src/FDM/YASim/YASim.cxx
+++ b/src/FDM/YASim/YASim.cxx
@@ -58,6 +58,8 @@ YASim::YASim(double dt) :
 YASim::~YASim()
 {
     delete _fdm;
+
+    _gearProps.clear();
 }
 
 void YASim::report()
@@ -75,7 +77,6 @@ void YASim::report()
     SG_LOG(SG_FLIGHT,SG_INFO,"       Cruise AoA: "<< aoa);
     SG_LOG(SG_FLIGHT,SG_INFO,"   Tail Incidence: "<< tail);
     SG_LOG(SG_FLIGHT,SG_INFO,"Approach Elevator: "<<a->getApproachElevator());
-    
 
     float cg[3];
     char buf[256];
@@ -102,30 +103,52 @@ void YASim::bind()
 
     char buf[256];
     for(int i=0; i<_fdm->getAirplane()->getModel()->numThrusters(); i++) {
-	sprintf(buf, "/engines/engine[%d]/fuel-flow-gph", i);        fgUntie(buf);
-	sprintf(buf, "/engines/engine[%d]/rpm", i);                  fgUntie(buf);
-	sprintf(buf, "/engines/engine[%d]/mp-osi", i);               fgUntie(buf);
-	sprintf(buf, "/engines/engine[%d]/egt-degf", i);             fgUntie(buf);
-	sprintf(buf, "/engines/engine[%d]/oil-temperature-degf", i); fgUntie(buf);
+        sprintf(buf, "/engines/engine[%d]/fuel-flow-gph", i);        fgUntie(buf);
+        sprintf(buf, "/engines/engine[%d]/rpm", i);                  fgUntie(buf);
+        sprintf(buf, "/engines/engine[%d]/mp-osi", i);               fgUntie(buf);
+        sprintf(buf, "/engines/engine[%d]/egt-degf", i);             fgUntie(buf);
+        sprintf(buf, "/engines/engine[%d]/oil-temperature-degf", i); fgUntie(buf);
     }
 }
 
+YASim::GearProps::GearProps(SGPropertyNode_ptr gear_root) :
+    has_brake(gear_root->getNode("has-brake", true)),
+    wow(gear_root->getNode("wow", true)),
+    compression_norm(gear_root->getNode("compression-norm", true)),
+    compression_m(gear_root->getNode("compression-m", true)),
+    caster_angle_deg(gear_root->getNode("caster-angle-deg", true)),
+    rollspeed_ms(gear_root->getNode("rollspeed-ms", true)),
+    ground_is_solid(gear_root->getNode("ground-is-solid", true)),
+    ground_friction_factor(gear_root->getNode("ground-friction-factor", true))
+{
+}
+
 void YASim::init()
 {
-    Airplane* a = _fdm->getAirplane();
-    Model* m = a->getModel();
+    Airplane* airplane = _fdm->getAirplane();
+    Model* model = airplane->getModel();
+
+    _crashed         = fgGetNode("/sim/crashed", true);
+    _pressure_inhg   = fgGetNode("/environment/pressure-inhg", true);
+    _temp_degc       = fgGetNode("/environment/temperature-degc", true);
+    _density_slugft3 = fgGetNode("/environment/density-slugft3", true);
+    _gear_agl_m      = fgGetNode("/position/gear-agl-m", true);
+    _gear_agl_ft     = fgGetNode("/position/gear-agl-ft", true);
+    _pilot_g         = fgGetNode("/accelerations/pilot-g", true);
+    _speed_setprop   = fgGetNode("/sim/presets/speed-set", true);
 
     // Superclass hook
     common_init();
 
-    m->setCrashed(false);
+    model->setCrashed(false);
+    _crashed->setBoolValue(false);
 
     // Figure out the initial speed type
-    string speed_set = fgGetString("/sim/presets/speed-set", "UVW");
-    if (speed_set == "NED")
-        _speed_set = NED;
-    else if (speed_set == "UVW")
+    string speed_set = _speed_setprop->getStringValue();
+    if ((speed_set == "") || (speed_set == "UVW"))
         _speed_set = UVW;
+    else if (speed_set == "NED")
+        _speed_set = NED;
     else if (speed_set == "knots")
         _speed_set = KNOTS;
     else if (speed_set == "mach")
@@ -149,21 +172,35 @@ void YASim::init()
     }
 
     // Compile it into a real airplane, and tell the user what they got
-    a->compile();
+    airplane->compile();
     report();
 
     _fdm->init();
 
+    if (model->getLaunchbar())
+    {
+        _catapult_launch_cmd         = fgGetNode("/controls/gear/catapult-launch-cmd", true);
+        _launchbar_position_norm     = fgGetNode("/gear/launchbar/position-norm", true);
+        _launchbar_holdback_pos_norm = fgGetNode("/gear/launchbar/holdback-position-norm", true);
+        _launchbar_state             = fgGetNode("/gear/launchbar/state", true);
+        _launchbar_strop             = fgGetNode("/gear/launchbar/strop", true);
+    }
+    if (airplane->getHook())
+    {
+        _tailhook_position_norm = fgGetNode("/gear/tailhook/position-norm", 0, true);
+    }
+
     // Create some FG{Eng|Gear}Interface objects
-    int i;
-    for(i=0; i<a->numGear(); i++) {
-        Gear* g = a->getGear(i);
-	SGPropertyNode * node = fgGetNode("gear/gear", i, true);
+    for(int i=0; i<airplane->numGear(); i++) {
+        Gear* g = airplane->getGear(i);
+        SGPropertyNode * node = fgGetNode("gear/gear", i, true);
         float pos[3];
         g->getPosition(pos);
-	node->setDoubleValue("xoffset-in", pos[0] * M2FT * 12);
-	node->setDoubleValue("yoffset-in", pos[1] * M2FT * 12);
-	node->setDoubleValue("zoffset-in", pos[2] * M2FT * 12);
+        node->setDoubleValue("xoffset-in", pos[0] * M2FT * 12);
+        node->setDoubleValue("yoffset-in", pos[1] * M2FT * 12);
+        node->setDoubleValue("zoffset-in", pos[2] * M2FT * 12);
+
+        _gearProps.push_back(GearProps(node));
     }
 
     // Are we at ground level?  If so, lift the plane up so the gear
@@ -171,21 +208,21 @@ void YASim::init()
     double runway_altitude = get_Runway_altitude();
     if(get_Altitude() - runway_altitude < 50) {
         fgSetBool("/controls/gear/gear-down", false);
-	float minGearZ = 1e18;
-	for(i=0; i<a->numGear(); i++) {
-	    Gear* g = a->getGear(i);
-	    float pos[3];
-	    g->getPosition(pos);
-	    if(pos[2] < minGearZ)
-		minGearZ = pos[2];
-	}
-	_set_Altitude(runway_altitude - minGearZ*M2FT);
-	fgSetBool("/controls/gear/gear-down", true);
+        float minGearZ = 1e18;
+        for(int i=0; i<airplane->numGear(); i++) {
+            Gear* g = airplane->getGear(i);
+            float pos[3];
+            g->getPosition(pos);
+            if(pos[2] < minGearZ)
+                minGearZ = pos[2];
+        }
+        _set_Altitude(runway_altitude - minGearZ*M2FT);
+        fgSetBool("/controls/gear/gear-down", true);
     }
 
     // Blank the state, and copy in ours
     State s;
-    m->setState(&s);
+    model->setState(&s);
     copyToYASim(true);
 
     _fdm->getExternalInput();
@@ -202,9 +239,9 @@ void YASim::update(double dt)
     int iterations = _calc_multiloop(dt);
 
     // If we're crashed, then we don't care
-    if(fgGetBool("/sim/crashed") || _fdm->getAirplane()->getModel()->isCrashed()) {
-        if(!fgGetBool("/sim/crashed"))
-            fgSetBool("/sim/crashed", true);
+    if(_crashed->getBoolValue() || _fdm->getAirplane()->getModel()->isCrashed()) {
+        if(!_crashed->getBoolValue())
+            _crashed->setBoolValue(true);
         _fdm->getAirplane()->getModel()->setCrashed(false);
         return;
     }
@@ -254,10 +291,10 @@ void YASim::copyToYASim(bool copyState)
     wind[1] = get_V_east_airmass() * FT2M * -1.0;
     wind[2] = get_V_down_airmass() * FT2M * -1.0;
 
-    float pressure = fgGetFloat("/environment/pressure-inhg") * INHG2PA;
-    float temp = fgGetFloat("/environment/temperature-degc") + 273.15;
-    float dens = fgGetFloat("/environment/density-slugft3") 
-        * SLUG2KG * M2FT*M2FT*M2FT;
+    float pressure = _pressure_inhg->getFloatValue() * INHG2PA;
+    float temp     = _temp_degc->getFloatValue() + 273.15;
+    float dens     = _density_slugft3->getFloatValue() *
+                            SLUG2KG * M2FT*M2FT*M2FT;
 
     // Convert and set:
     Model* model = _fdm->getAirplane()->getModel();
@@ -278,7 +315,6 @@ void YASim::copyToYASim(bool copyState)
     Math::mmul33(s.orient, xyz2ned, s.orient);
 
     // Velocity
-    string speed_set = fgGetString("/sim/presets/speed-set", "UVW");
     float v[3];
     bool needCopy = false;
     switch (_speed_set) {
@@ -334,7 +370,7 @@ void YASim::copyToYASim(bool copyState)
 
     Launchbar* l = model->getLaunchbar();
     if (l)
-        l->setLaunchCmd(0.0<fgGetFloat("/controls/gear/catapult-launch-cmd"));
+        l->setLaunchCmd(0.0 < _catapult_launch_cmd->getFloatValue());
 }
 
 // All the settables:
@@ -397,8 +433,8 @@ void YASim::copyFromYASim()
     _set_Altitude_AGL((alt-groundlevel_m)*SG_METER_TO_FEET);
 
     // the smallest agl of all gears
-    fgSetFloat("/position/gear-agl-m", model->getAGL());
-    fgSetFloat("/position/gear-agl-ft", model->getAGL()*M2FT);
+    _gear_agl_m->setFloatValue(model->getAGL());
+    _gear_agl_ft->setFloatValue(model->getAGL()*M2FT);
 
     // UNUSED
     //_set_Geocentric_Position(Glue::geod2geocLat(lat), lon, alt*M2FT);
@@ -412,7 +448,7 @@ void YASim::copyFromYASim()
     Math::vmul33(xyz2ned, s->v, v);
     _set_Velocities_Local(M2FT*v[0], M2FT*v[1], M2FT*v[2]);
     _set_V_ground_speed(Math::sqrt(M2FT*v[0]*M2FT*v[0] +
-				   M2FT*v[1]*M2FT*v[1]));
+                                   M2FT*v[1]*M2FT*v[1]));
     _set_Climb_Rate(-M2FT*v[2]);
 
     // The HUD uses this, but inverts down (?!)
@@ -431,9 +467,9 @@ void YASim::copyFromYASim()
     _set_Velocities_Wind_Body(v[0]*M2FT, -v[1]*M2FT, -v[2]*M2FT);
     _set_V_rel_wind(Math::mag3(v)*M2FT); // units?
 
-    float P = fgGetDouble("/environment/pressure-inhg") * INHG2PA;
-    float T = fgGetDouble("/environment/temperature-degc") + 273.15;
-    float D = fgGetFloat("/environment/density-slugft3")
+    float P = _pressure_inhg->getFloatValue() * INHG2PA;
+    float T = _temp_degc->getFloatValue() + 273.15;
+    float D = _density_slugft3->getFloatValue()
         *SLUG2KG * M2FT*M2FT*M2FT;
     _set_V_equiv_kts(Atmosphere::calcVEAS(v[0], P, T, D)*MPS2KTS);
     _set_V_calibrated_kts(Atmosphere::calcVCAS(v[0], P, T)*MPS2KTS);
@@ -453,7 +489,7 @@ void YASim::copyFromYASim()
     // There is no property for pilot G's, but I need it for a panel
     // instrument.  Hack this in here, and REMOVE IT WHEN IT FINDS A
     // REAL HOME!
-    fgSetFloat("/accelerations/pilot-g", -v[2]/9.8);
+    _pilot_g->setFloatValue(-v[2]/9.8);
 
     // The one appears (!) to want inverted pilot acceleration
     // numbers, in G's...
@@ -483,40 +519,44 @@ void YASim::copyFromYASim()
     _set_Euler_Rates(roll, pitch, hdg);
 
     // Fill out our engine and gear objects
-    int i;
-    for(i=0; i<airplane->numGear(); i++) {
+    for(int i=0; i<airplane->numGear(); i++) {
         Gear* g = airplane->getGear(i);
-	SGPropertyNode * node = fgGetNode("gear/gear", i, true);
-	node->setBoolValue("has-brake", g->getBrake() != 0);
-	node->setBoolValue("wow", g->getCompressFraction() != 0);
-	node->setFloatValue("compression-norm", g->getCompressFraction());
-	node->setFloatValue("compression-m", g->getCompressDist());
-        node->setFloatValue("caster-angle-deg", g->getCasterAngle() * RAD2DEG);
-        node->setFloatValue("rollspeed-ms", g->getRollSpeed());
-        node->setBoolValue("ground-is-solid", g->getGroundIsSolid()!=0);
-        node->setFloatValue("ground-friction-factor", g->getGroundFrictionFactor());
+        GearProps& gearProps = _gearProps[i];
+        gearProps.has_brake->setBoolValue(
+                g->getBrake() != 0);
+        gearProps.wow->setBoolValue(
+                g->getCompressFraction() != 0);
+        gearProps.compression_norm->setFloatValue(
+                g->getCompressFraction());
+        gearProps.compression_m->setFloatValue(
+                g->getCompressDist());
+        gearProps.caster_angle_deg->setFloatValue(
+                g->getCasterAngle() * RAD2DEG);
+        gearProps.rollspeed_ms->setFloatValue(
+                g->getRollSpeed());
+        gearProps.ground_is_solid->setBoolValue(
+                g->getGroundIsSolid()!=0);
+        gearProps.ground_friction_factor->setFloatValue(
+                g->getGroundFrictionFactor());
     }
 
     Hook* h = airplane->getHook();
     if(h) {
-	SGPropertyNode * node = fgGetNode("gear/tailhook", 0, true);
-	node->setFloatValue("position-norm", h->getCompressFraction());
+        _tailhook_position_norm->setFloatValue(h->getCompressFraction());
     }
 
     Launchbar* l = airplane->getLaunchbar();
     if(l) {
-	SGPropertyNode * node = fgGetNode("gear/launchbar", 0, true);
-	node->setFloatValue("position-norm", l->getCompressFraction());
-        node->setFloatValue("holdback-position-norm", l->getHoldbackCompressFraction());
-        node->setStringValue("state", l->getState());
-        node->setBoolValue("strop", l->getStrop());
+        _launchbar_position_norm->setFloatValue(l->getCompressFraction());
+        _launchbar_holdback_pos_norm->setFloatValue(l->getHoldbackCompressFraction());
+        _launchbar_state->setStringValue(l->getState());
+        _launchbar_strop->setBoolValue(l->getStrop());
     }
-
 }
 
 /** Reinit the FDM.
  * This is only used after a replay session and when the user requested to resume at
- * a past point of time. In thise case the FDM must reload all values from the property
+ * a past point of time. In this case the FDM must reload all values from the property
  * tree (as given by the replay system). */
 void YASim::reinit()
 {
diff --git a/src/FDM/YASim/YASim.hxx b/src/FDM/YASim/YASim.hxx
index eb67cadec..4948f5e28 100644
--- a/src/FDM/YASim/YASim.hxx
+++ b/src/FDM/YASim/YASim.hxx
@@ -2,6 +2,7 @@
 #define _YASIM_HXX
 
 #include <FDM/flight.hxx>
+#include <vector>
 
 namespace yasim { class FGFDM; };
 
@@ -34,6 +35,29 @@ public:
         MACH
     } _speed_set;
 
+    class GearProps
+    {
+    public:
+        GearProps(SGPropertyNode_ptr gear_root);
+
+        SGPropertyNode_ptr has_brake;
+        SGPropertyNode_ptr wow;
+        SGPropertyNode_ptr compression_norm;
+        SGPropertyNode_ptr compression_m;
+        SGPropertyNode_ptr caster_angle_deg;
+        SGPropertyNode_ptr rollspeed_ms;
+        SGPropertyNode_ptr ground_is_solid;
+        SGPropertyNode_ptr ground_friction_factor;
+    };
+
+    SGPropertyNode_ptr _crashed;
+    SGPropertyNode_ptr _pressure_inhg, _temp_degc, _density_slugft3;
+    SGPropertyNode_ptr _gear_agl_m, _gear_agl_ft;
+    SGPropertyNode_ptr _pilot_g, _speed_setprop;
+    SGPropertyNode_ptr _catapult_launch_cmd, _tailhook_position_norm;
+    SGPropertyNode_ptr _launchbar_position_norm, _launchbar_holdback_pos_norm;
+    SGPropertyNode_ptr _launchbar_state, _launchbar_strop;
+    vector<GearProps> _gearProps;
 };
 
 #endif // _YASIM_HXX