#include "Surface.hpp"
#include "Rotorpart.hpp"
#include "Thruster.hpp"
+#include "Hitch.hpp"
#include "Airplane.hpp"
namespace yasim {
_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()
}
}
-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);
_cruiseAoA = 0;
_tailIncidence = 0;
_cruiseFuel = fuel;
+ _cruiseGlideAngle = gla;
}
void Airplane::setElevatorControl(int control)
}
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;
f->width = width;
f->taper = taper;
f->mid = mid;
+ f->_cx=cx;
+ f->_cy=cy;
+ f->_cz=cz;
+ f->_idrag=idrag;
_fuselages.add(f);
}
_model.addHook(hook);
}
+void Airplane::addHitch(Hitch* hitch)
+{
+ _model.addHitch(hitch);
+}
+
void Airplane::addLaunchbar(Launchbar* launchbar)
{
_model.addLaunchbar(launchbar);
return _tailIncidence;
}
-char* Airplane::getFailureMsg()
+const char* Airplane::getFailureMsg()
{
return _failureMsg;
}
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);
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++)
return wgt;
}
-float Airplane::compileRotorgear()
+void Airplane::compileRotorgear()
{
- return getRotorgear()->compile(_model.getBody());
+ getRotorgear()->compile();
}
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;
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];
// I made these up
g->setStaticFriction(0.6f);
g->setDynamicFriction(0.5f);
+ g->setContactPoint(1);
_model.addGear(g);
}
for(i=0; i<_vstabs.size(); i++)
aeroWgt += compileWing((Wing*)_vstabs.get(i));
- // The rotor(s)
- aeroWgt += compileRotorgear();
// The fuselage(s)
for(i=0; i<_fuselages.size(); i++)
t->handle = body->addMass(0, t->pos);
totalFuel += t->cap;
}
- _cruiseWeight = _emptyWeight + totalFuel*0.5f;
- _approachWeight = _emptyWeight + totalFuel*0.2f;
+ _cruiseWeight = _emptyWeight + totalFuel*_cruiseFuel;
+ _approachWeight = _emptyWeight + totalFuel*_approachFuel;
body->recalc();
_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.
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
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);
// 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);
}
}
void Airplane::runCruise()
{
- setupState(_cruiseAoA, _cruiseSpeed, &_cruiseState);
+ setupState(_cruiseAoA, _cruiseSpeed,_cruiseGlideAngle, &_cruiseState);
_model.setState(&_cruiseState);
_model.setAir(_cruiseP, _cruiseT,
Atmosphere::calcStdDensity(_cruiseP, _cruiseT));
void Airplane::runApproach()
{
- setupState(_approachAoA, _approachSpeed, &_approachState);
+ setupState(_approachAoA, _approachSpeed,_approachGlideAngle, &_approachState);
_model.setState(&_approachState);
_model.setAir(_approachP, _approachT,
Atmosphere::calcStdDensity(_approachP, _approachT));
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);
applyDragFactor(Math::pow(15.7/1000, 1/SOLVE_TWEAK));
applyLiftRatio(Math::pow(104, 1/SOLVE_TWEAK));
}
- setupState(0,0, &_cruiseState);
+ setupState(0,0,0, &_cruiseState);
_model.setState(&_cruiseState);
setupWeights(true);
_controls.reset();