Updated to YASim-0.1.2
This commit is contained in:
parent
01d13f797a
commit
48260480b3
24 changed files with 330 additions and 181 deletions
|
@ -35,15 +35,16 @@ Airplane::Airplane()
|
||||||
|
|
||||||
Airplane::~Airplane()
|
Airplane::~Airplane()
|
||||||
{
|
{
|
||||||
for(int i=0; i<_fuselages.size(); i++)
|
int i;
|
||||||
|
for(i=0; i<_fuselages.size(); i++)
|
||||||
delete (Fuselage*)_fuselages.get(i);
|
delete (Fuselage*)_fuselages.get(i);
|
||||||
for(int i=0; i<_tanks.size(); i++)
|
for(i=0; i<_tanks.size(); i++)
|
||||||
delete (Tank*)_tanks.get(i);
|
delete (Tank*)_tanks.get(i);
|
||||||
for(int i=0; i<_thrusters.size(); i++)
|
for(i=0; i<_thrusters.size(); i++)
|
||||||
delete (ThrustRec*)_thrusters.get(i);
|
delete (ThrustRec*)_thrusters.get(i);
|
||||||
for(int i=0; i<_gears.size(); i++)
|
for(i=0; i<_gears.size(); i++)
|
||||||
delete (GearRec*)_gears.get(i);
|
delete (GearRec*)_gears.get(i);
|
||||||
for(int i=0; i<_surfs.size(); i++)
|
for(i=0; i<_surfs.size(); i++)
|
||||||
delete (Surface*)_surfs.get(i);
|
delete (Surface*)_surfs.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,12 +86,14 @@ void Airplane::getPilotAccel(float* out)
|
||||||
|
|
||||||
void Airplane::setPilotPos(float* pos)
|
void Airplane::setPilotPos(float* pos)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) _pilotPos[i] = pos[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) _pilotPos[i] = pos[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Airplane::getPilotPos(float* out)
|
void Airplane::getPilotPos(float* out)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) out[i] = _pilotPos[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) out[i] = _pilotPos[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
int Airplane::numGear()
|
int Airplane::numGear()
|
||||||
|
@ -105,7 +108,8 @@ Gear* Airplane::getGear(int g)
|
||||||
|
|
||||||
void Airplane::setGearState(bool down, float dt)
|
void Airplane::setGearState(bool down, float dt)
|
||||||
{
|
{
|
||||||
for(int i=0; i<_gears.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_gears.size(); i++) {
|
||||||
GearRec* gr = (GearRec*)_gears.get(i);
|
GearRec* gr = (GearRec*)_gears.get(i);
|
||||||
if(gr->time == 0) {
|
if(gr->time == 0) {
|
||||||
// Non-extensible
|
// Non-extensible
|
||||||
|
@ -206,7 +210,8 @@ void Airplane::addVStab(Wing* vstab)
|
||||||
void Airplane::addFuselage(float* front, float* back, float width)
|
void Airplane::addFuselage(float* front, float* back, float width)
|
||||||
{
|
{
|
||||||
Fuselage* f = new Fuselage();
|
Fuselage* f = new Fuselage();
|
||||||
for(int i=0; i<3; i++) {
|
int i;
|
||||||
|
for(i=0; i<3; i++) {
|
||||||
f->front[i] = front[i];
|
f->front[i] = front[i];
|
||||||
f->back[i] = back[i];
|
f->back[i] = back[i];
|
||||||
}
|
}
|
||||||
|
@ -217,7 +222,8 @@ void Airplane::addFuselage(float* front, float* back, float width)
|
||||||
int Airplane::addTank(float* pos, float cap, float density)
|
int Airplane::addTank(float* pos, float cap, float density)
|
||||||
{
|
{
|
||||||
Tank* t = new Tank();
|
Tank* t = new Tank();
|
||||||
for(int i=0; i<3; i++) t->pos[i] = pos[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) t->pos[i] = pos[i];
|
||||||
t->cap = cap;
|
t->cap = cap;
|
||||||
t->fill = cap;
|
t->fill = cap;
|
||||||
t->density = density;
|
t->density = density;
|
||||||
|
@ -239,7 +245,8 @@ void Airplane::addThruster(Thruster* thruster, float mass, float* cg)
|
||||||
ThrustRec* t = new ThrustRec();
|
ThrustRec* t = new ThrustRec();
|
||||||
t->thruster = thruster;
|
t->thruster = thruster;
|
||||||
t->mass = mass;
|
t->mass = mass;
|
||||||
for(int i=0; i<3; i++) t->cg[i] = cg[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) t->cg[i] = cg[i];
|
||||||
_thrusters.add(t);
|
_thrusters.add(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +291,8 @@ void Airplane::setWeight(int handle, float mass)
|
||||||
|
|
||||||
void Airplane::setFuelFraction(float frac)
|
void Airplane::setFuelFraction(float frac)
|
||||||
{
|
{
|
||||||
for(int i=0; i<_tanks.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_tanks.size(); i++) {
|
||||||
Tank* t = (Tank*)_tanks.get(i);
|
Tank* t = (Tank*)_tanks.get(i);
|
||||||
_model.getBody()->setMass(t->handle, t->cap * frac);
|
_model.getBody()->setMass(t->handle, t->cap * frac);
|
||||||
}
|
}
|
||||||
|
@ -330,7 +338,8 @@ void Airplane::setupState(float aoa, float speed, State* s)
|
||||||
|
|
||||||
s->v[0] = speed; s->v[1] = 0; s->v[2] = 0;
|
s->v[0] = speed; s->v[1] = 0; s->v[2] = 0;
|
||||||
|
|
||||||
for(int i=0; i<3; i++)
|
int i;
|
||||||
|
for(i=0; i<3; i++)
|
||||||
s->pos[i] = s->rot[i] = s->acc[i] = s->racc[i] = 0;
|
s->pos[i] = s->rot[i] = s->acc[i] = s->racc[i] = 0;
|
||||||
|
|
||||||
// Put us 1m above the origin, or else the gravity computation in
|
// Put us 1m above the origin, or else the gravity computation in
|
||||||
|
@ -346,7 +355,8 @@ float Airplane::compileWing(Wing* w)
|
||||||
w->compile();
|
w->compile();
|
||||||
|
|
||||||
float wgt = 0;
|
float wgt = 0;
|
||||||
for(int i=0; i<w->numSurfaces(); i++) {
|
int i;
|
||||||
|
for(i=0; i<w->numSurfaces(); i++) {
|
||||||
Surface* s = (Surface*)w->getSurface(i);
|
Surface* s = (Surface*)w->getSurface(i);
|
||||||
_model.addSurface(s);
|
_model.addSurface(s);
|
||||||
|
|
||||||
|
@ -367,7 +377,8 @@ float Airplane::compileFuselage(Fuselage* f)
|
||||||
float wid = f->width;
|
float wid = f->width;
|
||||||
int segs = (int)Math::ceil(len/wid);
|
int segs = (int)Math::ceil(len/wid);
|
||||||
float segWgt = len*wid/segs;
|
float segWgt = len*wid/segs;
|
||||||
for(int j=0; j<segs; j++) {
|
int j;
|
||||||
|
for(j=0; j<segs; j++) {
|
||||||
float frac = (j+0.5) / segs;
|
float frac = (j+0.5) / segs;
|
||||||
float pos[3];
|
float pos[3];
|
||||||
Math::mul3(frac, fwd, pos);
|
Math::mul3(frac, fwd, pos);
|
||||||
|
@ -442,34 +453,35 @@ void Airplane::compile()
|
||||||
// The Wing objects
|
// The Wing objects
|
||||||
aeroWgt += compileWing(_wing);
|
aeroWgt += compileWing(_wing);
|
||||||
aeroWgt += compileWing(_tail);
|
aeroWgt += compileWing(_tail);
|
||||||
for(int i=0; i<_vstabs.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_vstabs.size(); i++) {
|
||||||
aeroWgt += compileWing((Wing*)_vstabs.get(i));
|
aeroWgt += compileWing((Wing*)_vstabs.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The fuselage(s)
|
// The fuselage(s)
|
||||||
for(int i=0; i<_fuselages.size(); i++) {
|
for(i=0; i<_fuselages.size(); i++) {
|
||||||
aeroWgt += compileFuselage((Fuselage*)_fuselages.get(i));
|
aeroWgt += compileFuselage((Fuselage*)_fuselages.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count up the absolute weight we have
|
// Count up the absolute weight we have
|
||||||
float nonAeroWgt = _ballast;
|
float nonAeroWgt = _ballast;
|
||||||
for(int i=0; i<_thrusters.size(); i++)
|
for(i=0; i<_thrusters.size(); i++)
|
||||||
nonAeroWgt += ((ThrustRec*)_thrusters.get(i))->mass;
|
nonAeroWgt += ((ThrustRec*)_thrusters.get(i))->mass;
|
||||||
|
|
||||||
// Rescale to the specified empty weight
|
// Rescale to the specified empty weight
|
||||||
float wscale = (_emptyWeight-nonAeroWgt)/aeroWgt;
|
float wscale = (_emptyWeight-nonAeroWgt)/aeroWgt;
|
||||||
for(int i=firstMass; i<body->numMasses(); i++)
|
for(i=firstMass; i<body->numMasses(); i++)
|
||||||
body->setMass(i, body->getMass(i)*wscale);
|
body->setMass(i, body->getMass(i)*wscale);
|
||||||
|
|
||||||
// Add the thruster masses
|
// Add the thruster masses
|
||||||
for(int i=0; i<_thrusters.size(); i++) {
|
for(i=0; i<_thrusters.size(); i++) {
|
||||||
ThrustRec* t = (ThrustRec*)_thrusters.get(i);
|
ThrustRec* t = (ThrustRec*)_thrusters.get(i);
|
||||||
body->addMass(t->mass, t->cg);
|
body->addMass(t->mass, t->cg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the tanks, empty for now.
|
// Add the tanks, empty for now.
|
||||||
float totalFuel = 0;
|
float totalFuel = 0;
|
||||||
for(int i=0; i<_tanks.size(); i++) {
|
for(i=0; i<_tanks.size(); i++) {
|
||||||
Tank* t = (Tank*)_tanks.get(i);
|
Tank* t = (Tank*)_tanks.get(i);
|
||||||
t->handle = body->addMass(0, t->pos);
|
t->handle = body->addMass(0, t->pos);
|
||||||
totalFuel += t->cap;
|
totalFuel += t->cap;
|
||||||
|
@ -480,11 +492,11 @@ void Airplane::compile()
|
||||||
body->recalc();
|
body->recalc();
|
||||||
|
|
||||||
// Add surfaces for the landing gear.
|
// Add surfaces for the landing gear.
|
||||||
for(int i=0; i<_gears.size(); i++)
|
for(i=0; i<_gears.size(); i++)
|
||||||
compileGear((GearRec*)_gears.get(i));
|
compileGear((GearRec*)_gears.get(i));
|
||||||
|
|
||||||
// The Thruster objects
|
// The Thruster objects
|
||||||
for(int i=0; i<_thrusters.size(); i++) {
|
for(i=0; i<_thrusters.size(); i++) {
|
||||||
ThrustRec* tr = (ThrustRec*)_thrusters.get(i);
|
ThrustRec* tr = (ThrustRec*)_thrusters.get(i);
|
||||||
tr->handle = _model.addThruster(tr->thruster);
|
tr->handle = _model.addThruster(tr->thruster);
|
||||||
}
|
}
|
||||||
|
@ -512,7 +524,8 @@ void Airplane::solveGear()
|
||||||
// "buffer" to keep things from blowing up with aircraft with a
|
// "buffer" to keep things from blowing up with aircraft with a
|
||||||
// single gear very near the c.g. (AV-8, for example).
|
// single gear very near the c.g. (AV-8, for example).
|
||||||
float total = 0;
|
float total = 0;
|
||||||
for(int i=0; i<_gears.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_gears.size(); i++) {
|
||||||
GearRec* gr = (GearRec*)_gears.get(i);
|
GearRec* gr = (GearRec*)_gears.get(i);
|
||||||
Gear* g = gr->gear;
|
Gear* g = gr->gear;
|
||||||
g->getPosition(pos);
|
g->getPosition(pos);
|
||||||
|
@ -522,7 +535,7 @@ void Airplane::solveGear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renormalize so they sum to 1
|
// Renormalize so they sum to 1
|
||||||
for(int i=0; i<_gears.size(); i++)
|
for(i=0; i<_gears.size(); i++)
|
||||||
((GearRec*)_gears.get(i))->wgt /= total;
|
((GearRec*)_gears.get(i))->wgt /= total;
|
||||||
|
|
||||||
// The force at max compression should be sufficient to stop a
|
// The force at max compression should be sufficient to stop a
|
||||||
|
@ -535,7 +548,7 @@ void Airplane::solveGear()
|
||||||
// each gear.
|
// each gear.
|
||||||
float energy = 0.5*_approachWeight*descentRate*descentRate;
|
float energy = 0.5*_approachWeight*descentRate*descentRate;
|
||||||
|
|
||||||
for(int i=0; i<_gears.size(); i++) {
|
for(i=0; i<_gears.size(); i++) {
|
||||||
GearRec* gr = (GearRec*)_gears.get(i);
|
GearRec* gr = (GearRec*)_gears.get(i);
|
||||||
float e = energy * gr->wgt;
|
float e = energy * gr->wgt;
|
||||||
float comp[3];
|
float comp[3];
|
||||||
|
@ -558,7 +571,8 @@ void Airplane::solveGear()
|
||||||
|
|
||||||
void Airplane::stabilizeThrust()
|
void Airplane::stabilizeThrust()
|
||||||
{
|
{
|
||||||
for(int i=0; i<_thrusters.size(); i++)
|
int i;
|
||||||
|
for(i=0; i<_thrusters.size(); i++)
|
||||||
_model.getThruster(i)->stabilize();
|
_model.getThruster(i)->stabilize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,7 +584,8 @@ void Airplane::runCruise()
|
||||||
|
|
||||||
// The control configuration
|
// The control configuration
|
||||||
_controls.reset();
|
_controls.reset();
|
||||||
for(int i=0; i<_cruiseControls.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_cruiseControls.size(); i++) {
|
||||||
Control* c = (Control*)_cruiseControls.get(i);
|
Control* c = (Control*)_cruiseControls.get(i);
|
||||||
_controls.setInput(c->control, c->val);
|
_controls.setInput(c->control, c->val);
|
||||||
}
|
}
|
||||||
|
@ -589,7 +604,7 @@ void Airplane::runCruise()
|
||||||
|
|
||||||
// Set up the thruster parameters and iterate until the thrust
|
// Set up the thruster parameters and iterate until the thrust
|
||||||
// stabilizes.
|
// stabilizes.
|
||||||
for(int i=0; i<_thrusters.size(); i++) {
|
for(i=0; i<_thrusters.size(); i++) {
|
||||||
Thruster* t = ((ThrustRec*)_thrusters.get(i))->thruster;
|
Thruster* t = ((ThrustRec*)_thrusters.get(i))->thruster;
|
||||||
t->setWind(wind);
|
t->setWind(wind);
|
||||||
t->setAir(_cruiseP, _cruiseT);
|
t->setAir(_cruiseP, _cruiseT);
|
||||||
|
@ -610,7 +625,8 @@ void Airplane::runApproach()
|
||||||
|
|
||||||
// The control configuration
|
// The control configuration
|
||||||
_controls.reset();
|
_controls.reset();
|
||||||
for(int i=0; i<_approachControls.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_approachControls.size(); i++) {
|
||||||
Control* c = (Control*)_approachControls.get(i);
|
Control* c = (Control*)_approachControls.get(i);
|
||||||
_controls.setInput(c->control, c->val);
|
_controls.setInput(c->control, c->val);
|
||||||
}
|
}
|
||||||
|
@ -629,7 +645,7 @@ void Airplane::runApproach()
|
||||||
|
|
||||||
// Run the thrusters until they get to a stable setting. FIXME:
|
// Run the thrusters until they get to a stable setting. FIXME:
|
||||||
// this is lots of wasted work.
|
// this is lots of wasted work.
|
||||||
for(int i=0; i<_thrusters.size(); i++) {
|
for(i=0; i<_thrusters.size(); i++) {
|
||||||
Thruster* t = ((ThrustRec*)_thrusters.get(i))->thruster;
|
Thruster* t = ((ThrustRec*)_thrusters.get(i))->thruster;
|
||||||
t->setWind(wind);
|
t->setWind(wind);
|
||||||
t->setAir(_approachP, _approachT);
|
t->setAir(_approachP, _approachT);
|
||||||
|
@ -648,11 +664,12 @@ void Airplane::applyDragFactor(float factor)
|
||||||
_dragFactor *= applied;
|
_dragFactor *= applied;
|
||||||
_wing->setDragScale(_wing->getDragScale() * applied);
|
_wing->setDragScale(_wing->getDragScale() * applied);
|
||||||
_tail->setDragScale(_tail->getDragScale() * applied);
|
_tail->setDragScale(_tail->getDragScale() * applied);
|
||||||
for(int i=0; i<_vstabs.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_vstabs.size(); i++) {
|
||||||
Wing* w = (Wing*)_vstabs.get(i);
|
Wing* w = (Wing*)_vstabs.get(i);
|
||||||
w->setDragScale(w->getDragScale() * applied);
|
w->setDragScale(w->getDragScale() * applied);
|
||||||
}
|
}
|
||||||
for(int i=0; i<_surfs.size(); i++) {
|
for(i=0; i<_surfs.size(); i++) {
|
||||||
Surface* s = (Surface*)_surfs.get(i);
|
Surface* s = (Surface*)_surfs.get(i);
|
||||||
s->setTotalDrag(s->getTotalDrag() * applied);
|
s->setTotalDrag(s->getTotalDrag() * applied);
|
||||||
}
|
}
|
||||||
|
@ -664,7 +681,8 @@ void Airplane::applyLiftRatio(float factor)
|
||||||
_liftRatio *= applied;
|
_liftRatio *= applied;
|
||||||
_wing->setLiftRatio(_wing->getLiftRatio() * applied);
|
_wing->setLiftRatio(_wing->getLiftRatio() * applied);
|
||||||
_tail->setLiftRatio(_tail->getLiftRatio() * applied);
|
_tail->setLiftRatio(_tail->getLiftRatio() * applied);
|
||||||
for(int i=0; i<_vstabs.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_vstabs.size(); i++) {
|
||||||
Wing* w = (Wing*)_vstabs.get(i);
|
Wing* w = (Wing*)_vstabs.get(i);
|
||||||
w->setLiftRatio(w->getLiftRatio() * applied);
|
w->setLiftRatio(w->getLiftRatio() * applied);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,11 @@ struct State {
|
||||||
|
|
||||||
// Simple initialization
|
// Simple initialization
|
||||||
State() {
|
State() {
|
||||||
for(int i=0; i<3; i++) {
|
int i;
|
||||||
|
for(i=0; i<3; i++) {
|
||||||
pos[i] = v[i] = rot[i] = acc[i] = racc[i] = 0;
|
pos[i] = v[i] = rot[i] = acc[i] = racc[i] = 0;
|
||||||
for(int j=0; j<3; j++)
|
int j;
|
||||||
|
for(j=0; j<3; j++)
|
||||||
orient[3*i+j] = i==j ? 1 : 0;
|
orient[3*i+j] = i==j ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,14 +10,16 @@ namespace yasim {
|
||||||
|
|
||||||
ControlMap::~ControlMap()
|
ControlMap::~ControlMap()
|
||||||
{
|
{
|
||||||
for(int i=0; i<_inputs.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_inputs.size(); i++) {
|
||||||
Vector* v = (Vector*)_inputs.get(i);
|
Vector* v = (Vector*)_inputs.get(i);
|
||||||
for(int j=0; j<v->size(); j++)
|
int j;
|
||||||
|
for(j=0; j<v->size(); j++)
|
||||||
delete (MapRec*)v->get(j);
|
delete (MapRec*)v->get(j);
|
||||||
delete v;
|
delete v;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<_outputs.size(); i++) {
|
for(i=0; i<_outputs.size(); i++) {
|
||||||
OutRec* o = (OutRec*)_outputs.get(i);
|
OutRec* o = (OutRec*)_outputs.get(i);
|
||||||
delete[] o->values;
|
delete[] o->values;
|
||||||
delete o;
|
delete o;
|
||||||
|
@ -34,7 +36,8 @@ void ControlMap::addMapping(int input, int type, void* object, int options)
|
||||||
{
|
{
|
||||||
// See if the output object already exists
|
// See if the output object already exists
|
||||||
OutRec* out = 0;
|
OutRec* out = 0;
|
||||||
for(int i=0; i<_outputs.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_outputs.size(); i++) {
|
||||||
OutRec* o = (OutRec*)_outputs.get(i);
|
OutRec* o = (OutRec*)_outputs.get(i);
|
||||||
if(o->object == object && o->type == type) {
|
if(o->object == object && o->type == type) {
|
||||||
out = o;
|
out = o;
|
||||||
|
@ -73,9 +76,11 @@ void ControlMap::addMapping(int input, int type, void* object, int options)
|
||||||
void ControlMap::reset()
|
void ControlMap::reset()
|
||||||
{
|
{
|
||||||
// Set all the values to zero
|
// Set all the values to zero
|
||||||
for(int i=0; i<_outputs.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_outputs.size(); i++) {
|
||||||
OutRec* o = (OutRec*)_outputs.get(i);
|
OutRec* o = (OutRec*)_outputs.get(i);
|
||||||
for(int j=0; j<o->n; j++)
|
int j;
|
||||||
|
for(j=0; j<o->n; j++)
|
||||||
o->values[j] = 0;
|
o->values[j] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +88,8 @@ void ControlMap::reset()
|
||||||
void ControlMap::setInput(int input, float value)
|
void ControlMap::setInput(int input, float value)
|
||||||
{
|
{
|
||||||
Vector* maps = (Vector*)_inputs.get(input);
|
Vector* maps = (Vector*)_inputs.get(input);
|
||||||
for(int i=0; i<maps->size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<maps->size(); i++) {
|
||||||
MapRec* map = (MapRec*)maps->get(i);
|
MapRec* map = (MapRec*)maps->get(i);
|
||||||
map->out->values[map->idx] = value;
|
map->out->values[map->idx] = value;
|
||||||
}
|
}
|
||||||
|
@ -91,13 +97,15 @@ void ControlMap::setInput(int input, float value)
|
||||||
|
|
||||||
void ControlMap::applyControls()
|
void ControlMap::applyControls()
|
||||||
{
|
{
|
||||||
for(int outrec=0; outrec<_outputs.size(); outrec++) {
|
int outrec;
|
||||||
|
for(outrec=0; outrec<_outputs.size(); outrec++) {
|
||||||
OutRec* o = (OutRec*)_outputs.get(outrec);
|
OutRec* o = (OutRec*)_outputs.get(outrec);
|
||||||
|
|
||||||
// Generate a summed value. Note the check for "split"
|
// Generate a summed value. Note the check for "split"
|
||||||
// control axes like ailerons.
|
// control axes like ailerons.
|
||||||
float lval = 0, rval = 0;
|
float lval = 0, rval = 0;
|
||||||
for(int i=0; i<o->n; i++) {
|
int i;
|
||||||
|
for(i=0; i<o->n; i++) {
|
||||||
float val = o->values[i];
|
float val = o->values[i];
|
||||||
int opt = (int)o->options.get(i);
|
int opt = (int)o->options.get(i);
|
||||||
if(opt & OPT_SQUARE)
|
if(opt & OPT_SQUARE)
|
||||||
|
|
|
@ -13,9 +13,9 @@ public:
|
||||||
BRAKE, STEER, EXTEND,
|
BRAKE, STEER, EXTEND,
|
||||||
INCIDENCE, FLAP0, FLAP1, SLAT, SPOILER };
|
INCIDENCE, FLAP0, FLAP1, SLAT, SPOILER };
|
||||||
|
|
||||||
static const int OPT_SPLIT = 0x01;
|
enum { OPT_SPLIT = 0x01,
|
||||||
static const int OPT_INVERT = 0x02;
|
OPT_INVERT = 0x02,
|
||||||
static const int OPT_SQUARE = 0x04;
|
OPT_SQUARE = 0x04 };
|
||||||
|
|
||||||
// Returns a new, not-yet-used "input handle" for addMapping and
|
// Returns a new, not-yet-used "input handle" for addMapping and
|
||||||
// setInput. This typically corresponds to one user axis.
|
// setInput. This typically corresponds to one user axis.
|
||||||
|
|
|
@ -37,24 +37,25 @@ FGFDM::FGFDM()
|
||||||
|
|
||||||
FGFDM::~FGFDM()
|
FGFDM::~FGFDM()
|
||||||
{
|
{
|
||||||
for(int i=0; i<_axes.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_axes.size(); i++) {
|
||||||
AxisRec* a = (AxisRec*)_axes.get(i);
|
AxisRec* a = (AxisRec*)_axes.get(i);
|
||||||
delete[] a->name;
|
delete[] a->name;
|
||||||
delete a;
|
delete a;
|
||||||
}
|
}
|
||||||
for(int i=0; i<_pistons.size(); i++) {
|
for(i=0; i<_pistons.size(); i++) {
|
||||||
EngRec* er = (EngRec*)_pistons.get(i);
|
EngRec* er = (EngRec*)_pistons.get(i);
|
||||||
delete[] er->prefix;
|
delete[] er->prefix;
|
||||||
delete (PropEngine*)er->eng;
|
delete (PropEngine*)er->eng;
|
||||||
delete er;
|
delete er;
|
||||||
}
|
}
|
||||||
for(int i=0; i<_jets.size(); i++) {
|
for(i=0; i<_jets.size(); i++) {
|
||||||
EngRec* er = (EngRec*)_pistons.get(i);
|
EngRec* er = (EngRec*)_pistons.get(i);
|
||||||
delete[] er->prefix;
|
delete[] er->prefix;
|
||||||
delete (Jet*)er->eng;
|
delete (Jet*)er->eng;
|
||||||
delete er;
|
delete er;
|
||||||
}
|
}
|
||||||
for(int i=0; i<_weights.size(); i++) {
|
for(i=0; i<_weights.size(); i++) {
|
||||||
WeightRec* wr = (WeightRec*)_weights.get(i);
|
WeightRec* wr = (WeightRec*)_weights.get(i);
|
||||||
delete[] wr->prop;
|
delete[] wr->prop;
|
||||||
delete wr;
|
delete wr;
|
||||||
|
@ -247,7 +248,8 @@ void FGFDM::getExternalInput(float dt)
|
||||||
// The control axes
|
// The control axes
|
||||||
ControlMap* cm = _airplane.getControlMap();
|
ControlMap* cm = _airplane.getControlMap();
|
||||||
cm->reset();
|
cm->reset();
|
||||||
for(int i=0; i<_axes.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_axes.size(); i++) {
|
||||||
AxisRec* a = (AxisRec*)_axes.get(i);
|
AxisRec* a = (AxisRec*)_axes.get(i);
|
||||||
float val = fgGetFloat(a->name, 0);
|
float val = fgGetFloat(a->name, 0);
|
||||||
cm->setInput(a->handle, val);
|
cm->setInput(a->handle, val);
|
||||||
|
@ -255,7 +257,7 @@ void FGFDM::getExternalInput(float dt)
|
||||||
cm->applyControls();
|
cm->applyControls();
|
||||||
|
|
||||||
// Weights
|
// Weights
|
||||||
for(int i=0; i<_weights.size(); i++) {
|
for(i=0; i<_weights.size(); i++) {
|
||||||
WeightRec* wr = (WeightRec*)_weights.get(i);
|
WeightRec* wr = (WeightRec*)_weights.get(i);
|
||||||
_airplane.setWeight(wr->handle, fgGetFloat(wr->prop));
|
_airplane.setWeight(wr->handle, fgGetFloat(wr->prop));
|
||||||
}
|
}
|
||||||
|
@ -267,24 +269,25 @@ void FGFDM::getExternalInput(float dt)
|
||||||
void FGFDM::setOutputProperties()
|
void FGFDM::setOutputProperties()
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
for(int i=0; i<_airplane.numTanks(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_airplane.numTanks(); i++) {
|
||||||
sprintf(buf, "/consumables/fuel/tank[%d]/level-gal_us", i);
|
sprintf(buf, "/consumables/fuel/tank[%d]/level-gal_us", i);
|
||||||
fgSetFloat(buf,
|
fgSetFloat(buf,
|
||||||
CM2GALS*_airplane.getFuel(i)/_airplane.getFuelDensity(i));
|
CM2GALS*_airplane.getFuel(i)/_airplane.getFuelDensity(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<_pistons.size(); i++) {
|
for(i=0; i<_pistons.size(); i++) {
|
||||||
EngRec* er = (EngRec*)_pistons.get(i);
|
EngRec* er = (EngRec*)_pistons.get(i);
|
||||||
PropEngine* p = (PropEngine*)er->eng;
|
PropEngine* p = (PropEngine*)er->eng;
|
||||||
|
|
||||||
sprintf(buf, "%s/rpm", er->prefix);
|
sprintf(buf, "%s/rpm", er->prefix);
|
||||||
fgSetFloat(buf, p->getOmega() * (30/3.15149265358979));
|
fgSetFloat(buf, p->getOmega() / RPM2RAD);
|
||||||
|
|
||||||
sprintf(buf, "%s/fuel-flow-gph", er->prefix);
|
sprintf(buf, "%s/fuel-flow-gph", er->prefix);
|
||||||
fgSetFloat(buf, p->getFuelFlow() * (3600*2.2/5)); // FIXME, wrong
|
fgSetFloat(buf, p->getFuelFlow() * (3600*2.2/5)); // FIXME, wrong
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<_jets.size(); i++) {
|
for(i=0; i<_jets.size(); i++) {
|
||||||
EngRec* er = (EngRec*)_jets.get(i);
|
EngRec* er = (EngRec*)_jets.get(i);
|
||||||
Jet* j = (Jet*)er->eng;
|
Jet* j = (Jet*)er->eng;
|
||||||
|
|
||||||
|
@ -380,7 +383,8 @@ void FGFDM::parsePropeller(XMLAttributes* a)
|
||||||
// yet.
|
// yet.
|
||||||
int FGFDM::parseAxis(const char* name)
|
int FGFDM::parseAxis(const char* name)
|
||||||
{
|
{
|
||||||
for(int i=0; i<_axes.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_axes.size(); i++) {
|
||||||
AxisRec* a = (AxisRec*)_axes.get(i);
|
AxisRec* a = (AxisRec*)_axes.get(i);
|
||||||
if(eq(a->name, name))
|
if(eq(a->name, name))
|
||||||
return a->handle;
|
return a->handle;
|
||||||
|
|
|
@ -6,7 +6,8 @@ namespace yasim {
|
||||||
|
|
||||||
Gear::Gear()
|
Gear::Gear()
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++)
|
int i;
|
||||||
|
for(i=0; i<3; i++)
|
||||||
_pos[i] = _cmpr[i] = 0;
|
_pos[i] = _cmpr[i] = 0;
|
||||||
_spring = 1;
|
_spring = 1;
|
||||||
_damp = 0;
|
_damp = 0;
|
||||||
|
@ -19,12 +20,14 @@ Gear::Gear()
|
||||||
|
|
||||||
void Gear::setPosition(float* position)
|
void Gear::setPosition(float* position)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) _pos[i] = position[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) _pos[i] = position[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gear::setCompression(float* compression)
|
void Gear::setCompression(float* compression)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) _cmpr[i] = compression[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) _cmpr[i] = compression[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gear::setSpring(float spring)
|
void Gear::setSpring(float spring)
|
||||||
|
@ -64,12 +67,14 @@ void Gear::setExtension(float extension)
|
||||||
|
|
||||||
void Gear::getPosition(float* out)
|
void Gear::getPosition(float* out)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) out[i] = _pos[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) out[i] = _pos[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gear::getCompression(float* out)
|
void Gear::getCompression(float* out)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) out[i] = _cmpr[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) out[i] = _cmpr[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
float Gear::getSpring()
|
float Gear::getSpring()
|
||||||
|
@ -126,7 +131,8 @@ float Gear::getCompressFraction()
|
||||||
void Gear::calcForce(RigidBody* body, float* v, float* rot, float* ground)
|
void Gear::calcForce(RigidBody* body, float* v, float* rot, float* ground)
|
||||||
{
|
{
|
||||||
// Init the return values
|
// Init the return values
|
||||||
for(int i=0; i<3; i++) _force[i] = _contact[i] = 0;
|
int i;
|
||||||
|
for(i=0; i<3; i++) _force[i] = _contact[i] = 0;
|
||||||
|
|
||||||
// Don't bother if it's not down
|
// Don't bother if it's not down
|
||||||
if(_extension < 1)
|
if(_extension < 1)
|
||||||
|
@ -150,7 +156,7 @@ void Gear::calcForce(RigidBody* body, float* v, float* rot, float* ground)
|
||||||
// Calculate the point of ground _contact.
|
// Calculate the point of ground _contact.
|
||||||
_frac = a/(a-b);
|
_frac = a/(a-b);
|
||||||
if(b < 0) _frac = 1;
|
if(b < 0) _frac = 1;
|
||||||
for(int i=0; i<3; i++)
|
for(i=0; i<3; i++)
|
||||||
_contact[i] = _pos[i] + _frac*_cmpr[i];
|
_contact[i] = _pos[i] + _frac*_cmpr[i];
|
||||||
|
|
||||||
// Turn _cmpr into a unit vector and a magnitude
|
// Turn _cmpr into a unit vector and a magnitude
|
||||||
|
|
|
@ -2,6 +2,15 @@
|
||||||
#include "Glue.hpp"
|
#include "Glue.hpp"
|
||||||
namespace yasim {
|
namespace yasim {
|
||||||
|
|
||||||
|
// WGS84 numbers
|
||||||
|
static const double EQURAD = 6378137; // equatorial radius
|
||||||
|
static const double STRETCH = 1.003352810665; // equ./polar radius
|
||||||
|
|
||||||
|
// Derived from the above
|
||||||
|
static const double SQUASH = 0.99665839311; // 1/STRETCH
|
||||||
|
static const double POLRAD = 6356823.77346; // EQURAD*SQUASH
|
||||||
|
static const double iPOLRAD = 1.57311266701e-07; // 1/POLRAD
|
||||||
|
|
||||||
void Glue::calcAlphaBeta(State* s, float* alpha, float* beta)
|
void Glue::calcAlphaBeta(State* s, float* alpha, float* beta)
|
||||||
{
|
{
|
||||||
// Convert the velocity to the aircraft frame.
|
// Convert the velocity to the aircraft frame.
|
||||||
|
@ -145,8 +154,9 @@ void Glue::euler2orient(float roll, float pitch, float hdg, float* out)
|
||||||
// rotation and are done out longhand below for efficiency.
|
// rotation and are done out longhand below for efficiency.
|
||||||
|
|
||||||
// Init to the identity matrix
|
// Init to the identity matrix
|
||||||
for(int i=0; i<3; i++)
|
int i, j;
|
||||||
for(int j=0; j<3; j++)
|
for(i=0; i<3; i++)
|
||||||
|
for(j=0; j<3; j++)
|
||||||
out[3*i+j] = (i==j) ? 1 : 0;
|
out[3*i+j] = (i==j) ? 1 : 0;
|
||||||
|
|
||||||
// Negate Y and Z
|
// Negate Y and Z
|
||||||
|
@ -154,7 +164,8 @@ void Glue::euler2orient(float roll, float pitch, float hdg, float* out)
|
||||||
|
|
||||||
float s = Math::sin(roll);
|
float s = Math::sin(roll);
|
||||||
float c = Math::cos(roll);
|
float c = Math::cos(roll);
|
||||||
for(int col=0; col<3; col++) {
|
int col;
|
||||||
|
for(col=0; col<3; col++) {
|
||||||
float y=out[col+3], z=out[col+6];
|
float y=out[col+3], z=out[col+6];
|
||||||
out[col+3] = c*y - s*z;
|
out[col+3] = c*y - s*z;
|
||||||
out[col+6] = s*y + c*z;
|
out[col+6] = s*y + c*z;
|
||||||
|
@ -162,7 +173,7 @@ void Glue::euler2orient(float roll, float pitch, float hdg, float* out)
|
||||||
|
|
||||||
s = Math::sin(pitch);
|
s = Math::sin(pitch);
|
||||||
c = Math::cos(pitch);
|
c = Math::cos(pitch);
|
||||||
for(int col=0; col<3; col++) {
|
for(col=0; col<3; col++) {
|
||||||
float x=out[col], z=out[col+6];
|
float x=out[col], z=out[col+6];
|
||||||
out[col] = c*x + s*z;
|
out[col] = c*x + s*z;
|
||||||
out[col+6] = c*z - s*x;
|
out[col+6] = c*z - s*x;
|
||||||
|
@ -170,7 +181,7 @@ void Glue::euler2orient(float roll, float pitch, float hdg, float* out)
|
||||||
|
|
||||||
s = Math::sin(hdg);
|
s = Math::sin(hdg);
|
||||||
c = Math::cos(hdg);
|
c = Math::cos(hdg);
|
||||||
for(int col=0; col<3; col++) {
|
for(col=0; col<3; col++) {
|
||||||
float x=out[col], y=out[col+3];
|
float x=out[col], y=out[col+3];
|
||||||
out[col] = c*x - s*y;
|
out[col] = c*x - s*y;
|
||||||
out[col+3] = s*x + c*y;
|
out[col+3] = s*x + c*y;
|
||||||
|
|
|
@ -43,17 +43,6 @@ public:
|
||||||
// Returns a geodetic (i.e. gravitational, "level", etc...) "up"
|
// Returns a geodetic (i.e. gravitational, "level", etc...) "up"
|
||||||
// vector for the specified xyz position.
|
// vector for the specified xyz position.
|
||||||
static void geodUp(double* pos, float* out);
|
static void geodUp(double* pos, float* out);
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// WGS84 numbers
|
|
||||||
static const double EQURAD = 6378137; // equatorial radius
|
|
||||||
static const double STRETCH = 1.003352810665; // equ./polar radius
|
|
||||||
|
|
||||||
// Derived from the above
|
|
||||||
static const double SQUASH = 0.99665839311; // 1/STRETCH
|
|
||||||
static const double POLRAD = 6356823.77346; // EQURAD*SQUASH
|
|
||||||
static const double iPOLRAD = 1.57311266701e-07; // 1/POLRAD
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace yasim
|
}; // namespace yasim
|
||||||
|
|
|
@ -75,7 +75,8 @@ void Integrator::calcNewInterval()
|
||||||
float dt = _dt / 4;
|
float dt = _dt / 4;
|
||||||
|
|
||||||
orthonormalize(_s.orient);
|
orthonormalize(_s.orient);
|
||||||
for(int i=0; i<4; i++) {
|
int i;
|
||||||
|
for(i=0; i<4; i++) {
|
||||||
_body->reset();
|
_body->reset();
|
||||||
_env->calcForces(&s);
|
_env->calcForces(&s);
|
||||||
|
|
||||||
|
@ -124,7 +125,8 @@ void Integrator::calcNewInterval()
|
||||||
// First off, sanify the initial orientation
|
// First off, sanify the initial orientation
|
||||||
orthonormalize(_s.orient);
|
orthonormalize(_s.orient);
|
||||||
|
|
||||||
for(int i=0; i<NITER; i++) {
|
int i;
|
||||||
|
for(i=0; i<NITER; i++) {
|
||||||
//
|
//
|
||||||
// extrapolate forward based on current values of the
|
// extrapolate forward based on current values of the
|
||||||
// derivatives and the ORIGINAL values of the
|
// derivatives and the ORIGINAL values of the
|
||||||
|
@ -139,7 +141,8 @@ void Integrator::calcNewInterval()
|
||||||
Math::mmul33(_s.orient, rotmat, ori[i]);
|
Math::mmul33(_s.orient, rotmat, ori[i]);
|
||||||
|
|
||||||
// add velocity to (original!) position
|
// add velocity to (original!) position
|
||||||
for(int j=0; j<3; j++) pos[i][j] = _s.pos[j];
|
int j;
|
||||||
|
for(j=0; j<3; j++) pos[i][j] = _s.pos[j];
|
||||||
extrapolatePosition(pos[i], currVel, dt, _s.orient, ori[i]);
|
extrapolatePosition(pos[i], currVel, dt, _s.orient, ori[i]);
|
||||||
|
|
||||||
// add acceleration to (original!) velocity
|
// add acceleration to (original!) velocity
|
||||||
|
@ -163,12 +166,12 @@ void Integrator::calcNewInterval()
|
||||||
// per-coordinate arrays should be changed into a single array
|
// per-coordinate arrays should be changed into a single array
|
||||||
// of State objects. Ick.
|
// of State objects. Ick.
|
||||||
State stmp;
|
State stmp;
|
||||||
for(int j=0; j<3; j++) {
|
for(j=0; j<3; j++) {
|
||||||
stmp.pos[j] = pos[i][j];
|
stmp.pos[j] = pos[i][j];
|
||||||
stmp.v[j] = vel[i][j];
|
stmp.v[j] = vel[i][j];
|
||||||
stmp.rot[j] = rot[i][j];
|
stmp.rot[j] = rot[i][j];
|
||||||
}
|
}
|
||||||
for(int j=0; j<9; j++)
|
for(j=0; j<9; j++)
|
||||||
stmp.orient[j] = ori[i][j];
|
stmp.orient[j] = ori[i][j];
|
||||||
_env->calcForces(&stmp);
|
_env->calcForces(&stmp);
|
||||||
|
|
||||||
|
@ -190,16 +193,17 @@ void Integrator::calcNewInterval()
|
||||||
// But the space is "locally" cartesian.
|
// But the space is "locally" cartesian.
|
||||||
State derivs;
|
State derivs;
|
||||||
float tot = 0;
|
float tot = 0;
|
||||||
for(int i=0; i<NITER; i++) {
|
for(i=0; i<NITER; i++) {
|
||||||
float wgt = WEIGHTS[i];
|
float wgt = WEIGHTS[i];
|
||||||
tot += wgt;
|
tot += wgt;
|
||||||
for(int j=0; j<3; j++) {
|
int j;
|
||||||
|
for(j=0; j<3; j++) {
|
||||||
derivs.v[j] += wgt*vel[i][j]; derivs.rot[j] += wgt*rot[i][j];
|
derivs.v[j] += wgt*vel[i][j]; derivs.rot[j] += wgt*rot[i][j];
|
||||||
derivs.acc[j] += wgt*acc[i][j]; derivs.racc[j] += wgt*rac[i][j];
|
derivs.acc[j] += wgt*acc[i][j]; derivs.racc[j] += wgt*rac[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float itot = 1/tot;
|
float itot = 1/tot;
|
||||||
for(int i=0; i<3; i++) {
|
for(i=0; i<3; i++) {
|
||||||
derivs.v[i] *= itot; derivs.rot[i] *= itot;
|
derivs.v[i] *= itot; derivs.rot[i] *= itot;
|
||||||
derivs.acc[i] *= itot; derivs.racc[i] *= itot;
|
derivs.acc[i] *= itot; derivs.racc[i] *= itot;
|
||||||
}
|
}
|
||||||
|
@ -211,7 +215,7 @@ void Integrator::calcNewInterval()
|
||||||
|
|
||||||
// save the starting orientation
|
// save the starting orientation
|
||||||
float orient0[9];
|
float orient0[9];
|
||||||
for(int i=0; i<9; i++) orient0[i] = _s.orient[i];
|
for(i=0; i<9; i++) orient0[i] = _s.orient[i];
|
||||||
|
|
||||||
float rotmat[9];
|
float rotmat[9];
|
||||||
rotMatrix(derivs.rot, _dt, rotmat);
|
rotMatrix(derivs.rot, _dt, rotmat);
|
||||||
|
@ -226,7 +230,7 @@ void Integrator::calcNewInterval()
|
||||||
Math::mul3(_dt, derivs.racc, tmp);
|
Math::mul3(_dt, derivs.racc, tmp);
|
||||||
Math::add3(_s.rot, tmp, _s.rot);
|
Math::add3(_s.rot, tmp, _s.rot);
|
||||||
|
|
||||||
for(int i=0; i<3; i++) {
|
for(i=0; i<3; i++) {
|
||||||
_s.acc[i] = derivs.acc[i];
|
_s.acc[i] = derivs.acc[i];
|
||||||
_s.racc[i] = derivs.racc[i];
|
_s.racc[i] = derivs.racc[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,8 @@ void Math::mmul33(float* a, float* b, float* out)
|
||||||
tmp[5] = a[3]*b[2] + a[4]*b[5] + a[5]*b[8];
|
tmp[5] = a[3]*b[2] + a[4]*b[5] + a[5]*b[8];
|
||||||
tmp[8] = a[6]*b[2] + a[7]*b[5] + a[8]*b[8];
|
tmp[8] = a[6]*b[2] + a[7]*b[5] + a[8]*b[8];
|
||||||
|
|
||||||
for(int i=0; i<9; i++)
|
int i;
|
||||||
|
for(i=0; i<9; i++)
|
||||||
out[i] = tmp[i];
|
out[i] = tmp[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ void printState(State* s)
|
||||||
printf("\nNEW STATE (LOCAL COORDS)\n");
|
printf("\nNEW STATE (LOCAL COORDS)\n");
|
||||||
printf("pos: %10.2f %10.2f %10.2f\n", tmp.pos[0], tmp.pos[1], tmp.pos[2]);
|
printf("pos: %10.2f %10.2f %10.2f\n", tmp.pos[0], tmp.pos[1], tmp.pos[2]);
|
||||||
printf("o: ");
|
printf("o: ");
|
||||||
for(int i=0; i<3; i++) {
|
int i;
|
||||||
|
for(i=0; i<3; i++) {
|
||||||
if(i != 0) printf(" ");
|
if(i != 0) printf(" ");
|
||||||
printf("%6.2f %6.2f %6.2f\n",
|
printf("%6.2f %6.2f %6.2f\n",
|
||||||
tmp.orient[3*i+0], tmp.orient[3*i+1], tmp.orient[3*i+2]);
|
tmp.orient[3*i+0], tmp.orient[3*i+1], tmp.orient[3*i+2]);
|
||||||
|
@ -38,7 +39,8 @@ void printState(State* s)
|
||||||
|
|
||||||
Model::Model()
|
Model::Model()
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) _wind[i] = 0;
|
int i;
|
||||||
|
for(i=0; i<3; i++) _wind[i] = 0;
|
||||||
|
|
||||||
_integrator.setBody(&_body);
|
_integrator.setBody(&_body);
|
||||||
_integrator.setEnvironment(this);
|
_integrator.setEnvironment(this);
|
||||||
|
@ -56,7 +58,8 @@ void Model::getThrust(float* out)
|
||||||
{
|
{
|
||||||
float tmp[3];
|
float tmp[3];
|
||||||
out[0] = out[1] = out[2] = 0;
|
out[0] = out[1] = out[2] = 0;
|
||||||
for(int i=0; i<_thrusters.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_thrusters.size(); i++) {
|
||||||
Thruster* t = (Thruster*)_thrusters.get(i);
|
Thruster* t = (Thruster*)_thrusters.get(i);
|
||||||
t->getThrust(tmp);
|
t->getThrust(tmp);
|
||||||
Math::add3(tmp, out, out);
|
Math::add3(tmp, out, out);
|
||||||
|
@ -66,9 +69,10 @@ void Model::getThrust(float* out)
|
||||||
void Model::initIteration()
|
void Model::initIteration()
|
||||||
{
|
{
|
||||||
// Precompute torque and angular momentum for the thrusters
|
// Precompute torque and angular momentum for the thrusters
|
||||||
for(int i=0; i<3; i++)
|
int i;
|
||||||
|
for(i=0; i<3; i++)
|
||||||
_gyro[i] = _torque[i] = 0;
|
_gyro[i] = _torque[i] = 0;
|
||||||
for(int i=0; i<_thrusters.size(); i++) {
|
for(i=0; i<_thrusters.size(); i++) {
|
||||||
Thruster* t = (Thruster*)_thrusters.get(i);
|
Thruster* t = (Thruster*)_thrusters.get(i);
|
||||||
|
|
||||||
// Get the wind velocity at the thruster location
|
// Get the wind velocity at the thruster location
|
||||||
|
@ -77,7 +81,7 @@ void Model::initIteration()
|
||||||
localWind(pos, _s, v);
|
localWind(pos, _s, v);
|
||||||
|
|
||||||
t->setWind(v);
|
t->setWind(v);
|
||||||
t->setAir(_P, _T);
|
t->setAir(_pressure, _temp);
|
||||||
t->integrate(_integrator.getInterval());
|
t->integrate(_integrator.getInterval());
|
||||||
|
|
||||||
t->getTorque(v);
|
t->getTorque(v);
|
||||||
|
@ -164,14 +168,15 @@ void Model::setGroundEffect(float* pos, float span, float mul)
|
||||||
// (v dot _ground)-_ground[3] gives the distance AGL.
|
// (v dot _ground)-_ground[3] gives the distance AGL.
|
||||||
void Model::setGroundPlane(double* planeNormal, double fromOrigin)
|
void Model::setGroundPlane(double* planeNormal, double fromOrigin)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) _ground[i] = planeNormal[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) _ground[i] = planeNormal[i];
|
||||||
_ground[3] = fromOrigin;
|
_ground[3] = fromOrigin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::setAir(float pressure, float temp)
|
void Model::setAir(float pressure, float temp)
|
||||||
{
|
{
|
||||||
_P = pressure;
|
_pressure = pressure;
|
||||||
_T = temp;
|
_temp = temp;
|
||||||
_rho = Atmosphere::calcDensity(pressure, temp);
|
_rho = Atmosphere::calcDensity(pressure, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +194,8 @@ void Model::calcForces(State* s)
|
||||||
// step.
|
// step.
|
||||||
_body.setGyro(_gyro);
|
_body.setGyro(_gyro);
|
||||||
_body.addTorque(_torque);
|
_body.addTorque(_torque);
|
||||||
for(int i=0; i<_thrusters.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_thrusters.size(); i++) {
|
||||||
Thruster* t = (Thruster*)_thrusters.get(i);
|
Thruster* t = (Thruster*)_thrusters.get(i);
|
||||||
float thrust[3], pos[3];
|
float thrust[3], pos[3];
|
||||||
t->getThrust(thrust);
|
t->getThrust(thrust);
|
||||||
|
@ -208,7 +214,7 @@ void Model::calcForces(State* s)
|
||||||
// point is different due to rotation.
|
// point is different due to rotation.
|
||||||
float faero[3];
|
float faero[3];
|
||||||
faero[0] = faero[1] = faero[2] = 0;
|
faero[0] = faero[1] = faero[2] = 0;
|
||||||
for(int i=0; i<_surfaces.size(); i++) {
|
for(i=0; i<_surfaces.size(); i++) {
|
||||||
Surface* sf = (Surface*)_surfaces.get(i);
|
Surface* sf = (Surface*)_surfaces.get(i);
|
||||||
|
|
||||||
// Vsurf = wind - velocity + (rot cross (cg - pos))
|
// Vsurf = wind - velocity + (rot cross (cg - pos))
|
||||||
|
@ -247,7 +253,7 @@ void Model::calcForces(State* s)
|
||||||
Math::vmul33(s->orient, s->v, lv);
|
Math::vmul33(s->orient, s->v, lv);
|
||||||
|
|
||||||
// The landing gear
|
// The landing gear
|
||||||
for(int i=0; i<_gears.size(); i++) {
|
for(i=0; i<_gears.size(); i++) {
|
||||||
float force[3], contact[3];
|
float force[3], contact[3];
|
||||||
Gear* g = (Gear*)_gears.get(i);
|
Gear* g = (Gear*)_gears.get(i);
|
||||||
g->calcForce(&_body, lv, lrot, ground);
|
g->calcForce(&_body, lv, lrot, ground);
|
||||||
|
@ -265,7 +271,8 @@ void Model::newState(State* s)
|
||||||
// Some simple collision detection
|
// Some simple collision detection
|
||||||
float ground[4], pos[3], cmpr[3];
|
float ground[4], pos[3], cmpr[3];
|
||||||
ground[3] = localGround(s, ground);
|
ground[3] = localGround(s, ground);
|
||||||
for(int i=0; i<_gears.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_gears.size(); i++) {
|
||||||
Gear* g = (Gear*)_gears.get(i);
|
Gear* g = (Gear*)_gears.get(i);
|
||||||
g->getPosition(pos);
|
g->getPosition(pos);
|
||||||
g->getCompression(cmpr);
|
g->getCompression(cmpr);
|
||||||
|
|
|
@ -71,8 +71,8 @@ private:
|
||||||
float _wingCenter[3];
|
float _wingCenter[3];
|
||||||
|
|
||||||
double _ground[4];
|
double _ground[4];
|
||||||
float _P;
|
float _pressure;
|
||||||
float _T;
|
float _temp;
|
||||||
float _rho;
|
float _rho;
|
||||||
float _wind[3];
|
float _wind[3];
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ PistonEngine::PistonEngine(float power, float speed)
|
||||||
// (2.2 lb/kg, 745.7 W/hp, 3600 sec/hour) 3.69e-07 kg/Ws.
|
// (2.2 lb/kg, 745.7 W/hp, 3600 sec/hour) 3.69e-07 kg/Ws.
|
||||||
_f0 = power * 3.69e-07;
|
_f0 = power * 3.69e-07;
|
||||||
|
|
||||||
_P0 = power;
|
_power0 = power;
|
||||||
_omega0 = speed;
|
_omega0 = speed;
|
||||||
|
|
||||||
// We must be at sea level under standard conditions
|
// We must be at sea level under standard conditions
|
||||||
|
@ -40,7 +40,7 @@ void PistonEngine::setTurboParams(float turbo, float maxMP)
|
||||||
|
|
||||||
float PistonEngine::getPower()
|
float PistonEngine::getPower()
|
||||||
{
|
{
|
||||||
return _P0;
|
return _power0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PistonEngine::setThrottle(float t)
|
void PistonEngine::setThrottle(float t)
|
||||||
|
@ -89,7 +89,7 @@ void PistonEngine::calc(float P, float T, float speed,
|
||||||
|
|
||||||
// And finally the power is just the reference power scaled by the
|
// And finally the power is just the reference power scaled by the
|
||||||
// amount of fuel burned.
|
// amount of fuel burned.
|
||||||
float power = _P0 * burned/_f0;
|
float power = _power0 * burned/_f0;
|
||||||
|
|
||||||
*torqueOut = power/speed;
|
*torqueOut = power/speed;
|
||||||
*fuelFlowOut = fuel;
|
*fuelFlowOut = fuel;
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
float* powerOut, float* fuelFlowOut);
|
float* powerOut, float* fuelFlowOut);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _P0; // reference power setting
|
float _power0; // reference power setting
|
||||||
float _omega0; // " engine speed
|
float _omega0; // " engine speed
|
||||||
float _rho0; // " manifold air density
|
float _rho0; // " manifold air density
|
||||||
float _f0; // "ideal" fuel flow at P0/omega0
|
float _f0; // "ideal" fuel flow at P0/omega0
|
||||||
|
|
|
@ -42,17 +42,20 @@ float PropEngine::getOmega()
|
||||||
|
|
||||||
void PropEngine::getThrust(float* out)
|
void PropEngine::getThrust(float* out)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) out[i] = _thrust[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) out[i] = _thrust[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropEngine::getTorque(float* out)
|
void PropEngine::getTorque(float* out)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) out[i] = _torque[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) out[i] = _torque[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropEngine::getGyro(float* out)
|
void PropEngine::getGyro(float* out)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) out[i] = _gyro[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) out[i] = _gyro[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
float PropEngine::getFuelFlow()
|
float PropEngine::getFuelFlow()
|
||||||
|
@ -78,7 +81,7 @@ void PropEngine::stabilize()
|
||||||
while(true) {
|
while(true) {
|
||||||
float etau, ptau, dummy;
|
float etau, ptau, dummy;
|
||||||
_prop->calc(_rho, speed, _omega, &dummy, &ptau);
|
_prop->calc(_rho, speed, _omega, &dummy, &ptau);
|
||||||
_eng->calc(_P, _T, _omega, &etau, &dummy);
|
_eng->calc(_pressure, _temp, _omega, &etau, &dummy);
|
||||||
float tdiff = etau - ptau;
|
float tdiff = etau - ptau;
|
||||||
|
|
||||||
if(Math::abs(tdiff/_moment) < 0.1)
|
if(Math::abs(tdiff/_moment) < 0.1)
|
||||||
|
@ -109,7 +112,7 @@ void PropEngine::integrate(float dt)
|
||||||
|
|
||||||
_prop->calc(_rho, speed, _omega,
|
_prop->calc(_rho, speed, _omega,
|
||||||
&thrust, &propTorque);
|
&thrust, &propTorque);
|
||||||
_eng->calc(_P, _T, _omega, &engTorque, &_fuelFlow);
|
_eng->calc(_pressure, _temp, _omega, &engTorque, &_fuelFlow);
|
||||||
|
|
||||||
// Turn the thrust into a vector and save it
|
// Turn the thrust into a vector and save it
|
||||||
Math::mul3(thrust, _dir, _thrust);
|
Math::mul3(thrust, _dir, _thrust);
|
||||||
|
|
|
@ -15,11 +15,11 @@ Propeller::Propeller(float radius, float v, float omega,
|
||||||
_r = radius;
|
_r = radius;
|
||||||
_etaC = 0.85; // make this settable?
|
_etaC = 0.85; // make this settable?
|
||||||
|
|
||||||
_J0 = v/(omega*_lambdaPeak);
|
_j0 = v/(omega*_lambdaPeak);
|
||||||
_baseJ0 = _J0;
|
_baseJ0 = _j0;
|
||||||
|
|
||||||
float V2 = v*v + (_r*omega)*(_r*omega);
|
float V2 = v*v + (_r*omega)*(_r*omega);
|
||||||
_F0 = 2*_etaC*power/(rho*v*V2);
|
_f0 = 2*_etaC*power/(rho*v*V2);
|
||||||
|
|
||||||
_matchTakeoff = false;
|
_matchTakeoff = false;
|
||||||
}
|
}
|
||||||
|
@ -29,17 +29,17 @@ void Propeller::setTakeoff(float omega0, float power0)
|
||||||
// Takeoff thrust coefficient at lambda==0
|
// Takeoff thrust coefficient at lambda==0
|
||||||
_matchTakeoff = true;
|
_matchTakeoff = true;
|
||||||
float V2 = _r*omega0 * _r*omega0;
|
float V2 = _r*omega0 * _r*omega0;
|
||||||
float gamma = _etaC * _beta / _J0;
|
float gamma = _etaC * _beta / _j0;
|
||||||
float torque = power0 / omega0;
|
float torque = power0 / omega0;
|
||||||
float density = Atmosphere::getStdDensity(0);
|
float density = Atmosphere::getStdDensity(0);
|
||||||
_tc0 = (torque * gamma) / (0.5 * density * V2 * _F0);
|
_tc0 = (torque * gamma) / (0.5 * density * V2 * _f0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Propeller::modPitch(float mod)
|
void Propeller::modPitch(float mod)
|
||||||
{
|
{
|
||||||
_J0 *= mod;
|
_j0 *= mod;
|
||||||
if(_J0 < 0.25*_baseJ0) _J0 = 0.25*_baseJ0;
|
if(_j0 < 0.25*_baseJ0) _j0 = 0.25*_baseJ0;
|
||||||
if(_J0 > 4*_baseJ0) _J0 = 4*_baseJ0;
|
if(_j0 > 4*_baseJ0) _j0 = 4*_baseJ0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,12 +54,12 @@ void Propeller::calc(float density, float v, float omega,
|
||||||
if(v < 0) v = 0;
|
if(v < 0) v = 0;
|
||||||
|
|
||||||
float J = v/omega;
|
float J = v/omega;
|
||||||
float lambda = J/_J0;
|
float lambda = J/_j0;
|
||||||
|
|
||||||
float torque = 0;
|
float torque = 0;
|
||||||
if(lambda > 1) {
|
if(lambda > 1) {
|
||||||
lambda = 1.0/lambda;
|
lambda = 1.0/lambda;
|
||||||
torque = (density*V2*_F0*_J0)/(4*_etaC*_beta*(1-_lambdaPeak));
|
torque = (density*V2*_f0*_j0)/(4*_etaC*_beta*(1-_lambdaPeak));
|
||||||
}
|
}
|
||||||
|
|
||||||
// There's an undefined point at 1. Just offset by a tiny bit to
|
// There's an undefined point at 1. Just offset by a tiny bit to
|
||||||
|
@ -72,14 +72,14 @@ void Propeller::calc(float density, float v, float omega,
|
||||||
float l4 = lambda*lambda; l4 = l4*l4;
|
float l4 = lambda*lambda; l4 = l4*l4;
|
||||||
|
|
||||||
// thrust/torque ratio
|
// thrust/torque ratio
|
||||||
float gamma = (_etaC*_beta/_J0)*(1-l4);
|
float gamma = (_etaC*_beta/_j0)*(1-l4);
|
||||||
|
|
||||||
// Compute a thrust, clamp to takeoff thrust to prevend huge
|
// Compute a thrust, clamp to takeoff thrust to prevend huge
|
||||||
// numbers at slow speeds.
|
// numbers at slow speeds.
|
||||||
float tc = (1 - lambda) / (1 - _lambdaPeak);
|
float tc = (1 - lambda) / (1 - _lambdaPeak);
|
||||||
if(_matchTakeoff && tc > _tc0) tc = _tc0;
|
if(_matchTakeoff && tc > _tc0) tc = _tc0;
|
||||||
|
|
||||||
float thrust = 0.5 * density * V2 * _F0 * tc;
|
float thrust = 0.5 * density * V2 * _f0 * tc;
|
||||||
|
|
||||||
if(torque > 0) {
|
if(torque > 0) {
|
||||||
torque -= thrust/gamma;
|
torque -= thrust/gamma;
|
||||||
|
|
|
@ -25,9 +25,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _r; // characteristic radius
|
float _r; // characteristic radius
|
||||||
float _J0; // zero-thrust advance ratio
|
float _j0; // zero-thrust advance ratio
|
||||||
float _baseJ0; // ... uncorrected for prop advance
|
float _baseJ0; // ... uncorrected for prop advance
|
||||||
float _F0; // thrust coefficient
|
float _f0; // thrust coefficient
|
||||||
float _etaC; // Peak efficiency
|
float _etaC; // Peak efficiency
|
||||||
float _lambdaPeak; // constant, ~0.759835;
|
float _lambdaPeak; // constant, ~0.759835;
|
||||||
float _beta; // constant, ~1.48058;
|
float _beta; // constant, ~1.48058;
|
||||||
|
|
|
@ -24,7 +24,8 @@ int RigidBody::addMass(float mass, float* pos)
|
||||||
if(_nMasses == _massesAlloced) {
|
if(_nMasses == _massesAlloced) {
|
||||||
_massesAlloced *= 2;
|
_massesAlloced *= 2;
|
||||||
Mass *m2 = new Mass[_massesAlloced];
|
Mass *m2 = new Mass[_massesAlloced];
|
||||||
for(int i=0; i<_nMasses; i++)
|
int i;
|
||||||
|
for(i=0; i<_nMasses; i++)
|
||||||
m2[i] = _masses[i];
|
m2[i] = _masses[i];
|
||||||
delete[] _masses;
|
delete[] _masses;
|
||||||
_masses = m2;
|
_masses = m2;
|
||||||
|
@ -86,7 +87,8 @@ void RigidBody::recalc()
|
||||||
// Calculate the c.g and total mass:
|
// Calculate the c.g and total mass:
|
||||||
_totalMass = 0;
|
_totalMass = 0;
|
||||||
_cg[0] = _cg[1] = _cg[2] = 0;
|
_cg[0] = _cg[1] = _cg[2] = 0;
|
||||||
for(int i=0; i<_nMasses; i++) {
|
int i;
|
||||||
|
for(i=0; i<_nMasses; i++) {
|
||||||
float m = _masses[i].m;
|
float m = _masses[i].m;
|
||||||
_totalMass += m;
|
_totalMass += m;
|
||||||
_cg[0] += m * _masses[i].p[0];
|
_cg[0] += m * _masses[i].p[0];
|
||||||
|
@ -96,10 +98,10 @@ void RigidBody::recalc()
|
||||||
Math::mul3(1/_totalMass, _cg, _cg);
|
Math::mul3(1/_totalMass, _cg, _cg);
|
||||||
|
|
||||||
// Now the inertia tensor:
|
// Now the inertia tensor:
|
||||||
for(int i=0; i<9; i++)
|
for(i=0; i<9; i++)
|
||||||
_I[i] = 0;
|
_tI[i] = 0;
|
||||||
|
|
||||||
for(int i=0; i<_nMasses; i++) {
|
for(i=0; i<_nMasses; i++) {
|
||||||
float m = _masses[i].m;
|
float m = _masses[i].m;
|
||||||
|
|
||||||
float x = _masses[i].p[0] - _cg[0];
|
float x = _masses[i].p[0] - _cg[0];
|
||||||
|
@ -109,13 +111,13 @@ void RigidBody::recalc()
|
||||||
float xy = m*x*y; float yz = m*y*z; float zx = m*z*x;
|
float xy = m*x*y; float yz = m*y*z; float zx = m*z*x;
|
||||||
float x2 = m*x*x; float y2 = m*y*y; float z2 = m*z*z;
|
float x2 = m*x*x; float y2 = m*y*y; float z2 = m*z*z;
|
||||||
|
|
||||||
_I[0] += y2+z2; _I[1] -= xy; _I[2] -= zx;
|
_tI[0] += y2+z2; _tI[1] -= xy; _tI[2] -= zx;
|
||||||
_I[3] -= xy; _I[4] += x2+z2; _I[5] -= yz;
|
_tI[3] -= xy; _tI[4] += x2+z2; _tI[5] -= yz;
|
||||||
_I[6] -= zx; _I[7] -= yz; _I[8] += x2+y2;
|
_tI[6] -= zx; _tI[7] -= yz; _tI[8] += x2+y2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// And its inverse
|
// And its inverse
|
||||||
Math::invert33(_I, _invI);
|
Math::invert33(_tI, _invI);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::reset()
|
void RigidBody::reset()
|
||||||
|
@ -195,7 +197,7 @@ void RigidBody::getAngularAccel(float* accelOut)
|
||||||
// Now work the equation of motion. Use "v" as a notational
|
// Now work the equation of motion. Use "v" as a notational
|
||||||
// shorthand, as the value isn't an acceleration until the end.
|
// shorthand, as the value isn't an acceleration until the end.
|
||||||
float *v = accelOut;
|
float *v = accelOut;
|
||||||
Math::vmul33(_I, _spin, v); // v = I*omega
|
Math::vmul33(_tI, _spin, v); // v = I*omega
|
||||||
Math::cross3(_spin, v, v); // v = omega X I*omega
|
Math::cross3(_spin, v, v); // v = omega X I*omega
|
||||||
Math::add3(tau, v, v); // v = tau + (omega X I*omega)
|
Math::add3(tau, v, v); // v = tau + (omega X I*omega)
|
||||||
Math::vmul33(_invI, v, v); // v = invI*(tau + (omega X I*omega))
|
Math::vmul33(_invI, v, v); // v = invI*(tau + (omega X I*omega))
|
||||||
|
|
|
@ -110,7 +110,7 @@ private:
|
||||||
float _gyro[3];
|
float _gyro[3];
|
||||||
|
|
||||||
// Inertia tensor, and its inverse. Computed from the above.
|
// Inertia tensor, and its inverse. Computed from the above.
|
||||||
float _I[9];
|
float _tI[9];
|
||||||
float _invI[9];
|
float _invI[9];
|
||||||
|
|
||||||
// Externally determined quantities
|
// Externally determined quantities
|
||||||
|
|
|
@ -9,7 +9,8 @@ Surface::Surface()
|
||||||
_cx = _cy = _cz = 1;
|
_cx = _cy = _cz = 1;
|
||||||
_cz0 = 0;
|
_cz0 = 0;
|
||||||
_peaks[0] = _peaks[1] = 1;
|
_peaks[0] = _peaks[1] = 1;
|
||||||
for(int i=0; i<4; i++)
|
int i;
|
||||||
|
for(i=0; i<4; i++)
|
||||||
_stalls[i] = _widths[i] = 0;
|
_stalls[i] = _widths[i] = 0;
|
||||||
_orient[0] = 1; _orient[1] = 0; _orient[2] = 0;
|
_orient[0] = 1; _orient[1] = 0; _orient[2] = 0;
|
||||||
_orient[3] = 0; _orient[4] = 1; _orient[5] = 0;
|
_orient[3] = 0; _orient[4] = 1; _orient[5] = 0;
|
||||||
|
@ -25,12 +26,14 @@ Surface::Surface()
|
||||||
|
|
||||||
void Surface::setPosition(float* p)
|
void Surface::setPosition(float* p)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) _pos[i] = p[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) _pos[i] = p[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Surface::getPosition(float* out)
|
void Surface::getPosition(float* out)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) out[i] = _pos[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) out[i] = _pos[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Surface::setChord(float chord)
|
void Surface::setChord(float chord)
|
||||||
|
@ -85,7 +88,8 @@ void Surface::setStallWidth(int i, float width)
|
||||||
|
|
||||||
void Surface::setOrientation(float* o)
|
void Surface::setOrientation(float* o)
|
||||||
{
|
{
|
||||||
for(int i=0; i<9; i++)
|
int i;
|
||||||
|
for(i=0; i<9; i++)
|
||||||
_orient[i] = o[i];
|
_orient[i] = o[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +142,8 @@ void Surface::calcForce(float* v, float rho, float* out, float* torque)
|
||||||
// Handle the blowup condition. Zero velocity means zero force by
|
// Handle the blowup condition. Zero velocity means zero force by
|
||||||
// definition.
|
// definition.
|
||||||
if(vel == 0) {
|
if(vel == 0) {
|
||||||
for(int i=0; i<3; i++) out[i] = torque[i] = 0;
|
int i;
|
||||||
|
for(i=0; i<3; i++) out[i] = torque[i] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,11 @@ namespace yasim {
|
||||||
Thruster::Thruster()
|
Thruster::Thruster()
|
||||||
{
|
{
|
||||||
_dir[0] = 1; _dir[1] = 0; _dir[2] = 0;
|
_dir[0] = 1; _dir[1] = 0; _dir[2] = 0;
|
||||||
for(int i=0; i<3; i++) _pos[i] = _wind[i] = 0;
|
int i;
|
||||||
|
for(i=0; i<3; i++) _pos[i] = _wind[i] = 0;
|
||||||
_throttle = 0;
|
_throttle = 0;
|
||||||
_mixture = 0;
|
_mixture = 0;
|
||||||
_P = _T = _rho = 0;
|
_pressure = _temp = _rho = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thruster::~Thruster()
|
Thruster::~Thruster()
|
||||||
|
@ -17,17 +18,20 @@ Thruster::~Thruster()
|
||||||
|
|
||||||
void Thruster::getPosition(float* out)
|
void Thruster::getPosition(float* out)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) out[i] = _pos[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) out[i] = _pos[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thruster::setPosition(float* pos)
|
void Thruster::setPosition(float* pos)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) _pos[i] = pos[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) _pos[i] = pos[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thruster::getDirection(float* out)
|
void Thruster::getDirection(float* out)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) out[i] = _dir[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) out[i] = _dir[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thruster::setDirection(float* dir)
|
void Thruster::setDirection(float* dir)
|
||||||
|
@ -47,14 +51,15 @@ void Thruster::setMixture(float mixture)
|
||||||
|
|
||||||
void Thruster::setWind(float* wind)
|
void Thruster::setWind(float* wind)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) _wind[i] = wind[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) _wind[i] = wind[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thruster::setAir(float pressure, float temp)
|
void Thruster::setAir(float pressure, float temp)
|
||||||
{
|
{
|
||||||
_P = pressure;
|
_pressure = pressure;
|
||||||
_T = temp;
|
_temp = temp;
|
||||||
_rho = _P / (287.1 * _T);
|
_rho = _pressure / (287.1 * _temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // namespace yasim
|
}; // namespace yasim
|
||||||
|
|
|
@ -50,8 +50,8 @@ protected:
|
||||||
float _mixture;
|
float _mixture;
|
||||||
|
|
||||||
float _wind[3];
|
float _wind[3];
|
||||||
float _P;
|
float _pressure;
|
||||||
float _T;
|
float _temp;
|
||||||
float _rho;
|
float _rho;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,8 @@ Wing::Wing()
|
||||||
|
|
||||||
Wing::~Wing()
|
Wing::~Wing()
|
||||||
{
|
{
|
||||||
for(int i=0; i<_surfs.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_surfs.size(); i++) {
|
||||||
SurfRec* s = (SurfRec*)_surfs.get(i);
|
SurfRec* s = (SurfRec*)_surfs.get(i);
|
||||||
delete s->surface;
|
delete s->surface;
|
||||||
delete s;
|
delete s;
|
||||||
|
@ -68,7 +69,8 @@ void Wing::setMirror(bool mirror)
|
||||||
|
|
||||||
void Wing::setBase(float* base)
|
void Wing::setBase(float* base)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) _base[i] = base[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) _base[i] = base[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wing::setLength(float length)
|
void Wing::setLength(float length)
|
||||||
|
@ -119,7 +121,8 @@ void Wing::setCamber(float camber)
|
||||||
void Wing::setIncidence(float incidence)
|
void Wing::setIncidence(float incidence)
|
||||||
{
|
{
|
||||||
_incidence = incidence;
|
_incidence = incidence;
|
||||||
for(int i=0; i<_surfs.size(); i++)
|
int i;
|
||||||
|
for(i=0; i<_surfs.size(); i++)
|
||||||
((SurfRec*)_surfs.get(i))->surface->setIncidence(incidence);
|
((SurfRec*)_surfs.get(i))->surface->setIncidence(incidence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +162,8 @@ void Wing::setFlap0(float lval, float rval)
|
||||||
{
|
{
|
||||||
lval = Math::clamp(lval, -1, 1);
|
lval = Math::clamp(lval, -1, 1);
|
||||||
rval = Math::clamp(rval, -1, 1);
|
rval = Math::clamp(rval, -1, 1);
|
||||||
for(int i=0; i<_flap0Surfs.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_flap0Surfs.size(); i++) {
|
||||||
((Surface*)_flap0Surfs.get(i))->setFlap(lval);
|
((Surface*)_flap0Surfs.get(i))->setFlap(lval);
|
||||||
if(_mirror) ((Surface*)_flap0Surfs.get(++i))->setFlap(rval);
|
if(_mirror) ((Surface*)_flap0Surfs.get(++i))->setFlap(rval);
|
||||||
}
|
}
|
||||||
|
@ -169,7 +173,8 @@ void Wing::setFlap1(float lval, float rval)
|
||||||
{
|
{
|
||||||
lval = Math::clamp(lval, -1, 1);
|
lval = Math::clamp(lval, -1, 1);
|
||||||
rval = Math::clamp(rval, -1, 1);
|
rval = Math::clamp(rval, -1, 1);
|
||||||
for(int i=0; i<_flap1Surfs.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_flap1Surfs.size(); i++) {
|
||||||
((Surface*)_flap1Surfs.get(i))->setFlap(lval);
|
((Surface*)_flap1Surfs.get(i))->setFlap(lval);
|
||||||
if(_mirror) ((Surface*)_flap1Surfs.get(++i))->setFlap(rval);
|
if(_mirror) ((Surface*)_flap1Surfs.get(++i))->setFlap(rval);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +184,8 @@ void Wing::setSpoiler(float lval, float rval)
|
||||||
{
|
{
|
||||||
lval = Math::clamp(lval, 0, 1);
|
lval = Math::clamp(lval, 0, 1);
|
||||||
rval = Math::clamp(rval, 0, 1);
|
rval = Math::clamp(rval, 0, 1);
|
||||||
for(int i=0; i<_spoilerSurfs.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_spoilerSurfs.size(); i++) {
|
||||||
((Surface*)_spoilerSurfs.get(i))->setSpoiler(lval);
|
((Surface*)_spoilerSurfs.get(i))->setSpoiler(lval);
|
||||||
if(_mirror) ((Surface*)_spoilerSurfs.get(++i))->setSpoiler(rval);
|
if(_mirror) ((Surface*)_spoilerSurfs.get(++i))->setSpoiler(rval);
|
||||||
}
|
}
|
||||||
|
@ -188,13 +194,15 @@ void Wing::setSpoiler(float lval, float rval)
|
||||||
void Wing::setSlat(float val)
|
void Wing::setSlat(float val)
|
||||||
{
|
{
|
||||||
val = Math::clamp(val, 0, 1);
|
val = Math::clamp(val, 0, 1);
|
||||||
for(int i=0; i<_slatSurfs.size(); i++)
|
int i;
|
||||||
|
for(i=0; i<_slatSurfs.size(); i++)
|
||||||
((Surface*)_slatSurfs.get(i))->setSlat(val);
|
((Surface*)_slatSurfs.get(i))->setSlat(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Wing::getGroundEffect(float* posOut)
|
float Wing::getGroundEffect(float* posOut)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++) posOut[i] = _base[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) posOut[i] = _base[i];
|
||||||
float span = _length * Math::cos(_sweep) * Math::cos(_dihedral);
|
float span = _length * Math::cos(_sweep) * Math::cos(_dihedral);
|
||||||
span = 2*(span + Math::abs(_base[2]));
|
span = 2*(span + Math::abs(_base[2]));
|
||||||
return span;
|
return span;
|
||||||
|
@ -215,10 +223,12 @@ void Wing::compile()
|
||||||
bounds[6] = _slatStart; bounds[7] = _slatEnd;
|
bounds[6] = _slatStart; bounds[7] = _slatEnd;
|
||||||
|
|
||||||
// Sort in increasing order
|
// Sort in increasing order
|
||||||
for(int i=0; i<8; i++) {
|
int i;
|
||||||
|
for(i=0; i<8; i++) {
|
||||||
int minIdx = i;
|
int minIdx = i;
|
||||||
float minVal = bounds[i];
|
float minVal = bounds[i];
|
||||||
for(int j=i+1; j<8; j++) {
|
int j;
|
||||||
|
for(j=i+1; j<8; j++) {
|
||||||
if(bounds[j] < minVal) {
|
if(bounds[j] < minVal) {
|
||||||
minIdx = j;
|
minIdx = j;
|
||||||
minVal = bounds[j];
|
minVal = bounds[j];
|
||||||
|
@ -231,7 +241,7 @@ void Wing::compile()
|
||||||
// Uniqify
|
// Uniqify
|
||||||
float last = bounds[0];
|
float last = bounds[0];
|
||||||
int nbounds = 1;
|
int nbounds = 1;
|
||||||
for(int i=1; i<8; i++) {
|
for(i=1; i<8; i++) {
|
||||||
if(bounds[i] != last)
|
if(bounds[i] != last)
|
||||||
bounds[nbounds++] = bounds[i];
|
bounds[nbounds++] = bounds[i];
|
||||||
last = bounds[i];
|
last = bounds[i];
|
||||||
|
@ -270,19 +280,20 @@ void Wing::compile()
|
||||||
|
|
||||||
if(_mirror) {
|
if(_mirror) {
|
||||||
// Derive the right side orientation matrix from this one.
|
// Derive the right side orientation matrix from this one.
|
||||||
for(int i=0; i<9; i++) rightOrient[i] = orient[i];
|
int i;
|
||||||
|
for(i=0; i<9; i++) rightOrient[i] = orient[i];
|
||||||
|
|
||||||
// Negate all Y coordinates, this gets us a valid basis, but
|
// Negate all Y coordinates, this gets us a valid basis, but
|
||||||
// it's left handed! So...
|
// it's left handed! So...
|
||||||
for(int i=1; i<9; i+=3) rightOrient[i] = -rightOrient[i];
|
for(i=1; i<9; i+=3) rightOrient[i] = -rightOrient[i];
|
||||||
|
|
||||||
// Change the direction of the Y axis to get back to a
|
// Change the direction of the Y axis to get back to a
|
||||||
// right-handed system.
|
// right-handed system.
|
||||||
for(int i=3; i<6; i++) rightOrient[i] = -rightOrient[i];
|
for(i=3; i<6; i++) rightOrient[i] = -rightOrient[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now go through each boundary and make segments
|
// Now go through each boundary and make segments
|
||||||
for(int i=0; i<(nbounds-1); i++) {
|
for(i=0; i<(nbounds-1); i++) {
|
||||||
float start = bounds[i];
|
float start = bounds[i];
|
||||||
float end = bounds[i+1];
|
float end = bounds[i+1];
|
||||||
float mid = (start+end)/2;
|
float mid = (start+end)/2;
|
||||||
|
@ -299,7 +310,8 @@ void Wing::compile()
|
||||||
int nSegs = (int)Math::ceil((end-start)/segLen);
|
int nSegs = (int)Math::ceil((end-start)/segLen);
|
||||||
float segWid = _length * (end - start)/nSegs;
|
float segWid = _length * (end - start)/nSegs;
|
||||||
|
|
||||||
for(int j=0; j<nSegs; j++) {
|
int j;
|
||||||
|
for(j=0; j<nSegs; j++) {
|
||||||
float frac = start + (j+0.5) * (end-start)/nSegs;
|
float frac = start + (j+0.5) * (end-start)/nSegs;
|
||||||
float pos[3];
|
float pos[3];
|
||||||
interp(root, tip, frac, pos);
|
interp(root, tip, frac, pos);
|
||||||
|
@ -337,7 +349,8 @@ float Wing::getDragScale()
|
||||||
void Wing::setDragScale(float scale)
|
void Wing::setDragScale(float scale)
|
||||||
{
|
{
|
||||||
_dragScale = scale;
|
_dragScale = scale;
|
||||||
for(int i=0; i<_surfs.size(); i++) {
|
int i;
|
||||||
|
for(i=0; i<_surfs.size(); i++) {
|
||||||
SurfRec* s = (SurfRec*)_surfs.get(i);
|
SurfRec* s = (SurfRec*)_surfs.get(i);
|
||||||
s->surface->setTotalDrag(scale * s->weight);
|
s->surface->setTotalDrag(scale * s->weight);
|
||||||
}
|
}
|
||||||
|
@ -346,7 +359,8 @@ void Wing::setDragScale(float scale)
|
||||||
void Wing::setLiftRatio(float ratio)
|
void Wing::setLiftRatio(float ratio)
|
||||||
{
|
{
|
||||||
_liftRatio = ratio;
|
_liftRatio = ratio;
|
||||||
for(int i=0; i<_surfs.size(); i++)
|
int i;
|
||||||
|
for(i=0; i<_surfs.size(); i++)
|
||||||
((SurfRec*)_surfs.get(i))->surface->setZDrag(ratio);
|
((SurfRec*)_surfs.get(i))->surface->setZDrag(ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,7 +400,8 @@ Surface* Wing::newSurface(float* pos, float* orient, float chord,
|
||||||
// The "reverse" stalls are unmeasurable junk. Just use 13deg and
|
// The "reverse" stalls are unmeasurable junk. Just use 13deg and
|
||||||
// "sharp".
|
// "sharp".
|
||||||
s->setStallPeak(1, 1);
|
s->setStallPeak(1, 1);
|
||||||
for(int i=2; i<4; i++) {
|
int i;
|
||||||
|
for(i=2; i<4; i++) {
|
||||||
s->setStall(i, 0.2267);
|
s->setStall(i, 0.2267);
|
||||||
s->setStallWidth(i, 1);
|
s->setStallWidth(i, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,16 +16,20 @@
|
||||||
#include "Glue.hpp"
|
#include "Glue.hpp"
|
||||||
#include "Gear.hpp"
|
#include "Gear.hpp"
|
||||||
#include "PropEngine.hpp"
|
#include "PropEngine.hpp"
|
||||||
|
#include "PistonEngine.hpp"
|
||||||
|
|
||||||
#include "YASim.hxx"
|
#include "YASim.hxx"
|
||||||
|
|
||||||
using namespace yasim;
|
using namespace yasim;
|
||||||
|
|
||||||
static const float RAD2DEG = 180/3.14159265358979323846;
|
static const float RAD2DEG = 180/3.14159265358979323846;
|
||||||
|
static const float RAD2RPM = 9.54929658551;
|
||||||
static const float M2FT = 3.2808399;
|
static const float M2FT = 3.2808399;
|
||||||
static const float FT2M = 0.3048;
|
static const float FT2M = 0.3048;
|
||||||
static const float MPS2KTS = 3600.0/1852.0;
|
static const float MPS2KTS = 3600.0/1852.0;
|
||||||
static const float CM2GALS = 264.172037284; // gallons/cubic meter
|
static const float CM2GALS = 264.172037284; // gallons/cubic meter
|
||||||
|
static const float KG2LBS = 2.20462262185;
|
||||||
|
static const float W2HP = 1.3416e-3;
|
||||||
|
|
||||||
void YASim::printDEBUG()
|
void YASim::printDEBUG()
|
||||||
{
|
{
|
||||||
|
@ -114,9 +118,32 @@ void YASim::init()
|
||||||
|
|
||||||
_fdm->init();
|
_fdm->init();
|
||||||
|
|
||||||
|
// Create some FG{Eng|Gear}Interface objects
|
||||||
|
int i;
|
||||||
|
for(i=0; i<a->numGear(); i++) {
|
||||||
|
Gear* g = a->getGear(i);
|
||||||
|
FGGearInterface fgg;
|
||||||
|
float pos[3];
|
||||||
|
g->getPosition(pos);
|
||||||
|
fgg.SetX(pos[0]); fgg.SetY(-pos[1]); fgg.SetZ(-pos[2]);
|
||||||
|
add_gear_unit(fgg);
|
||||||
|
}
|
||||||
|
for(i=0; i<m->numThrusters(); i++) {
|
||||||
|
FGEngInterface fge;
|
||||||
|
add_engine(fge);
|
||||||
|
|
||||||
|
// Sanify the initial input conditions
|
||||||
|
char buf[64];
|
||||||
|
sprintf(buf, "/controls/throttle[%d]", i); fgSetFloat(buf, 0);
|
||||||
|
sprintf(buf, "/controls/mixture[%d]", i); fgSetFloat(buf, 1);
|
||||||
|
sprintf(buf, "/controls/propeller-pitch[%d]", i); fgSetFloat(buf, 1);
|
||||||
|
sprintf(buf, "/controls/afterburner[%d]", i); fgSetFloat(buf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Lift the plane up so the gear clear the ground
|
// Lift the plane up so the gear clear the ground
|
||||||
float minGearZ = 1e18;
|
float minGearZ = 1e18;
|
||||||
for(int i=0; i<a->numGear(); i++) {
|
for(i=0; i<a->numGear(); i++) {
|
||||||
Gear* g = a->getGear(i);
|
Gear* g = a->getGear(i);
|
||||||
float pos[3];
|
float pos[3];
|
||||||
g->getPosition(pos);
|
g->getPosition(pos);
|
||||||
|
@ -142,7 +169,8 @@ void YASim::init()
|
||||||
|
|
||||||
bool YASim::update(int iterations)
|
bool YASim::update(int iterations)
|
||||||
{
|
{
|
||||||
for(int i=0; i<iterations; i++) {
|
int i;
|
||||||
|
for(i=0; i<iterations; i++) {
|
||||||
// Remember, update only every 4th call
|
// Remember, update only every 4th call
|
||||||
_updateCount++;
|
_updateCount++;
|
||||||
if(_updateCount >= 4) {
|
if(_updateCount >= 4) {
|
||||||
|
@ -214,7 +242,8 @@ void YASim::copyToYASim(bool copyState)
|
||||||
double xyz[3], gplane[3]; float up[3];
|
double xyz[3], gplane[3]; float up[3];
|
||||||
Glue::geod2xyz(lat, lon, ground, xyz);
|
Glue::geod2xyz(lat, lon, ground, xyz);
|
||||||
Glue::geodUp(xyz, up); // FIXME, needless reverse computation...
|
Glue::geodUp(xyz, up); // FIXME, needless reverse computation...
|
||||||
for(int i=0; i<3; i++) gplane[i] = up[i];
|
int i;
|
||||||
|
for(i=0; i<3; i++) gplane[i] = up[i];
|
||||||
double rad = gplane[0]*xyz[0] + gplane[1]*xyz[1] + gplane[2]*xyz[2];
|
double rad = gplane[0]*xyz[0] + gplane[1]*xyz[1] + gplane[2]*xyz[2];
|
||||||
model->setGroundPlane(gplane, rad);
|
model->setGroundPlane(gplane, rad);
|
||||||
|
|
||||||
|
@ -269,7 +298,8 @@ void YASim::copyToYASim(bool copyState)
|
||||||
// _set_Static_temperature
|
// _set_Static_temperature
|
||||||
void YASim::copyFromYASim()
|
void YASim::copyFromYASim()
|
||||||
{
|
{
|
||||||
Model* model = _fdm->getAirplane()->getModel();
|
Airplane* airplane = _fdm->getAirplane();
|
||||||
|
Model* model = airplane->getModel();
|
||||||
State* s = model->getState();
|
State* s = model->getState();
|
||||||
|
|
||||||
// position
|
// position
|
||||||
|
@ -350,4 +380,43 @@ void YASim::copyFromYASim()
|
||||||
|
|
||||||
Glue::calcEulerRates(s, &roll, &pitch, &hdg);
|
Glue::calcEulerRates(s, &roll, &pitch, &hdg);
|
||||||
_set_Euler_Rates(roll, pitch, hdg);
|
_set_Euler_Rates(roll, pitch, hdg);
|
||||||
|
|
||||||
|
// Fill out our engine and gear objects
|
||||||
|
int i;
|
||||||
|
for(i=0; i<get_num_gear(); i++) {
|
||||||
|
FGGearInterface* fgg = get_gear_unit(i);
|
||||||
|
Gear* g = airplane->getGear(i);
|
||||||
|
if(g->getBrake() != 0)
|
||||||
|
fgg->SetBrake(true);
|
||||||
|
if(g->getCompressFraction() != 0)
|
||||||
|
fgg->SetWoW(true);
|
||||||
|
fgg->SetPosition(g->getExtension());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<get_num_engines(); i++) {
|
||||||
|
FGEngInterface* fge = get_engine(i);
|
||||||
|
Thruster* t = model->getThruster(i);
|
||||||
|
|
||||||
|
fge->set_Running_Flag(true);
|
||||||
|
|
||||||
|
// Note: assumes all tanks have the same fuel density!
|
||||||
|
fge->set_Fuel_Flow(CM2GALS * t->getFuelFlow()
|
||||||
|
/ airplane->getFuelDensity(0));
|
||||||
|
|
||||||
|
float tmp[3];
|
||||||
|
t->getThrust(tmp);
|
||||||
|
fge->set_prop_thrust(Math::mag3(tmp) * KG2LBS / 9.8);
|
||||||
|
|
||||||
|
PropEngine* pe = t->getPropEngine();
|
||||||
|
if(pe) {
|
||||||
|
fge->set_RPM(pe->getOmega() * RAD2RPM);
|
||||||
|
|
||||||
|
pe->getTorque(tmp);
|
||||||
|
float power = Math::mag3(tmp) * pe->getOmega();
|
||||||
|
float maxPower = pe->getPistonEngine()->getPower();
|
||||||
|
|
||||||
|
fge->set_MaxHP(maxPower * W2HP);
|
||||||
|
fge->set_Percentage_Power(100 * power/maxPower);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue