]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/YASim/Airplane.cpp
simplify name/number handling
[flightgear.git] / src / FDM / YASim / Airplane.cpp
index 10bb49055b3d13ec8a27ff259caf485886d4e456..30bdf59f34490893e4e9a8d90d4c2bf0f154627f 100644 (file)
@@ -6,7 +6,6 @@
 #include "RigidBody.hpp"
 #include "Surface.hpp"
 #include "Rotorpart.hpp"
-#include "Rotorblade.hpp"
 #include "Thruster.hpp"
 #include "Airplane.hpp"
 
@@ -60,12 +59,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);
+    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)
@@ -73,35 +93,12 @@ void Airplane::iterate(float dt)
     // The gear might have moved.  Change their aerodynamics.
     updateGearState();
 
-    _model.iterate(dt);
+    _model.iterate();
 }
 
-void Airplane::consumeFuel(float dt)
+void Airplane::calcFuelWeights()
 {
-    // This is a really simple implementation that assumes all engines
-    // draw equally from all tanks in proportion to the amount of fuel
-    // stored there.  Needs to be fixed, but that has to wait for a
-    // decision as to what the property interface will look like.
-    int i, outOfFuel = 0;
-    float fuelFlow = 0, totalFuel = 0.00001; // <-- overflow protection
-    for(i=0; i<_thrusters.size(); i++)
-        fuelFlow += ((ThrustRec*)_thrusters.get(i))->thruster->getFuelFlow();
-    for(i=0; i<_tanks.size(); i++)
-        totalFuel += ((Tank*)_tanks.get(i))->fill;
-    for(i=0; i<_tanks.size(); i++) {
-        Tank* t = (Tank*)_tanks.get(i);
-        t->fill -= dt * fuelFlow * (t->fill/totalFuel);
-        if(t->fill <= 0) {
-            t->fill = 0;
-            outOfFuel = 1;
-        }
-    }
-    if(outOfFuel)
-        for(int i=0; i<_thrusters.size(); i++)
-            ((ThrustRec*)_thrusters.get(i))->thruster->setFuelState(false);
-
-    // Set the tank masses on the RigidBody
-    for(i=0; i<_tanks.size(); i++) {
+    for(int i=0; i<_tanks.size(); i++) {
         Tank* t = (Tank*)_tanks.get(i);
         _model.getBody()->setMass(t->handle, t->fill);
     }
@@ -158,6 +155,21 @@ Gear* Airplane::getGear(int g)
     return ((GearRec*)_gears.get(g))->gear;
 }
 
+Hook* Airplane::getHook()
+{
+    return _model.getHook();
+}
+
+Launchbar* Airplane::getLaunchbar()
+{
+    return _model.getLaunchbar();
+}
+
+Rotorgear* Airplane::getRotorgear()
+{
+    return _model.getRotorgear();
+}
+
 void Airplane::updateGearState()
 {
     for(int i=0; i<_gears.size(); i++) {
@@ -170,27 +182,23 @@ void Airplane::updateGearState()
     }
 }
 
-void Airplane::setApproach(float speed, float altitude)
-{
-    // The zero AoA will become a calculated stall AoA in compile()
-    setApproach(speed, altitude, 0);
-}
-
-void Airplane::setApproach(float speed, float altitude, float aoa)
+void Airplane::setApproach(float speed, float altitude, float aoa, float fuel)
 {
     _approachSpeed = speed;
     _approachP = Atmosphere::getStdPressure(altitude);
     _approachT = Atmosphere::getStdTemperature(altitude);
     _approachAoA = aoa;
+    _approachFuel = fuel;
 }
  
-void Airplane::setCruise(float speed, float altitude)
+void Airplane::setCruise(float speed, float altitude, float fuel)
 {
     _cruiseSpeed = speed;
     _cruiseP = Atmosphere::getStdPressure(altitude);
     _cruiseT = Atmosphere::getStdTemperature(altitude);
     _cruiseAoA = 0;
     _tailIncidence = 0;
+    _cruiseFuel = fuel;
 }
 
 void Airplane::setElevatorControl(int control)
@@ -216,6 +224,15 @@ void Airplane::addCruiseControl(int control, float val)
     _cruiseControls.add(c);
 }
 
+void Airplane::addSolutionWeight(bool approach, int idx, float wgt)
+{
+    SolveWeight* w = new SolveWeight();
+    w->approach = approach;
+    w->idx = idx;
+    w->wgt = wgt;
+    _solveWeights.add(w);
+}
+
 int Airplane::numTanks()
 {
     return _tanks.size();
@@ -226,6 +243,11 @@ float Airplane::getFuel(int tank)
     return ((Tank*)_tanks.get(tank))->fill;
 }
 
+float Airplane::setFuel(int tank, float fuel)
+{
+    return ((Tank*)_tanks.get(tank))->fill = fuel;
+}
+
 float Airplane::getFuelDensity(int tank)
 {
     return ((Tank*)_tanks.get(tank))->density;
@@ -256,11 +278,6 @@ 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)
 {
@@ -296,6 +313,16 @@ void Airplane::addGear(Gear* gear)
     _gears.add(g);
 }
 
+void Airplane::addHook(Hook* hook)
+{
+    _model.addHook(hook);
+}
+
+void Airplane::addLaunchbar(Launchbar* launchbar)
+{
+    _model.addLaunchbar(launchbar);
+}
+
 void Airplane::addThruster(Thruster* thruster, float mass, float* cg)
 {
     ThrustRec* t = new ThrustRec();
@@ -406,11 +433,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)
@@ -449,67 +477,9 @@ float Airplane::compileWing(Wing* w)
     return wgt;
 }
 
-float Airplane::compileRotor(Rotor* w)
+float Airplane::compileRotorgear()
 {
-    /* todo contact points
-    // The tip of the wing is a contact point
-    float tip[3];
-    w->getTip(tip);
-    addContactPoint(tip);
-    if(w->isMirrored()) {
-        tip[1] *= -1;
-        addContactPoint(tip);
-    }
-    */
-
-    // Make sure it's initialized.  The surfaces will pop out with
-    // total drag coefficients equal to their areas, which is what we
-    // want.
-    w->compile();
-    _model.addRotor(w);
-
-    float wgt = 0;
-    int i;
-    /* Todo: add rotor to model!!!
-       Todo: calc and add mass!!!
-    */
-    for(i=0; i<w->numRotorparts(); i++) {
-        Rotorpart* s = (Rotorpart*)w->getRotorpart(i);
-
-        //float td = s->getTotalDrag();
-        //s->setTotalDrag(td);
-
-        _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<w->numRotorblades(); i++) {
-        Rotorblade* s = (Rotorblade*)w->getRotorblade(i);
-
-        //float td = s->getTotalDrag();
-        //s->setTotalDrag(td);
-
-        _model.addRotorblade(s);
-
-        
-        float mass = s->getWeight();
-        mass = mass * Math::sqrt(mass);
-        float pos[3];
-        s->getPosition(pos);
-        _model.getBody()->addMass(mass, pos);
-        wgt += mass;
-        
-    }
-    
-    return wgt;
+    return getRotorgear()->compile(_model.getBody());
 }
 
 float Airplane::compileFuselage(Fuselage* f)
@@ -612,10 +582,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);
@@ -632,10 +603,6 @@ void Airplane::compileContactPoints()
 
 void Airplane::compile()
 {
-    double ground[3];
-    ground[0] = 0; ground[1] = 0; ground[2] = 1;
-    _model.setGroundPlane(ground, -100000);
-
     RigidBody* body = _model.getBody();
     int firstMass = body->numMasses();
 
@@ -650,17 +617,15 @@ void Airplane::compile()
     if (_tail)
       aeroWgt += compileWing(_tail);
     int i;
-    for(i=0; i<_vstabs.size(); 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 rotor(s)
+    aeroWgt += compileRotorgear(); 
+
     // The fuselage(s)
-    for(i=0; i<_fuselages.size(); i++) {
+    for(i=0; i<_fuselages.size(); i++)
         aeroWgt += compileFuselage((Fuselage*)_fuselages.get(i));
-    }
 
     // Count up the absolute weight we have
     float nonAeroWgt = _ballast;
@@ -701,17 +666,16 @@ void Airplane::compile()
     }
 
     // Ground effect
-    float gepos[3];
-    float gespan;
-    if(_wing)
-      gespan = _wing->getGroundEffect(gepos);
-    else
-      gespan=0;
-    _model.setGroundEffect(gepos, gespan, 0.15f);
+    if(_wing) {
+        float gepos[3];
+        float gespan = 0;
+        gespan = _wing->getGroundEffect(gepos);
+        _model.setGroundEffect(gepos, gespan, 0.15f);
+    }
 
     solveGear();
-    
-    solve();
+    if(_wing && _tail) solve();
+    else solveHelicopter();
 
     // Do this after solveGear, because it creates "gear" objects that
     // we don't want to affect.
@@ -790,6 +754,18 @@ void Airplane::stabilizeThrust()
        _model.getThruster(i)->stabilize();
 }
 
+void Airplane::setupWeights(bool isApproach)
+{
+    int i;
+    for(i=0; i<_weights.size(); i++)
+        setWeight(i, 0);
+    for(i=0; i<_solveWeights.size(); i++) {
+        SolveWeight* w = (SolveWeight*)_solveWeights.get(i);
+        if(w->approach == isApproach)
+            setWeight(w->idx, w->wgt);
+    }
+}
+
 void Airplane::runCruise()
 {
     setupState(_cruiseAoA, _cruiseSpeed, &_cruiseState);
@@ -811,8 +787,8 @@ void Airplane::runCruise()
     Math::mul3(-1, _cruiseState.v, wind);
     Math::vmul33(_cruiseState.orient, wind, wind);
  
-    // Cruise is by convention at 50% tank capacity
-    setFuelFraction(0.5);
+    setFuelFraction(_cruiseFuel);
+    setupWeights(false);
    
     // Set up the thruster parameters and iterate until the thrust
     // stabilizes.
@@ -829,7 +805,7 @@ void Airplane::runCruise()
     // Precompute thrust in the model, and calculate aerodynamic forces
     _model.getBody()->recalc();
     _model.getBody()->reset();
-    _model.initIteration(.01);//hier parameter egal
+    _model.initIteration();
     _model.calcForces(&_cruiseState);
 }
 
@@ -854,8 +830,9 @@ void Airplane::runApproach()
     Math::mul3(-1, _approachState.v, wind);
     Math::vmul33(_approachState.orient, wind, wind);
     
-    // Approach is by convention at 20% tank capacity
-    setFuelFraction(0.2f);
+    setFuelFraction(_approachFuel);
+
+    setupWeights(true);
 
     // Run the thrusters until they get to a stable setting.  FIXME:
     // this is lots of wasted work.
@@ -872,7 +849,7 @@ void Airplane::runApproach()
     // Precompute thrust in the model, and calculate aerodynamic forces
     _model.getBody()->recalc();
     _model.getBody()->reset();
-    _model.initIteration(.01);//hier parameter egal
+    _model.initIteration();
     _model.calcForces(&_approachState);
 }
 
@@ -931,19 +908,8 @@ void Airplane::solve()
     float tmp[3];
     _solutionIterations = 0;
     _failureMsg = 0;
-    if((_wing)&&(_tail))
-    {
-    while(1) {
-#if 0
-        printf("%d %f %f %f %f %f\n", //DEBUG
-               _solutionIterations,
-               1000*_dragFactor,
-               _liftRatio,
-               _cruiseAoA,
-               _tailIncidence,
-               _approachElevator.val);
-#endif
 
+    while(1) {
         if(_solutionIterations++ > 10000) { 
             _failureMsg = "Solution failed to converge after 10000 iterations";
             return;
@@ -1071,19 +1037,35 @@ void Airplane::solve()
        _failureMsg = "Tail incidence > 10 degrees";
        return;
     }
+}
+
+void Airplane::solveHelicopter()
+{
+    _solutionIterations = 0;
+    _failureMsg = 0;
+    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, &_cruiseState);
-        _model.setState(&_cruiseState);
-        _controls.reset();
-        _model.getBody()->reset();
-
-
     }
-
-    return;
+    setupState(0,0, &_cruiseState);
+    _model.setState(&_cruiseState);
+    setupWeights(true);
+    _controls.reset();
+    _model.getBody()->reset();
+    _model.setAir(_cruiseP, _cruiseT,
+                  Atmosphere::calcStdDensity(_cruiseP, _cruiseT));
+    
 }
+
 }; // namespace yasim