1
0
Fork 0

YASim-0.1.3 updates.

This commit is contained in:
curt 2001-12-10 23:13:54 +00:00
parent ec346bf0ef
commit 9f73588b31
9 changed files with 99 additions and 62 deletions

View file

@ -31,6 +31,10 @@ float Atmosphere::data[][4] = {{ 0, 288.20, 101325, 1.22500 },
{ 18000, 216.66, 7565, 0.12165 },
{ 18900, 216.66, 6570, 0.10564 }};
// Universal gas constant for air, in SI units. P = R * rho * T.
// P in pascals (N/m^2), rho is kg/m^3, T in kelvin.
const float R = 287.1;
float Atmosphere::getStdTemperature(float alt)
{
return getRecord(alt, 1);
@ -48,7 +52,9 @@ float Atmosphere::getStdDensity(float alt)
float Atmosphere::calcVEAS(float spd, float pressure, float temp)
{
return 0; //FIXME
static float rho0 = getStdDensity(0);
float densityRatio = calcDensity(pressure, temp) / rho0;
return spd * Math::sqrt(densityRatio);
}
float Atmosphere::calcVCAS(float spd, float pressure, float temp)
@ -84,13 +90,12 @@ float Atmosphere::calcVCAS(float spd, float pressure, float temp)
float Atmosphere::calcDensity(float pressure, float temp)
{
// P = rho*R*T, R == 287 kPa*m^3 per kg*kelvin for air
return pressure / (287 * temp);
return pressure / (R * temp);
}
float Atmosphere::calcMach(float spd, float temp)
{
return spd / Math::sqrt(1.4 * 287 * temp);
return spd / Math::sqrt(1.4 * R * temp);
}
float Atmosphere::getRecord(float alt, int recNum)

View file

@ -77,23 +77,10 @@ Airplane* FGFDM::getAirplane()
void FGFDM::init()
{
// We don't want to use these ties (we set the values ourselves,
// and this works only for the first piston engine anyway).
fgUntie("/engines/engine[0]/rpm");
fgUntie("/engines/engine[0]/egt-degf");
fgUntie("/engines/engine[0]/cht-degf");
fgUntie("/engines/engine[0]/oil-temperature-degf");
fgUntie("/engines/engine[0]/mp-osi");
fgUntie("/engines/engine[0]/fuel-flow-gph");
fgUntie("/engines/engine[0]/running");
fgUntie("/engines/engine[0]/cranking");
// We don't want to use these ties (we set the values ourselves)
fgUntie("/consumables/fuel/tank[0]/level-gal_us");
fgUntie("/consumables/fuel/tank[1]/level-gal_us");
// Set these to sane values. We don't support engine start yet.
fgSetBool("/engines/engine[0]/running", true);
fgSetBool("/engines/engine[0]/cranking", false);
// Allows the user to start with something other than full fuel
_airplane.setFuelFraction(fgGetFloat("/yasim/fuel-fraction", 1));

View file

@ -143,8 +143,11 @@ void Gear::calcForce(RigidBody* body, float* v, float* rot, float* ground)
// First off, make sure that the gear "tip" is below the ground.
// If it's not, there's no force.
float a = ground[3] - Math::dot3(_pos, ground);
if(a > 0)
if(a > 0) {
_wow = 0;
_frac = 0;
return;
}
// Now a is the distance from the tip to ground, so make b the
// distance from the base to ground. We can get the fraction
@ -169,11 +172,10 @@ void Gear::calcForce(RigidBody* body, float* v, float* rot, float* ground)
body->pointVelocity(_contact, rot, cv);
Math::add3(cv, v, cv);
// Finally, we can start adding up the forces. First the
// spring compression (note the clamping of _frac to 1):
// Finally, we can start adding up the forces. First the spring
// compression. (note the clamping of _frac to 1):
_frac = (_frac > 1) ? 1 : _frac;
float fmag = _frac*clen*_spring;
Math::mul3(fmag, cmpr, _force);
// Then the damping. Use the only the velocity into the ground
// (projection along "ground") projected along the compression
@ -183,10 +185,11 @@ void Gear::calcForce(RigidBody* body, float* v, float* rot, float* ground)
float damp = _damp * dv;
if(damp > fmag) damp = fmag; // can't pull the plane down!
if(damp < -fmag) damp = -fmag; // sanity
Math::mul3(-damp, cmpr, tmp);
Math::add3(_force, tmp, _force);
_wow = fmag - damp;
// The actual force applied is only the component perpendicular to
// the ground. Side forces come from velocity only.
_wow = (fmag - damp) * -Math::dot3(cmpr, ground);
Math::mul3(-_wow, ground, _force);
// Wheels are funky. Split the velocity along the ground plane
// into rolling and skidding components. Assuming small angles,

View file

@ -20,11 +20,6 @@ float Math::sqrt(float f)
return ::sqrt(f);
}
float Math::pow(float base, float exp)
{
return ::pow(base, exp);
}
float Math::ceil(float f)
{
return ::ceil(f);
@ -60,7 +55,7 @@ double Math::sqrt(double f)
return ::sqrt(f);
}
double Math::pow(double base, double exp)
float Math::pow(double base, double exp)
{
return ::pow(base, exp);
}

View file

@ -12,17 +12,18 @@ public:
// Simple wrappers around library routines
static float abs(float f);
static float sqrt(float f);
static float pow(float base, float exp);
static float ceil(float f);
static float sin(float f);
static float cos(float f);
static float tan(float f);
static float atan2(float y, float x);
// Takes two args and runs afoul of the Koenig rules.
static float pow(double base, double exp);
// double variants of the above
static double abs(double f);
static double sqrt(double f);
static double pow(double base, double exp);
static double ceil(double f);
static double sin(double f);
static double cos(double f);

View file

@ -47,6 +47,9 @@ Model::Model()
// Default value of 30 Hz
_integrator.setInterval(1.0/30.0);
_agl = 0;
_crashed = false;
}
Model::~Model()
@ -99,6 +102,21 @@ void Model::iterate()
_integrator.calcNewInterval();
}
bool Model::isCrashed()
{
return _crashed;
}
void Model::setCrashed(bool crashed)
{
_crashed = crashed;
}
float Model::getAGL()
{
return _agl;
}
State* Model::getState()
{
return _s;
@ -269,20 +287,27 @@ void Model::newState(State* s)
//printState(s);
// Some simple collision detection
float min = 1e8;
float ground[4], pos[3], cmpr[3];
ground[3] = localGround(s, ground);
int i;
for(i=0; i<_gears.size(); i++) {
Gear* g = (Gear*)_gears.get(i);
// Get the point of ground contact
g->getPosition(pos);
g->getCompression(cmpr);
Math::mul3(g->getCompressFraction(), cmpr, cmpr);
Math::add3(cmpr, pos, pos);
float dist = ground[3] - Math::dot3(pos, ground);
if(dist < 0) {
printf("CRASH: gear %d\n", i);
*(int*)0=0;
}
// Find the lowest one
if(dist < min)
min = dist;
}
_agl = min;
if(_agl < -1) // Allow for some integration slop
_crashed = true;
}
// Returns a unit "down" vector for the ground in out, and the

View file

@ -24,6 +24,9 @@ public:
State* getState();
void setState(State* s);
bool isCrashed();
void setCrashed(bool crashed);
float getAGL();
void iterate();
@ -81,6 +84,8 @@ private:
float _torque[3];
State* _s;
bool _crashed;
float _agl;
};
}; // namespace yasim

View file

@ -126,9 +126,6 @@ void PropEngine::integrate(float dt)
// needs to go away when the startup code gets written.
if(_omega < 52.3) _omega = 52.3;
// FIXME: Integrate the propeller governor here, when that gets
// implemented...
// Store the total angular momentum into _gyro
Math::mul3(_omega*_moment, _dir, _gyro);
@ -140,15 +137,25 @@ void PropEngine::integrate(float dt)
float tau = _moment < 0 ? engTorque : -engTorque;
Math::mul3(tau, _dir, _torque);
// Play with the variable propeller, but only if the propeller is
// vaguely stable alread (accelerating less than 100 rpm/s)
if(_variable && Math::abs(rotacc) < 20) {
float target = _minOmega + _advance*(_maxOmega-_minOmega);
float mod = 1.04;
if(target > _omega) mod = 1/mod;
float diff = Math::abs(target - _omega);
if(diff < 1) mod = 1 + (mod-1)*diff;
if(thrust < 0) mod = 1;
// Iterate the propeller governor, if we have one. Since engine
// torque is basically constant with RPM, we want to make the
// propeller torque at the target RPM equal to the engine by
// varying the pitch. Assume the the torque goes as the square of
// the RPM (roughly correct) and compute a "target" torque for the
// _current_ RPM. Seek to that. This is sort of a continuous
// Newton-Raphson, basically.
if(_variable) {
float targetOmega = _minOmega + _advance*(_maxOmega-_minOmega);
float ratio2 = (_omega*_omega)/(targetOmega*targetOmega);
float targetTorque = engTorque * ratio2;
float mod = propTorque < targetTorque ? 1.04 : (1/1.04);
// Convert to an acceleration here, so that big propellers
// don't seek faster than small ones.
float diff = Math::abs(propTorque - targetTorque) / _moment;
if(diff < 10) mod = 1 + (mod-1)*(0.1*diff);
_prop->modPitch(mod);
}
}

View file

@ -105,6 +105,8 @@ void YASim::init()
// Superclass hook
common_init();
m->setCrashed(false);
// Build a filename and parse it
SGPath f(globals->get_fg_root());
f.append("Aircraft-yasim");
@ -141,16 +143,19 @@ void YASim::init()
}
// Lift the plane up so the gear clear the ground
float minGearZ = 1e18;
for(i=0; i<a->numGear(); i++) {
Gear* g = a->getGear(i);
float pos[3];
g->getPosition(pos);
if(pos[2] < minGearZ)
minGearZ = pos[2];
// Are we at ground level? If so, lift the plane up so the gear
// clear the ground
if(get_Altitude() - get_Runway_altitude() < 50) {
float minGearZ = 1e18;
for(i=0; i<a->numGear(); i++) {
Gear* g = a->getGear(i);
float pos[3];
g->getPosition(pos);
if(pos[2] < minGearZ)
minGearZ = pos[2];
}
_set_Altitude(get_Runway_altitude() - minGearZ*M2FT);
}
_set_Altitude(get_Altitude() - minGearZ*M2FT);
// The pilot's eyepoint
float pilot[3];
@ -169,6 +174,10 @@ void YASim::init()
bool YASim::update(int iterations)
{
// If we're crashed, then we don't care
if(_fdm->getAirplane()->getModel()->isCrashed())
return true;
int i;
for(i=0; i<iterations; i++) {
// Remember, update only every 4th call
@ -310,10 +319,7 @@ void YASim::copyFromYASim()
// UNUSED
//_set_Geocentric_Position(Glue::geod2geocLat(lat), lon, alt*M2FT);
// FIXME: there's a normal vector available too, use it.
float groundMSL = scenery.get_cur_elev();
_set_Runway_altitude(groundMSL*M2FT);
_set_Altitude_AGL((alt - groundMSL)*M2FT);
_set_Altitude_AGL(model->getAGL() * M2FT);
// useful conversion matrix
float xyz2ned[9];
@ -390,6 +396,8 @@ void YASim::copyFromYASim()
fgg->SetBrake(true);
if(g->getCompressFraction() != 0)
fgg->SetWoW(true);
else
fgg->SetWoW(false);
fgg->SetPosition(g->getExtension());
}
@ -398,6 +406,7 @@ void YASim::copyFromYASim()
Thruster* t = model->getThruster(i);
fge->set_Running_Flag(true);
fge->set_Cranking_Flag(false);
// Note: assumes all tanks have the same fuel density!
fge->set_Fuel_Flow(CM2GALS * t->getFuelFlow()