1 #ifndef _WING_HPP 2 #define _WING_HPP 3 4 #include "yasim-common.hpp" 5 #include "Vector.hpp" 6 #include "Version.hpp" 7 #include "Math.hpp" 8 #include <simgear/props/props.hxx> 9 10 namespace yasim { 11 12 class Surface; 13 class Model; 14 15 struct FlapParams { 16 float start {0}; 17 float end {0}; 18 float lift {0}; 19 float drag {0}; 20 float aoa {0}; 21 }; 22 23 struct StallParams { 24 float aoa {0}; 25 float width {0}; 26 float peak {0}; 27 }; 28 29 // position and length of a chord line 30 struct Chord { 31 float x {0}; 32 float y {0}; 33 float z {0}; 34 float length {0}; 35 }; 36 37 enum WingFlaps { 38 WING_FLAP0, 39 WING_FLAP1, 40 WING_SPOILER, 41 WING_SLAT, 42 }; 43 44 enum FlowRegime { 45 FLOW_SUBSONIC, 46 FLOW_TRANSONIC 47 }; 48 49 class Wing { 50 SGPropertyNode_ptr _wingN {nullptr}; 51 52 struct SurfRec { 53 Surface* surface; 54 float weight; 55 }; 56 57 struct WingSection { 58 int _id; 59 /// length and midpoint (not leading edge!) of root chord 60 Chord _rootChord; 61 /// length is distance from base to tip, not wing span 62 float _length {0}; 63 float _taper {1}; 64 /// sweep of center line, not leading edge! 65 float _sweepAngleCenterLine {0}; 66 float _dihedral {0}; 67 float _twist {0}; 68 float _camber {0}; 69 float _inducedDrag {1}; 70 71 StallParams _stallParams; 72 73 ///fixed incidence of section as given in config XML 74 float _sectionIncidence {0}; 75 float _dragScale {1}; 76 float _liftRatio {1}; 77 78 FlapParams _flapParams[sizeof(WingFlaps)]; 79 80 // calculated from above 81 float _orient[9]; 82 float _rightOrient[9]; 83 Chord _tipChord; 84 /// std. mean chord 85 float _meanChord {0}; 86 /// mean aerodynamic chord, (x,y) leading edge! 87 Chord _mac; 88 float _sectionSpan {0}; 89 /// all SurfRec of this wing 90 Vector _surfs; 91 /// surfaces having a certain type of flap (flap, slat, spoiler) 92 Vector _flapSurfs[sizeof(WingFlaps)]; 93 94 void calculateGeometry(); 95 void calculateWingCoordinateSystem(); 96 void calculateTipChord(); 97 void calculateSpan(); 98 void calculateMAC(); 99 float calculateSweepAngleLeadingEdge(); 100 /// update surfaces of wing section to (incidence + _sectionIncidence) 101 /// e.g. for rotating hstab 102 void setIncidence(float incidence); 103 // parameters for stall curve setStallParamsyasim::Wing::WingSection104 void setStallParams(StallParams sp) { _stallParams = sp; } 105 106 // valid only after Wing::compile() was called getMACyasim::Wing::WingSection107 Chord getMAC() const { return _mac; }; getMACxyasim::Wing::WingSection108 float getMACx() const { return _mac.x; }; getMACyyasim::Wing::WingSection109 float getMACy() const { return _mac.y; }; getMACzyasim::Wing::WingSection110 float getMACz() const { return _mac.z; }; getAreayasim::Wing::WingSection111 float getArea() const { return _sectionSpan*_meanChord; }; 112 void setDragCoefficient(float scale); 113 void multiplyDragCoefficient(float factor); 114 // The ratio of force along the Z (lift) direction of each wing 115 // segment to that along the X (drag) direction. 116 void setLiftRatio(float ratio); 117 void multiplyLiftRatio(float factor); getLiftRatioyasim::Wing::WingSection118 float getLiftRatio() const { return _liftRatio; }; 119 120 void newSurface(Version* _version, float* pos, float* orient, float chord, 121 bool hasFlap0, bool hasFlap1, bool hasSlat, bool hasSpoiler, 122 float weight, float twist, FlowRegime flow, float mcrit); numSurfacesyasim::Wing::WingSection123 int numSurfaces() const { return _surfs.size(); } getSurfaceyasim::Wing::WingSection124 Surface* getSurface(int n) { return ((SurfRec*)_surfs.get(n))->surface; } getSurfaceWeightyasim::Wing::WingSection125 float getSurfaceWeight(int n) const { return ((SurfRec*)_surfs.get(n))->weight; } 126 }; //struct WingSection 127 128 //-- wing member variables -- 129 Version* _version; 130 bool _mirror {false}; 131 Vector _sections; 132 // midpoint (not leading edge!) of wing root chord 133 float _base[3] {0,0,0}; 134 // midpoint (not leading edge!) of wing tip 135 float _tip[3] {0,0,0}; 136 float _netSpan {0}; 137 float _wingSpan {0}; 138 float _area {0}; 139 float _aspectRatio {0}; 140 float _meanChord {0}; 141 Chord _mac; 142 float _taper {1.0f}; 143 float _incidence {0}; 144 float _incidenceMin {INCIDENCE_MIN}; 145 float _incidenceMax {INCIDENCE_MAX}; 146 float _weight {0}; 147 float _sweepLEMin {0}; 148 float _sweepLEMax {0}; 149 FlowRegime _flow {FLOW_SUBSONIC}; 150 float _Mcrit {1.0f}; 151 152 153 //-- private methods 154 //copy float[3] to chord x,y,z 155 static Chord _float2chord(float* pos, float lenght = 0); 156 //copy chord x,y,z to float[3] 157 static void _chord2float(Chord c, float* pos); 158 void _interp(const float* v1, const float* v2, const float frac, float* out); 159 void _writeInfoToProptree(); 160 Chord _weightedMeanChord(Chord a, float wa, Chord b, float wb); 161 162 public: 163 Wing(Version* ver, bool mirror); 164 ~Wing(); 165 166 int addWingSection(float* base, float chord, float wingLength, 167 float taper = 1, float sweep = 0, float dihedral = 0, float twist = 0, 168 float camber = 0, float idrag = 1, float incidence = 0); 169 170 void setFlapParams(int section, WingFlaps type, FlapParams fp); 171 void setSectionDrag(int section, float pdrag); 172 void setSectionStallParams(int section, StallParams sp); 173 174 // Compile the thing into a bunch of Surface objects 175 void compile(); 176 void multiplyLiftRatio(float factor); 177 void multiplyDragCoefficient(float factor); 178 // setIncidence used to rotate (trim) the hstab 179 bool setIncidence(float incidence); 180 // limits for setIncidence setIncidenceMin(float min)181 void setIncidenceMin(float min) { _incidenceMin = min; }; setIncidenceMax(float max)182 void setIncidenceMax(float max) { _incidenceMax = max; }; getIncidenceMin() const183 float getIncidenceMin() const { return _incidenceMin; }; getIncidenceMax() const184 float getIncidenceMax() const { return _incidenceMax; }; setFlowRegime(FlowRegime flow)185 void setFlowRegime(FlowRegime flow) { _flow = flow; }; setCriticalMachNumber(float m)186 void setCriticalMachNumber(float m) { _Mcrit = m; }; 187 // write mass (= _weight * scale) to property tree 188 void weight2mass(float scale); 189 isMirrored() const190 bool isMirrored() const { return _mirror; }; getBase(float * base) const191 void getBase(float* base) const { Math::set3(_base, base); }; getTip(float * tip) const192 void getTip(float* tip) const { Math::set3(_tip, tip); }; getSpan() const193 float getSpan() const { return _wingSpan; }; getTaper() const194 float getTaper() const { return _taper; }; 195 float getArea() const; getAspectRatio() const196 float getAspectRatio() const { return _aspectRatio; }; getSMC() const197 float getSMC() const { return _meanChord; }; getMACLength() const198 float getMACLength() const { return _mac.length; }; // get length of MAC getMACx() const199 float getMACx() const { return _mac.x; }; // get x-coord of MAC leading edge getMACy() const200 float getMACy() const { return _mac.y; }; // get y-coord of MAC leading edge getMACz() const201 float getMACz() const { return _mac.z; }; // get z-coord of MAC leading edge getSweepLEMin() const202 float getSweepLEMin() const { return _sweepLEMin; }; //min sweep angle of leading edge getSweepLEMax() const203 float getSweepLEMax() const { return _sweepLEMax; }; //max sweep angle of leading edge getFlowRegime() const204 FlowRegime getFlowRegime() const { return _flow; }; 205 getCriticalMachNumber() const206 float getCriticalMachNumber() const { return _Mcrit; }; 207 //----------------------------- 208 // propergate the control axes value for the sub-surfaces 209 void setFlapPos(WingFlaps type, float lval, float rval = 0); 210 void setFlapEffectiveness(WingFlaps f, float lval); 211 /// base node for exporting data of this wing to property tree setPropertyNode(SGPropertyNode_ptr n)212 void setPropertyNode(SGPropertyNode_ptr n) { _wingN = n; }; 213 float updateModel(Model* model); 214 /// for YASim CLI tool 215 void printSectionInfo(); 216 }; 217 218 }; // namespace yasim 219 #endif // _WING_HPP 220