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