X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FFDM%2FYASim%2FAirplane.cpp;h=166a861b54b1b352792da5b002dcfb2ef86d14f2;hb=c62048d5e26a2931f2a0f5fa7e94b3f7203e4762;hp=10bb49055b3d13ec8a27ff259caf485886d4e456;hpb=5333f82eb1c98a9dac366a36e78f47f903f2681d;p=flightgear.git diff --git a/src/FDM/YASim/Airplane.cpp b/src/FDM/YASim/Airplane.cpp index 10bb49055..166a861b5 100644 --- a/src/FDM/YASim/Airplane.cpp +++ b/src/FDM/YASim/Airplane.cpp @@ -66,6 +66,8 @@ Airplane::~Airplane() delete (Surface*)_surfs.get(i); for(i=0; i<_contacts.size(); i++) delete[] (float*)_contacts.get(i); + for(i=0; i<_solveWeights.size(); i++) + delete[] (SolveWeight*)_solveWeights.get(i); } void Airplane::iterate(float dt) @@ -73,35 +75,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); } @@ -170,27 +149,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 +191,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 +210,11 @@ float Airplane::getFuel(int tank) return ((Tank*)_tanks.get(tank))->fill; } +float Airplane::setFuel(int tank, float fuel) +{ + ((Tank*)_tanks.get(tank))->fill = fuel; +} + float Airplane::getFuelDensity(int tank) { return ((Tank*)_tanks.get(tank))->density; @@ -449,38 +438,19 @@ float Airplane::compileWing(Wing* w) return wgt; } -float Airplane::compileRotor(Rotor* w) +float Airplane::compileRotor(Rotor* r) { - /* 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); + // Todo: add rotor to model!!! + // Todo: calc and add mass!!! + r->compile(); + _model.addRotor(r); float wgt = 0; int i; - /* Todo: add rotor to model!!! - Todo: calc and add mass!!! - */ - for(i=0; inumRotorparts(); i++) { - Rotorpart* s = (Rotorpart*)w->getRotorpart(i); - - //float td = s->getTotalDrag(); - //s->setTotalDrag(td); + for(i=0; inumRotorparts(); i++) { + Rotorpart* s = (Rotorpart*)r->getRotorpart(i); _model.addRotorpart(s); - float mass = s->getWeight(); mass = mass * Math::sqrt(mass); @@ -488,27 +458,20 @@ float Airplane::compileRotor(Rotor* w) s->getPosition(pos); _model.getBody()->addMass(mass, pos); wgt += mass; - } - for(i=0; inumRotorblades(); i++) { - Rotorblade* s = (Rotorblade*)w->getRotorblade(i); - - //float td = s->getTotalDrag(); - //s->setTotalDrag(td); - - _model.addRotorblade(s); + for(i=0; inumRotorblades(); i++) { + Rotorblade* b = (Rotorblade*)r->getRotorblade(i); + _model.addRotorblade(b); - float mass = s->getWeight(); + float mass = b->getWeight(); mass = mass * Math::sqrt(mass); float pos[3]; - s->getPosition(pos); + b->getPosition(pos); _model.getBody()->addMass(mass, pos); wgt += mass; - } - return wgt; } @@ -650,17 +613,14 @@ 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++) { + for(i=0; i<_rotors.size(); i++) aeroWgt += compileRotor((Rotor*)_rotors.get(i)); - } // 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; @@ -702,16 +662,14 @@ void Airplane::compile() // Ground effect float gepos[3]; - float gespan; + float gespan = 0; if(_wing) gespan = _wing->getGroundEffect(gepos); - else - gespan=0; _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 +748,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 +781,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 +799,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 +824,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 +843,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 +902,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 +1031,19 @@ void Airplane::solve() _failureMsg = "Tail incidence > 10 degrees"; return; } - } - else - { - 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(); - +} - } +void Airplane::solveHelicopter() +{ + _solutionIterations = 0; + _failureMsg = 0; - return; + 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(); } + }; // namespace yasim