From f7c5d2b1f948384484c8484e07949a6242408bdf Mon Sep 17 00:00:00 2001 From: Henning Stahlke Date: Wed, 6 Dec 2017 20:26:41 +0100 Subject: [PATCH] YASIM refactoring class Surface and export more properties to proptree --- src/FDM/YASim/Airplane.cpp | 125 +++++++++++++++++-------------------- src/FDM/YASim/Surface.cpp | 63 +++++++++++++------ src/FDM/YASim/Surface.hpp | 9 +-- src/FDM/YASim/Wing.cpp | 4 +- 4 files changed, 109 insertions(+), 92 deletions(-) diff --git a/src/FDM/YASim/Airplane.cpp b/src/FDM/YASim/Airplane.cpp index 8a3fb9afd..56dfad66e 100644 --- a/src/FDM/YASim/Airplane.cpp +++ b/src/FDM/YASim/Airplane.cpp @@ -254,9 +254,7 @@ int Airplane::addWeight(float* pos, float size) WeightRec* wr = new WeightRec(); wr->handle = _model.getBody()->addMass(0, pos); - wr->surf = new Surface(this); - wr->surf->setPosition(pos); - wr->surf->setDragCoefficient(size*size); + wr->surf = new Surface(this, pos, size*size); _model.addSurface(wr->surf); _surfs.add(wr->surf); @@ -273,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->setYDrag(0); - wr->surf->setZDrag(0); + wr->surf->setXDrag(0); + wr->surf->setYDrag(0); + wr->surf->setZDrag(0); } else { - wr->surf->setXDrag(1); - wr->surf->setYDrag(1); - wr->surf->setZDrag(1); + wr->surf->setXDrag(1); + wr->surf->setYDrag(1); + wr->surf->setZDrag(1); } } @@ -347,7 +345,7 @@ float Airplane::compileFuselage(Fuselage* f) float len = Math::mag3(fwd); if (len == 0) { _failureMsg = "Zero length fuselage"; - return 0; + return 0; } float wid = f->width; int segs = (int)Math::ceil(len/wid); @@ -355,19 +353,18 @@ float Airplane::compileFuselage(Fuselage* f) int j; for(j=0; jmid) scale = f->taper+(1-f->taper) * (frac / f->mid); else { - if( isVersionOrNewer( YASIM_VERSION_32 ) ) { - // Correct calculation of width for fuselage taper. - scale = 1 - (1-f->taper) * (frac - f->mid) / (1 - f->mid); - } else { - // Original, incorrect calculation of width for fuselage taper. - scale = f->taper+(1-f->taper) * (frac - f->mid) / (1 - f->mid); - } - } + if( isVersionOrNewer( YASIM_VERSION_32 ) ) { + // Correct calculation of width for fuselage taper. + scale = 1 - (1-f->taper) * (frac - f->mid) / (1 - f->mid); + } else { + // Original, incorrect calculation of width for fuselage taper. + scale = f->taper+(1-f->taper) * (frac - f->mid) / (1 - f->mid); + } + } // Where are we? float pos[3]; @@ -379,44 +376,42 @@ float Airplane::compileFuselage(Fuselage* f) _model.getBody()->addMass(mass, pos, true); wgt += mass; + + // The following is the original YASim value for sideDrag. + // Originally YASim calculated the fuselage's lateral drag + // coefficient as (solver drag factor) * (len/wid). + // However, this greatly underestimates a fuselage's lateral drag. + float sideDrag = len/wid; + + if ( isVersionOrNewer( YASIM_VERSION_32 ) ) { + // New YASim assumes a fixed lateral drag coefficient of 0.5. + // This will not be multiplied by the solver drag factor, because + // that factor is tuned to match the drag in the direction of + // flight, which is completely independent of lateral drag. + // The value of 0.5 is only a ballpark estimate, roughly matching + // the side-on drag for a long cylinder at the higher Reynolds + // numbers typical for an aircraft's lateral drag. + // This fits if the fuselage is long and has a round cross section. + // For flat-sided fuselages, the value should be increased, up to + // a limit of around 2 for a long rectangular prism. + // For very short fuselages, in which the end effects are strong, + // the value should be reduced. + // Such adjustments can be made using the fuselage's "cy" and "cz" + // XML parameters: "cy" for the sides, "cz" for top and bottom. + sideDrag = 0.5; + } + float dragCoefficient = scale*segWgt*f->_cx; + if( isVersionOrNewer( YASIM_VERSION_32 ) ) { + dragCoefficient = scale*segWgt; + } + // Make a Surface too - Surface* s = new Surface(this); - s->setPosition(pos); - - // The following is the original YASim value for sideDrag. - // Originally YASim calculated the fuselage's lateral drag - // coefficient as (solver drag factor) * (len/wid). - // However, this greatly underestimates a fuselage's lateral drag. - float sideDrag = len/wid; - - if ( isVersionOrNewer( YASIM_VERSION_32 ) ) { - // New YASim assumes a fixed lateral drag coefficient of 0.5. - // This will not be multiplied by the solver drag factor, because - // that factor is tuned to match the drag in the direction of - // flight, which is completely independent of lateral drag. - // The value of 0.5 is only a ballpark estimate, roughly matching - // the side-on drag for a long cylinder at the higher Reynolds - // numbers typical for an aircraft's lateral drag. - // This fits if the fuselage is long and has a round cross section. - // For flat-sided fuselages, the value should be increased, up to - // a limit of around 2 for a long rectangular prism. - // For very short fuselages, in which the end effects are strong, - // the value should be reduced. - // Such adjustments can be made using the fuselage's "cy" and "cz" - // XML parameters: "cy" for the sides, "cz" for top and bottom. - sideDrag = 0.5; - } - - if( isVersionOrNewer( YASIM_VERSION_32 ) ) { - s->setXDrag(f->_cx); - } + Surface* s = new Surface(this, pos, dragCoefficient); + if( isVersionOrNewer( YASIM_VERSION_32 ) ) { + s->setXDrag(f->_cx); + } s->setYDrag(sideDrag*f->_cy); s->setZDrag(sideDrag*f->_cz); - if( isVersionOrNewer( YASIM_VERSION_32 ) ) { - s->setDragCoefficient(scale*segWgt); - } else { - s->setDragCoefficient(scale*segWgt*f->_cx); - } s->setInducedDrag(f->_idrag); // FIXME: fails for fuselages aligned along the Y axis @@ -425,8 +420,8 @@ float Airplane::compileFuselage(Fuselage* f) Math::unit3(fwd, x); y[0] = 0; y[1] = 1; y[2] = 0; Math::cross3(x, y, z); - Math::unit3(z, z); - Math::cross3(z, x, y); + Math::unit3(z, z); + Math::cross3(z, x, y); s->setOrientation(o); _model.addSurface(s); @@ -441,9 +436,6 @@ void Airplane::compileGear(GearRec* gr) { Gear* g = gr->gear; - // Make a Surface object for the aerodynamic behavior - Surface* s = new Surface(this); - gr->surf = s; // Put the surface at the half-way point on the gear strut, give // it a drag coefficient equal to a square of the same dimension @@ -456,8 +448,9 @@ void Airplane::compileGear(GearRec* gr) Math::mul3(0.5, cmp, cmp); Math::add3(pos, cmp, pos); - s->setPosition(pos); - s->setDragCoefficient(length*length); + // Make a Surface object for the aerodynamic behavior + Surface* s = new Surface(this, pos, length*length); + gr->surf = s; _model.addGear(g); _model.addSurface(s); @@ -812,17 +805,17 @@ void Airplane::applyDragFactor(float factor) } else { // Originally YASim applied the drag factor to all axes // for Fuselage Surfaces. - s->setDragCoefficient(s->getDragCoefficient() * applied); + s->mulDragCoefficient(applied); } } } for(i=0; i<_weights.size(); i++) { - WeightRec* wr = (WeightRec*)_weights.get(i); - wr->surf->setDragCoefficient(wr->surf->getDragCoefficient() * applied); + WeightRec* wr = (WeightRec*)_weights.get(i); + wr->surf->mulDragCoefficient(applied); } for(i=0; i<_gears.size(); i++) { - GearRec* gr = (GearRec*)_gears.get(i); - gr->surf->setDragCoefficient(gr->surf->getDragCoefficient() * applied); + GearRec* gr = (GearRec*)_gears.get(i); + gr->surf->mulDragCoefficient(applied); } } diff --git a/src/FDM/YASim/Surface.cpp b/src/FDM/YASim/Surface.cpp index ffb5723bf..e9284dc4d 100644 --- a/src/FDM/YASim/Surface.cpp +++ b/src/FDM/YASim/Surface.cpp @@ -1,11 +1,13 @@ #include
+#include "Math.hpp" #include "Surface.hpp" namespace yasim { int Surface::s_idGenerator = 0; -Surface::Surface( Version * version ) : - _version(version) +Surface::Surface(Version* version, float* pos, float dragCoefficient = 1 ) : + _version(version), + _c0(dragCoefficient) { _id = s_idGenerator++; @@ -13,36 +15,59 @@ Surface::Surface( Version * version ) : _orient[3] = 0; _orient[4] = 1; _orient[5] = 0; _orient[6] = 0; _orient[7] = 0; _orient[8] = 1; + Math::set3(pos, _pos); + _surfN = fgGetNode("/fdm/yasim/debug/surfaces", true); if (_surfN != 0) { - _surfN = _surfN->getChild("surface", _id, true); - _fxN = _surfN->getNode("f-x", true); - _fyN = _surfN->getNode("f-y", true); - _fzN = _surfN->getNode("f-z", true); - _fabsN = _surfN->getNode("f-abs", true); - _alphaN = _surfN->getNode("alpha", true); - _stallAlphaN = _surfN->getNode("stall-alpha", true); - _flapN = _surfN->getNode("flap-pos", true); - _slatN = _surfN->getNode("slat-pos", true); - _spoilerN = _surfN->getNode("spoiler-pos", true); + _surfN = _surfN->getChild("surface", _id, true); + _fxN = _surfN->getNode("f-x", true); + _fyN = _surfN->getNode("f-y", true); + _fzN = _surfN->getNode("f-z", true); + _fabsN = _surfN->getNode("f-abs", true); + _alphaN = _surfN->getNode("alpha", true); + _stallAlphaN = _surfN->getNode("stall-alpha", true); + _flapN = _surfN->getNode("flap-pos", true); + _slatN = _surfN->getNode("slat-pos", true); + _spoilerN = _surfN->getNode("spoiler-pos", true); + _surfN->getNode("pos-x", true)->setFloatValue(pos[0]); + _surfN->getNode("pos-y", true)->setFloatValue(pos[1]); + _surfN->getNode("pos-z", true)->setFloatValue(pos[2]); + _surfN->getNode("chord",true)->setFloatValue(0); + _surfN->getNode("axis-x", true)->setFloatValue(0); + _surfN->getNode("axis-y", true)->setFloatValue(0); + _surfN->getNode("axis-z", true)->setFloatValue(0); } } -void Surface::setPosition(const float* p) +void Surface::setPosition(const float* pos) { - int i; - for(i=0; i<3; i++) _pos[i] = p[i]; + Math::set3(pos, _pos); if (_surfN != 0) { - _surfN->getNode("pos-x", true)->setFloatValue(p[0]); - _surfN->getNode("pos-y", true)->setFloatValue(p[1]); - _surfN->getNode("pos-z", true)->setFloatValue(p[2]); + _surfN->getNode("pos-x", true)->setFloatValue(pos[0]); + _surfN->getNode("pos-y", true)->setFloatValue(pos[1]); + _surfN->getNode("pos-z", true)->setFloatValue(pos[2]); + } +} + +void Surface::setChord(float chord) +{ + _chord = chord; + if (_surfN != 0) { + _surfN->getNode("chord",true)->setFloatValue(_chord); } } void Surface::setOrientation(const float* o) { - for(int i=0; i<9; i++) _orient[i] = o[i]; + for(int i=0; i<9; i++) _orient[i] = o[i]; + if (_surfN) { + float xaxis[3] {-1,0,0}; + Math::tmul33(_orient,xaxis, xaxis); + _surfN->getNode("axis-x", true)->setFloatValue(xaxis[0]); + _surfN->getNode("axis-y", true)->setFloatValue(xaxis[1]); + _surfN->getNode("axis-z", true)->setFloatValue(xaxis[2]); + } } diff --git a/src/FDM/YASim/Surface.hpp b/src/FDM/YASim/Surface.hpp index 4d5538ce1..fc16bc501 100644 --- a/src/FDM/YASim/Surface.hpp +++ b/src/FDM/YASim/Surface.hpp @@ -16,7 +16,7 @@ class Surface int _id; //index for property tree public: - Surface( Version * version ); + Surface(Version * version, float* pos, float dragCoefficient); int getID() const { return _id; }; static void resetIDgen() { s_idGenerator = 0; }; @@ -25,8 +25,8 @@ public: void setPosition(const float* p); void getPosition(float* out) const { Math::set3(_pos, out); } - // Distance scale along the X axis - void setChord(float chord) { _chord = chord; } + // Distance scale along the X axis used for torque (pitch) calculation + void setChord(float chord); // Slats act to move the stall peak by the specified angle, and // increase drag by the multiplier specified. @@ -60,6 +60,7 @@ public: void setTwist(float angle) { _twist = angle; } void setDragCoefficient(float c0) { _c0 = c0; } + void mulDragCoefficient(float factor) { _c0 *= factor; } float getDragCoefficient() const { return _c0; } void setXDrag(float cx) { _cx = cx; } @@ -87,6 +88,7 @@ public: private: SGPropertyNode_ptr _surfN; + Version * _version; float stallFunc(float* v); float flapLift(float alpha); @@ -123,7 +125,6 @@ private: float _stallAlpha {0}; float _alpha {0}; - Version * _version; SGPropertyNode* _fxN; SGPropertyNode* _fyN; SGPropertyNode* _fzN; diff --git a/src/FDM/YASim/Wing.cpp b/src/FDM/YASim/Wing.cpp index 02757fa2f..3c9c8ffc4 100644 --- a/src/FDM/YASim/Wing.cpp +++ b/src/FDM/YASim/Wing.cpp @@ -402,9 +402,8 @@ void Wing::WingSection::multiplyLiftRatio(float factor) void Wing::WingSection::newSurface(Version* _version, float* pos, float* orient, float chord, bool hasFlap0, bool hasFlap1, bool hasSlat, bool hasSpoiler, float weight, float twist) { - Surface* s = new Surface(_version); + Surface* s = new Surface(_version, pos, weight); - s->setPosition(pos); s->setOrientation(orient); s->setChord(chord); @@ -457,7 +456,6 @@ void Wing::WingSection::newSurface(Version* _version, float* pos, float* orient, SurfRec *sr = new SurfRec(); sr->surface = s; sr->weight = weight; - s->setDragCoefficient(sr->weight); s->setTwist(twist); _surfs.add(sr); }