YASim variable and method name clarification in class Surface
This commit is contained in:
parent
f7c5d2b1f9
commit
7c55aa2c4a
5 changed files with 84 additions and 68 deletions
|
@ -133,9 +133,9 @@ void Airplane::updateGearState()
|
|||
GearRec* gr = (GearRec*)_gears.get(i);
|
||||
float ext = gr->gear->getExtension();
|
||||
|
||||
gr->surf->setXDrag(ext);
|
||||
gr->surf->setDragCoefficient(ext);
|
||||
gr->surf->setYDrag(ext);
|
||||
gr->surf->setZDrag(ext);
|
||||
gr->surf->setLiftCoefficient(ext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,13 +271,13 @@ void Airplane::setWeight(int handle, float mass)
|
|||
// Kill the aerodynamic drag if the mass is exactly zero. This is
|
||||
// how we simulate droppable stores.
|
||||
if(mass == 0) {
|
||||
wr->surf->setXDrag(0);
|
||||
wr->surf->setDragCoefficient(0);
|
||||
wr->surf->setYDrag(0);
|
||||
wr->surf->setZDrag(0);
|
||||
wr->surf->setLiftCoefficient(0);
|
||||
} else {
|
||||
wr->surf->setXDrag(1);
|
||||
wr->surf->setDragCoefficient(1);
|
||||
wr->surf->setYDrag(1);
|
||||
wr->surf->setZDrag(1);
|
||||
wr->surf->setLiftCoefficient(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,10 +408,10 @@ float Airplane::compileFuselage(Fuselage* f)
|
|||
// Make a Surface too
|
||||
Surface* s = new Surface(this, pos, dragCoefficient);
|
||||
if( isVersionOrNewer( YASIM_VERSION_32 ) ) {
|
||||
s->setXDrag(f->_cx);
|
||||
s->setDragCoefficient(f->_cx);
|
||||
}
|
||||
s->setYDrag(sideDrag*f->_cy);
|
||||
s->setZDrag(sideDrag*f->_cz);
|
||||
s->setLiftCoefficient(sideDrag*f->_cz);
|
||||
s->setInducedDrag(f->_idrag);
|
||||
|
||||
// FIXME: fails for fuselages aligned along the Y axis
|
||||
|
@ -512,38 +512,38 @@ void Airplane::compile()
|
|||
// The Wing objects
|
||||
if (_wing)
|
||||
{
|
||||
if (baseN != 0) {
|
||||
_wingsN = baseN->getChild("wing", 0, true);
|
||||
_wing->setPropertyNode(_wingsN);
|
||||
}
|
||||
aeroWgt += compileWing(_wing);
|
||||
|
||||
// convert % to absolute x coordinates
|
||||
_cgDesiredFront = _wing->getMACx() - _wing->getMACLength()*_cgDesiredMin;
|
||||
_cgDesiredAft = _wing->getMACx() - _wing->getMACLength()*_cgDesiredMax;
|
||||
if (baseN != 0) {
|
||||
SGPropertyNode_ptr n = fgGetNode("/fdm/yasim/model", true);
|
||||
n->getNode("cg-x-range-front", true)->setFloatValue(_cgDesiredFront);
|
||||
n->getNode("cg-x-range-aft", true)->setFloatValue(_cgDesiredAft);
|
||||
}
|
||||
if (baseN != 0) {
|
||||
_wingsN = baseN->getChild("wing", 0, true);
|
||||
_wing->setPropertyNode(_wingsN);
|
||||
}
|
||||
aeroWgt += compileWing(_wing);
|
||||
|
||||
// convert % to absolute x coordinates
|
||||
_cgDesiredFront = _wing->getMACx() - _wing->getMACLength()*_cgDesiredMin;
|
||||
_cgDesiredAft = _wing->getMACx() - _wing->getMACLength()*_cgDesiredMax;
|
||||
if (baseN != 0) {
|
||||
SGPropertyNode_ptr n = fgGetNode("/fdm/yasim/model", true);
|
||||
n->getNode("cg-x-range-front", true)->setFloatValue(_cgDesiredFront);
|
||||
n->getNode("cg-x-range-aft", true)->setFloatValue(_cgDesiredAft);
|
||||
}
|
||||
}
|
||||
if (_tail)
|
||||
{
|
||||
if (baseN != 0) {
|
||||
_wingsN = baseN->getChild("tail", 0, true);
|
||||
_tail->setPropertyNode(_wingsN);
|
||||
}
|
||||
aeroWgt += compileWing(_tail);
|
||||
if (baseN != 0) {
|
||||
_wingsN = baseN->getChild("tail", 0, true);
|
||||
_tail->setPropertyNode(_wingsN);
|
||||
}
|
||||
aeroWgt += compileWing(_tail);
|
||||
}
|
||||
int i;
|
||||
for(i=0; i<_vstabs.size(); i++)
|
||||
{
|
||||
Wing* vs = (Wing*)_vstabs.get(i);
|
||||
if (baseN != 0) {
|
||||
_wingsN = baseN->getChild("stab", i, true);
|
||||
vs->setPropertyNode(_wingsN);
|
||||
}
|
||||
aeroWgt += compileWing(vs);
|
||||
Wing* vs = (Wing*)_vstabs.get(i);
|
||||
if (baseN != 0) {
|
||||
_wingsN = baseN->getChild("stab", i, true);
|
||||
vs->setPropertyNode(_wingsN);
|
||||
}
|
||||
aeroWgt += compileWing(vs);
|
||||
}
|
||||
|
||||
// The fuselage(s)
|
||||
|
@ -557,9 +557,13 @@ void Airplane::compile()
|
|||
|
||||
// Rescale to the specified empty weight
|
||||
float wscale = (_emptyWeight-nonAeroWgt)/aeroWgt;
|
||||
for(i=firstMass; i<body->numMasses(); i++)
|
||||
for(i=firstMass; i<body->numMasses(); i++) {
|
||||
body->setMass(i, body->getMass(i)*wscale);
|
||||
|
||||
}
|
||||
if (_wingsN != nullptr) {
|
||||
float w = _wingsN->getNode("weight", true)->getFloatValue();
|
||||
_wingsN->getNode("mass", true)->setFloatValue(w * wscale);
|
||||
}
|
||||
// Add the thruster masses
|
||||
for(i=0; i<_thrusters.size(); i++) {
|
||||
ThrustRec* t = (ThrustRec*)_thrusters.get(i);
|
||||
|
@ -801,21 +805,21 @@ void Airplane::applyDragFactor(float factor)
|
|||
// it won't be affected by the streamlining done to reduce
|
||||
// longitudinal drag. So the solver should only adjust the
|
||||
// fuselage's longitudinal (X axis) drag coefficient.
|
||||
s->setXDrag(s->getXDrag() * applied);
|
||||
s->setDragCoefficient(s->getDragCoefficient() * applied);
|
||||
} else {
|
||||
// Originally YASim applied the drag factor to all axes
|
||||
// for Fuselage Surfaces.
|
||||
s->mulDragCoefficient(applied);
|
||||
s->mulTotalForceCoefficient(applied);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i=0; i<_weights.size(); i++) {
|
||||
WeightRec* wr = (WeightRec*)_weights.get(i);
|
||||
wr->surf->mulDragCoefficient(applied);
|
||||
wr->surf->mulTotalForceCoefficient(applied);
|
||||
}
|
||||
for(i=0; i<_gears.size(); i++) {
|
||||
GearRec* gr = (GearRec*)_gears.get(i);
|
||||
gr->surf->mulDragCoefficient(applied);
|
||||
gr->surf->mulTotalForceCoefficient(applied);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <Main/fg_props.hxx>
|
||||
#include "yasim-common.hpp"
|
||||
#include "Math.hpp"
|
||||
#include "Surface.hpp"
|
||||
|
||||
|
@ -119,23 +120,24 @@ void Surface::setSpoilerPos(float pos)
|
|||
|
||||
// Calculate the aerodynamic force given a wind vector v (in the
|
||||
// aircraft's "local" coordinates) and an air density rho. Returns a
|
||||
// torque about the Y axis, too.
|
||||
// torque about the Y axis ("pitch"), too.
|
||||
void Surface::calcForce(const float* v, const float rho, float* out, float* torque)
|
||||
{
|
||||
// initialize outputs to zero
|
||||
Math::zero3(out);
|
||||
Math::zero3(torque);
|
||||
|
||||
// Split v into magnitude and direction:
|
||||
float vel = Math::mag3(v);
|
||||
|
||||
// Zero velocity means zero force by definition (also prevents div0).
|
||||
if(vel == 0) {
|
||||
int i;
|
||||
for(i=0; i<3; i++) out[i] = torque[i] = 0;
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
// special case this so the logic below doesn't produce a non-zero
|
||||
// force; should probably have a "no force" flag instead...
|
||||
if(_cx == 0. && _cy == 0. && _cz == 0.) {
|
||||
for(int i=0; i<3; i++) out[i] = torque[i] = 0.;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -145,10 +147,10 @@ void Surface::calcForce(const float* v, const float rho, float* out, float* torq
|
|||
|
||||
// "Rotate" by the incidence angle. Assume small angles, so we
|
||||
// need to diddle only the Z component, X is relatively unchanged
|
||||
// by small rotations.
|
||||
// by small rotations. sin(a) ~ a, cos(a) ~ 1 for small a
|
||||
float incidence = _incidence + _twist;
|
||||
out[2] += incidence * out[0]; // z' = z + incidence * x
|
||||
|
||||
|
||||
// Hold onto the local wind vector so we can multiply the induced
|
||||
// drag at the end.
|
||||
float lwind[3];
|
||||
|
@ -190,9 +192,9 @@ void Surface::calcForce(const float* v, const float rho, float* out, float* torq
|
|||
// roughly parallel with Z, the small-angle approximation
|
||||
// must change its X component.
|
||||
if( _version->isVersionOrNewer( Version::YASIM_VERSION_32 )) {
|
||||
out[0] += incidence * out[2];
|
||||
out[0] += incidence * out[2];
|
||||
} else {
|
||||
out[2] -= incidence * out[0];
|
||||
out[2] -= incidence * out[0];
|
||||
}
|
||||
|
||||
// Convert back to external coordinates
|
||||
|
|
|
@ -59,17 +59,18 @@ public:
|
|||
// The offset from base incidence for this surface.
|
||||
void setTwist(float angle) { _twist = angle; }
|
||||
|
||||
void setDragCoefficient(float c0) { _c0 = c0; }
|
||||
void mulDragCoefficient(float factor) { _c0 *= factor; }
|
||||
float getDragCoefficient() const { return _c0; }
|
||||
void setTotalForceCoefficient(float c0) { _c0 = c0; }
|
||||
void mulTotalForceCoefficient(float factor) { _c0 *= factor; }
|
||||
float getTotalForceCoefficient() const { return _c0; }
|
||||
|
||||
void setXDrag(float cx) { _cx = cx; }
|
||||
void setYDrag(float cy) { _cy = cy; }
|
||||
void setZDrag(float cz) { _cz = cz; }
|
||||
float getXDrag() const { return _cx; }
|
||||
void setDragCoefficient(float cx) { _cx = cx; }
|
||||
float getDragCoefficient() const { return _cx; }
|
||||
void setYDrag(float cy) { _cy = cy; }
|
||||
void setLiftCoefficient(float cz) { _cz = cz; }
|
||||
float getLiftCoefficient() const { return _cz; }
|
||||
|
||||
// zero-alpha Z drag ("camber") specified as a fraction of cz
|
||||
void setBaseZDrag(float cz0) { _cz0 = cz0; }
|
||||
void setZeroAlphaLift(float cz0) { _cz0 = cz0; }
|
||||
|
||||
// i: 0 == forward, 1 == backwards
|
||||
void setStallPeak(int i, float peak) { _peaks[i] = peak; }
|
||||
|
|
|
@ -379,7 +379,7 @@ void Wing::WingSection::setDragCoefficient(float scale)
|
|||
_dragScale = scale;
|
||||
for(int i=0; i<_surfs.size(); i++) {
|
||||
SurfRec* s = (SurfRec*)_surfs.get(i);
|
||||
s->surface->setDragCoefficient(scale * s->weight);
|
||||
s->surface->setTotalForceCoefficient(scale * s->weight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,7 +392,7 @@ void Wing::WingSection::setLiftRatio(float ratio)
|
|||
{
|
||||
_liftRatio = ratio;
|
||||
for(int i=0; i<_surfs.size(); i++)
|
||||
((SurfRec*)_surfs.get(i))->surface->setZDrag(ratio);
|
||||
((SurfRec*)_surfs.get(i))->surface->setLiftCoefficient(ratio);
|
||||
}
|
||||
|
||||
void Wing::WingSection::multiplyLiftRatio(float factor)
|
||||
|
@ -408,7 +408,7 @@ void Wing::WingSection::newSurface(Version* _version, float* pos, float* orient,
|
|||
s->setChord(chord);
|
||||
|
||||
// Camber is expressed as a fraction of stall peak, so convert.
|
||||
s->setBaseZDrag(_camber*_stallParams.peak);
|
||||
s->setZeroAlphaLift(_camber*_stallParams.peak);
|
||||
|
||||
// The "main" (i.e. normal) stall angle
|
||||
float stallAoA = _stallParams.aoa - _stallParams.width/4;
|
||||
|
@ -498,7 +498,7 @@ void Wing::writeInfoToProptree()
|
|||
ws = (WingSection*)_sections.get(section);
|
||||
for (int surf=0; surf < ws->numSurfaces(); surf++) {
|
||||
Surface* s = ws->getSurface(surf);
|
||||
float drag = s->getDragCoefficient();
|
||||
float drag = s->getTotalForceCoefficient();
|
||||
dragSum += drag;
|
||||
|
||||
float mass = ws->getSurfaceWeight(surf);
|
||||
|
@ -510,9 +510,11 @@ void Wing::writeInfoToProptree()
|
|||
_wingN->getNode("drag", true)->setFloatValue(dragSum);
|
||||
}
|
||||
|
||||
// estimate a mass distibution and add masses to the model
|
||||
// they will be scaled to match total mass of aircraft later
|
||||
float Wing::updateModel(Model* model)
|
||||
{
|
||||
float wgt = 0;
|
||||
_weight = 0;
|
||||
WingSection* ws;
|
||||
for (int section=0; section < _sections.size(); section++) {
|
||||
ws = (WingSection*)_sections.get(section);
|
||||
|
@ -520,21 +522,26 @@ float Wing::updateModel(Model* model)
|
|||
Surface* s = ws->getSurface(surf);
|
||||
model->addSurface(s);
|
||||
|
||||
float mass = ws->getSurfaceWeight(surf);
|
||||
mass = mass * Math::sqrt(mass);
|
||||
wgt += mass;
|
||||
float weight = ws->getSurfaceWeight(surf);
|
||||
weight = weight * Math::sqrt(weight);
|
||||
_weight += weight;
|
||||
|
||||
float pos[3];
|
||||
s->getPosition(pos);
|
||||
int mid = model->getBody()->addMass(mass, pos, true);
|
||||
int mid = model->getBody()->addMass(weight, pos, true);
|
||||
if (_wingN != nullptr) {
|
||||
SGPropertyNode_ptr n = _wingN->getNode("surfaces", true)->getChild("surface", s->getID(), true);
|
||||
n->getNode("drag", true)->setFloatValue(s->getDragCoefficient());
|
||||
n->getNode("c0", true)->setFloatValue(s->getTotalForceCoefficient());
|
||||
n->getNode("cdrag", true)->setFloatValue(s->getDragCoefficient());
|
||||
n->getNode("clift", true)->setFloatValue(s->getLiftCoefficient());
|
||||
n->getNode("mass-id", true)->setIntValue(mid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return wgt;
|
||||
if (_wingN != nullptr) {
|
||||
_wingN->getNode("weight", true)->setFloatValue(_weight);
|
||||
}
|
||||
return _weight;
|
||||
}
|
||||
|
||||
}; // namespace yasim
|
||||
|
|
|
@ -49,6 +49,7 @@ class Wing {
|
|||
};
|
||||
|
||||
struct WingSection {
|
||||
int _id;
|
||||
Chord _rootChord;
|
||||
// length is distance from base to tip, not wing span
|
||||
float _length {0};
|
||||
|
@ -123,7 +124,9 @@ class Wing {
|
|||
float _aspectRatio {0};
|
||||
float _meanChord {0};
|
||||
float _incidence {0};
|
||||
float _weight {0};
|
||||
|
||||
//-- private methods
|
||||
Chord _float2chord(float* pos, float lenght = 0);
|
||||
void _chord2float(Chord c, float* pos);
|
||||
void interp(const float* v1, const float* v2, const float frac, float* out);
|
||||
|
@ -166,7 +169,6 @@ public:
|
|||
|
||||
void setPropertyNode(SGPropertyNode_ptr n) { _wingN = n; };
|
||||
float updateModel(Model* model);
|
||||
|
||||
};
|
||||
|
||||
}; // namespace yasim
|
||||
|
|
Loading…
Add table
Reference in a new issue