]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/YASim/Airplane.cpp
Fix bug 141, by ensuring certain subsystems are assigned to the 'post FDM' group...
[flightgear.git] / src / FDM / YASim / Airplane.cpp
index e9763673e3eecce6741a1ea2ec9665349a4f31a0..483da426911dcdcd73addc1da6bb6991d6068551 100644 (file)
@@ -6,8 +6,8 @@
 #include "RigidBody.hpp"
 #include "Surface.hpp"
 #include "Rotorpart.hpp"
-#include "Rotorblade.hpp"
 #include "Thruster.hpp"
+#include "Hitch.hpp"
 #include "Airplane.hpp"
 
 namespace yasim {
@@ -39,16 +39,20 @@ Airplane::Airplane()
     _cruiseT = 0;
     _cruiseSpeed = 0;
     _cruiseWeight = 0;
+    _cruiseGlideAngle = 0;
     _approachP = 0;
     _approachT = 0;
     _approachSpeed = 0;
     _approachAoA = 0;
     _approachWeight = 0;
+    _approachGlideAngle = 0;
 
     _dragFactor = 1;
     _liftRatio = 1;
     _cruiseAoA = 0;
     _tailIncidence = 0;
+
+    _failureMsg = 0;
 }
 
 Airplane::~Airplane()
@@ -60,14 +64,33 @@ Airplane::~Airplane()
        delete (Tank*)_tanks.get(i);
     for(i=0; i<_thrusters.size(); i++)
        delete (ThrustRec*)_thrusters.get(i);
-    for(i=0; i<_gears.size(); i++)
-       delete (GearRec*)_gears.get(i);
+    for(i=0; i<_gears.size(); i++) {
+       GearRec* g = (GearRec*)_gears.get(i);
+        delete g->gear;
+        delete g;
+    }
     for(i=0; i<_surfs.size(); i++)
        delete (Surface*)_surfs.get(i);    
-    for(i=0; i<_contacts.size(); i++)
-        delete[] (float*)_contacts.get(i);
+    for(i=0; i<_contacts.size(); i++) {
+        ContactRec* c = (ContactRec*)_contacts.get(i);
+        delete c->gear;
+        delete c;
+    }
     for(i=0; i<_solveWeights.size(); i++)
-        delete[] (SolveWeight*)_solveWeights.get(i);
+        delete (SolveWeight*)_solveWeights.get(i);
+    for(i=0; i<_cruiseControls.size(); i++)
+        delete (Control*)_cruiseControls.get(i);
+    for(i=0; i<_approachControls.size(); i++) {
+        Control* c = (Control*)_approachControls.get(i);
+        if(c != &_approachElevator)
+            delete c;
+    }
+    delete _wing;
+    delete _tail;
+    for(i=0; i<_vstabs.size(); i++)
+        delete (Wing*)_vstabs.get(i);
+    for(i=0; i<_weights.size(); i++)
+        delete (WeightRec*)_weights.get(i);
 }
 
 void Airplane::iterate(float dt)
@@ -147,6 +170,11 @@ Launchbar* Airplane::getLaunchbar()
     return _model.getLaunchbar();
 }
 
+Rotorgear* Airplane::getRotorgear()
+{
+    return _model.getRotorgear();
+}
+
 void Airplane::updateGearState()
 {
     for(int i=0; i<_gears.size(); i++) {
@@ -159,16 +187,17 @@ void Airplane::updateGearState()
     }
 }
 
-void Airplane::setApproach(float speed, float altitude, float aoa, float fuel)
+void Airplane::setApproach(float speed, float altitude, float aoa, float fuel, float gla)
 {
     _approachSpeed = speed;
     _approachP = Atmosphere::getStdPressure(altitude);
     _approachT = Atmosphere::getStdTemperature(altitude);
     _approachAoA = aoa;
     _approachFuel = fuel;
+    _approachGlideAngle = gla;
 }
  
-void Airplane::setCruise(float speed, float altitude, float fuel)
+void Airplane::setCruise(float speed, float altitude, float fuel, float gla)
 {
     _cruiseSpeed = speed;
     _cruiseP = Atmosphere::getStdPressure(altitude);
@@ -176,6 +205,7 @@ void Airplane::setCruise(float speed, float altitude, float fuel)
     _cruiseAoA = 0;
     _tailIncidence = 0;
     _cruiseFuel = fuel;
+    _cruiseGlideAngle = gla;
 }
 
 void Airplane::setElevatorControl(int control)
@@ -255,13 +285,9 @@ void Airplane::addVStab(Wing* vstab)
     _vstabs.add(vstab);
 }
 
-void Airplane::addRotor(Rotor* rotor)
-{
-    _rotors.add(rotor);
-}
-
 void Airplane::addFuselage(float* front, float* back, float width,
-                           float taper, float mid)
+                           float taper, float mid, 
+                           float cx, float cy, float cz, float idrag)
 {
     Fuselage* f = new Fuselage();
     int i;
@@ -272,6 +298,10 @@ void Airplane::addFuselage(float* front, float* back, float width,
     f->width = width;
     f->taper = taper;
     f->mid = mid;
+    f->_cx=cx;
+    f->_cy=cy;
+    f->_cz=cz;
+    f->_idrag=idrag;
     _fuselages.add(f);
 }
 
@@ -300,6 +330,11 @@ void Airplane::addHook(Hook* hook)
     _model.addHook(hook);
 }
 
+void Airplane::addHitch(Hitch* hitch)
+{
+    _model.addHitch(hitch);
+}
+
 void Airplane::addLaunchbar(Launchbar* launchbar)
 {
     _model.addLaunchbar(launchbar);
@@ -384,7 +419,7 @@ float Airplane::getTailIncidence()
     return _tailIncidence;
 }
 
-char* Airplane::getFailureMsg()
+const char* Airplane::getFailureMsg()
 {
     return _failureMsg;
 }
@@ -394,7 +429,7 @@ int Airplane::getSolutionIterations()
     return _solutionIterations;
 }
 
-void Airplane::setupState(float aoa, float speed, State* s)
+void Airplane::setupState(float aoa, float speed, float gla, State* s)
 {
     float cosAoA = Math::cos(aoa);
     float sinAoA = Math::sin(aoa);
@@ -402,7 +437,7 @@ void Airplane::setupState(float aoa, float speed, State* s)
     s->orient[3] =       0; s->orient[4] = 1; s->orient[5] =      0;
     s->orient[6] = -sinAoA; s->orient[7] = 0; s->orient[8] = cosAoA;
 
-    s->v[0] = speed; s->v[1] = 0; s->v[2] = 0;
+    s->v[0] = speed*Math::cos(gla); s->v[1] = -speed*Math::sin(gla); s->v[2] = 0;
 
     int i;
     for(i=0; i<3; i++)
@@ -415,11 +450,12 @@ void Airplane::setupState(float aoa, float speed, State* s)
 
 void Airplane::addContactPoint(float* pos)
 {
-    float* cp = new float[3];
-    cp[0] = pos[0];
-    cp[1] = pos[1];
-    cp[2] = pos[2];
-    _contacts.add(cp);
+    ContactRec* c = new ContactRec;
+    c->gear = 0;
+    c->p[0] = pos[0];
+    c->p[1] = pos[1];
+    c->p[2] = pos[2];
+    _contacts.add(c);
 }
 
 float Airplane::compileWing(Wing* w)
@@ -458,41 +494,9 @@ float Airplane::compileWing(Wing* w)
     return wgt;
 }
 
-float Airplane::compileRotor(Rotor* r)
+void Airplane::compileRotorgear()
 {
-    // Todo: add rotor to model!!!
-    // Todo: calc and add mass!!!
-    r->compile();
-    _model.addRotor(r);
-
-    float wgt = 0;
-    int i;
-    for(i=0; i<r->numRotorparts(); i++) {
-        Rotorpart* s = (Rotorpart*)r->getRotorpart(i);
-
-        _model.addRotorpart(s);
-        
-        float mass = s->getWeight();
-        mass = mass * Math::sqrt(mass);
-        float pos[3];
-        s->getPosition(pos);
-        _model.getBody()->addMass(mass, pos);
-        wgt += mass;
-    }
-    
-    for(i=0; i<r->numRotorblades(); i++) {
-        Rotorblade* b = (Rotorblade*)r->getRotorblade(i);
-
-        _model.addRotorblade(b);
-        
-        float mass = b->getWeight();
-        mass = mass * Math::sqrt(mass);
-        float pos[3];
-        b->getPosition(pos);
-        _model.getBody()->addMass(mass, pos);
-        wgt += mass;
-    }
-    return wgt;
+    getRotorgear()->compile();
 }
 
 float Airplane::compileFuselage(Fuselage* f)
@@ -505,6 +509,10 @@ float Airplane::compileFuselage(Fuselage* f)
     float fwd[3];
     Math::sub3(f->front, f->back, fwd);
     float len = Math::mag3(fwd);
+    if (len == 0) {
+        _failureMsg = "Zero length fuselage";
+       return 0;
+    }
     float wid = f->width;
     int segs = (int)Math::ceil(len/wid);
     float segWgt = len*wid/segs;
@@ -532,9 +540,10 @@ float Airplane::compileFuselage(Fuselage* f)
         Surface* s = new Surface();
         s->setPosition(pos);
        float sideDrag = len/wid;
-        s->setYDrag(sideDrag);
-        s->setZDrag(sideDrag);
-        s->setTotalDrag(scale*segWgt);
+        s->setYDrag(sideDrag*f->_cy);
+        s->setZDrag(sideDrag*f->_cz);
+        s->setTotalDrag(scale*segWgt*f->_cx);
+        s->setInducedDrag(f->_idrag);
 
         // FIXME: fails for fuselages aligned along the Y axis
         float o[9];
@@ -595,10 +604,11 @@ void Airplane::compileContactPoints()
 
     int i;
     for(i=0; i<_contacts.size(); i++) {
-        float *cp = (float*)_contacts.get(i);
+        ContactRec* c = (ContactRec*)_contacts.get(i);
 
         Gear* g = new Gear();
-        g->setPosition(cp);
+        c->gear = g;
+        g->setPosition(c->p);
         
         g->setCompression(comp);
         g->setSpring(spring);
@@ -608,6 +618,7 @@ void Airplane::compileContactPoints()
         // I made these up
         g->setStaticFriction(0.6f);
         g->setDynamicFriction(0.5f);
+        g->setContactPoint(1);
 
         _model.addGear(g);
     }
@@ -631,9 +642,8 @@ void Airplane::compile()
     int i;
     for(i=0; i<_vstabs.size(); i++)
         aeroWgt += compileWing((Wing*)_vstabs.get(i)); 
-    for(i=0; i<_rotors.size(); i++)
-        aeroWgt += compileRotor((Rotor*)_rotors.get(i)); 
-    
+
+
     // The fuselage(s)
     for(i=0; i<_fuselages.size(); i++)
         aeroWgt += compileFuselage((Fuselage*)_fuselages.get(i));
@@ -684,9 +694,18 @@ void Airplane::compile()
         _model.setGroundEffect(gepos, gespan, 0.15f);
     }
 
+    // solve function below resets failure message
+    // so check if we have any problems and abort here
+    if (_failureMsg) return;
+
     solveGear();
     if(_wing && _tail) solve();
-    else solveHelicopter();
+    else
+    {
+       // The rotor(s) mass:
+       compileRotorgear(); 
+       solveHelicopter();
+    }
 
     // Do this after solveGear, because it creates "gear" objects that
     // we don't want to affect.
@@ -711,7 +730,8 @@ void Airplane::solveGear()
         g->getPosition(pos);
        Math::sub3(cg, pos, pos);
         gr->wgt = 1.0f/(0.5f+Math::sqrt(pos[0]*pos[0] + pos[1]*pos[1]));
-        total += gr->wgt;
+        if (!g->getIgnoreWhileSolving())
+            total += gr->wgt;
     }
 
     // Renormalize so they sum to 1
@@ -733,7 +753,7 @@ void Airplane::solveGear()
         float e = energy * gr->wgt;
         float comp[3];
         gr->gear->getCompression(comp);
-        float len = Math::mag3(comp);
+        float len = Math::mag3(comp)*(1+2*gr->gear->getInitialLoad());
 
         // Energy in a spring: e = 0.5 * k * len^2
         float k = 2 * e / (len*len);
@@ -743,10 +763,6 @@ void Airplane::solveGear()
         // Critically damped (too damped, too!)
         gr->gear->setDamping(2*Math::sqrt(k*_approachWeight*gr->wgt)
                              * gr->gear->getDamping());
-
-        // These are pretty generic
-        gr->gear->setStaticFriction(0.8f);
-        gr->gear->setDynamicFriction(0.7f);
     }
 }
 
@@ -779,7 +795,7 @@ void Airplane::setupWeights(bool isApproach)
 
 void Airplane::runCruise()
 {
-    setupState(_cruiseAoA, _cruiseSpeed, &_cruiseState);
+    setupState(_cruiseAoA, _cruiseSpeed,_approachGlideAngle, &_cruiseState);
     _model.setState(&_cruiseState);
     _model.setAir(_cruiseP, _cruiseT,
                   Atmosphere::calcStdDensity(_cruiseP, _cruiseT));
@@ -822,7 +838,7 @@ void Airplane::runCruise()
 
 void Airplane::runApproach()
 {
-    setupState(_approachAoA, _approachSpeed, &_approachState);
+    setupState(_approachAoA, _approachSpeed,_approachGlideAngle, &_approachState);
     _model.setState(&_approachState);
     _model.setAir(_approachP, _approachT,
                   Atmosphere::calcStdDensity(_approachP, _approachT));
@@ -930,7 +946,7 @@ void Airplane::solve()
        runCruise();
 
        _model.getThrust(tmp);
-       float thrust = tmp[0];
+        float thrust = tmp[0] + _cruiseWeight * Math::sin(_cruiseGlideAngle) * 9.81;
 
        _model.getBody()->getAccel(tmp);
         Math::tmul33(_cruiseState.orient, tmp, tmp);
@@ -1054,13 +1070,29 @@ void Airplane::solveHelicopter()
 {
     _solutionIterations = 0;
     _failureMsg = 0;
-
-    applyDragFactor(Math::pow(15.7/1000, 1/SOLVE_TWEAK));
-    applyLiftRatio(Math::pow(104, 1/SOLVE_TWEAK));
-    setupState(0,0, &_cruiseState);
+    if (getRotorgear()!=0)
+    {
+        Rotorgear* rg = getRotorgear();
+        applyDragFactor(Math::pow(rg->getYasimDragFactor()/1000,
+            1/SOLVE_TWEAK));
+        applyLiftRatio(Math::pow(rg->getYasimLiftFactor(),
+            1/SOLVE_TWEAK));
+    }
+    else
+    //huh, no wing and no rotor? (_rotorgear is constructed, 
+    //if a rotor is defined
+    {
+        applyDragFactor(Math::pow(15.7/1000, 1/SOLVE_TWEAK));
+        applyLiftRatio(Math::pow(104, 1/SOLVE_TWEAK));
+    }
+    setupState(0,0,0, &_cruiseState);
     _model.setState(&_cruiseState);
+    setupWeights(true);
     _controls.reset();
     _model.getBody()->reset();
+    _model.setAir(_cruiseP, _cruiseT,
+                  Atmosphere::calcStdDensity(_cruiseP, _cruiseT));
+    
 }
 
 }; // namespace yasim