]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/YASim/Wing.cpp
latest updates from JSBSim
[flightgear.git] / src / FDM / YASim / Wing.cpp
index 22cc84a663dcb89b864eb82b97fed1ddcb97bb0e..ad15410e17a7a7831e1280849a69253f4635552b 100644 (file)
@@ -1,6 +1,7 @@
 #include "Math.hpp"
 #include "Surface.hpp"
 #include "Wing.hpp"
+
 namespace yasim {
 
 Wing::Wing()
@@ -15,8 +16,10 @@ Wing::Wing()
     _stall = 0;
     _stallWidth = 0;
     _stallPeak = 0;
+    _twist = 0;
     _camber = 0;
     _incidence = 0;
+    _inducedDrag = 1;
     _dragScale = 1;
     _liftRatio = 1;
     _flap0Start = 0;
@@ -113,6 +116,11 @@ void Wing::setStallPeak(float fraction)
     _stallPeak = fraction;
 }
 
+void Wing::setTwist(float angle)
+{
+    _twist = angle;
+}
+
 void Wing::setCamber(float camber)
 {
     _camber = camber;
@@ -169,6 +177,16 @@ void Wing::setFlap0(float lval, float rval)
     }
 }
 
+void Wing::setFlap0Effectiveness(float lval)
+{
+    lval = Math::clamp(lval, 1, 10);
+    int i;
+    for(i=0; i<_flap0Surfs.size(); i++) {
+        ((Surface*)_flap0Surfs.get(i))->setFlapEffectiveness(lval);
+//     if(_mirror) ((Surface*)_flap0Surfs.get(++i))->setFlapEffectiveness(rval);
+    }
+}
+
 void Wing::setFlap1(float lval, float rval)
 {
     lval = Math::clamp(lval, -1, 1);
@@ -180,6 +198,16 @@ void Wing::setFlap1(float lval, float rval)
     }
 }
 
+void Wing::setFlap1Effectiveness(float lval)
+{
+    lval = Math::clamp(lval, 1, 10);
+    int i;
+    for(i=0; i<_flap1Surfs.size(); i++) {
+        ((Surface*)_flap1Surfs.get(i))->setFlapEffectiveness(lval);
+//     if(_mirror) ((Surface*)_flap1Surfs.get(++i))->setFlap(rval);
+    }
+}
+
 void Wing::setSpoiler(float lval, float rval)
 {
     lval = Math::clamp(lval, 0, 1);
@@ -208,27 +236,45 @@ float Wing::getGroundEffect(float* posOut)
     return span;
 }
 
+void Wing::getTip(float* tip)
+{
+    tip[0] = -Math::tan(_sweep);
+    tip[1] = Math::cos(_dihedral);
+    tip[2] = Math::sin(_dihedral);
+    Math::unit3(tip, tip);
+    Math::mul3(_length, tip, tip);
+    Math::add3(_base, tip, tip);
+}
+
+bool Wing::isMirrored()
+{
+    return _mirror;
+}
+
 void Wing::compile()
 {
     // Have we already been compiled?
     if(_surfs.size() != 0) return;
 
-    // Assemble the start/end coordinates into an array, sort them,
+    // Assemble the start/end coordinates of all control surfaces
+    // and the wing itself into an array, sort them,
     // and remove duplicates.  This gives us the boundaries of our
     // segments.
-    float bounds[8];
+    float bounds[10];
     bounds[0] = _flap0Start;   bounds[1] = _flap0End;
     bounds[2] = _flap1Start;   bounds[3] = _flap1End;
     bounds[4] = _spoilerStart; bounds[5] = _spoilerEnd;
     bounds[6] = _slatStart;    bounds[7] = _slatEnd;
+    //and don't forget the root and the tip of the wing itself
+    bounds[8] = 0;             bounds[9] = 1;
 
     // Sort in increasing order
     int i;
-    for(i=0; i<8; i++) {
+    for(i=0; i<10; i++) {
         int minIdx = i;
        float minVal = bounds[i];
         int j;
-        for(j=i+1; j<8; j++) {
+        for(j=i+1; j<10; j++) {
             if(bounds[j] < minVal) {
                 minIdx = j;
                minVal = bounds[j];
@@ -237,11 +283,11 @@ void Wing::compile()
         float tmp = bounds[i];
         bounds[i] = minVal; bounds[minIdx] = tmp;
     }
-                                 
+
     // Uniqify
     float last = bounds[0];
     int nbounds = 1;
-    for(i=1; i<8; i++) {
+    for(i=1; i<10; i++) {
         if(bounds[i] != last)
             bounds[nbounds++] = bounds[i];
         last = bounds[i];
@@ -249,7 +295,7 @@ void Wing::compile()
 
     // Calculate a "nominal" segment length equal to an average chord,
     // normalized to lie within 0-1 over the length of the wing.
-    float segLen = _chord * (0.5*(_taper+1)) / _length;
+    float segLen = _chord * (0.5f*(_taper+1)) / _length;
 
     // Generating a unit vector pointing out the left wing.
     float left[3];
@@ -308,11 +354,13 @@ void Wing::compile()
         // and flap1 are set.  Right now flap1 overrides.
 
         int nSegs = (int)Math::ceil((end-start)/segLen);
+        if (_twist != 0 && nSegs < 8) // more segments if twisted
+            nSegs = 8;
         float segWid = _length * (end - start)/nSegs;
 
         int j;
         for(j=0; j<nSegs; j++) {
-            float frac = start + (j+0.5) * (end-start)/nSegs;
+            float frac = start + (j+0.5f) * (end-start)/nSegs;
             float pos[3];
             interp(root, tip, frac, pos);
 
@@ -325,6 +373,7 @@ void Wing::compile()
             sr->surface = s;
             sr->weight = chord * segWid;
             s->setTotalDrag(sr->weight);
+            s->setTwist(_twist * frac);
             _surfs.add(sr);
 
             if(_mirror) {
@@ -335,10 +384,15 @@ void Wing::compile()
                 sr->surface = s;
                 sr->weight = chord * segWid;
                 s->setTotalDrag(sr->weight);
+                s->setTwist(_twist * frac);
                 _surfs.add(sr);
             }
         }
     }
+
+    // Last of all, re-set the incidence in case setIncidence() was
+    // called before we were compiled.
+    setIncidence(_incidence);
 }
 
 float Wing::getDragScale()
@@ -390,8 +444,8 @@ Surface* Wing::newSurface(float* pos, float* orient, float chord,
     // The negative AoA stall is the same if we're using an uncambered
     // airfoil, otherwise a "little badder".
     if(_camber > 0) {
-        s->setStall(1, stallAoA * 0.8);
-        s->setStallWidth(1, _stallWidth * 0.5);
+        s->setStall(1, stallAoA * 0.8f);
+        s->setStallWidth(1, _stallWidth * 0.5f);
     } else {
         s->setStall(1, stallAoA);
         s->setStall(1, _stallWidth);
@@ -402,8 +456,8 @@ Surface* Wing::newSurface(float* pos, float* orient, float chord,
     s->setStallPeak(1, 1);
     int i;
     for(i=2; i<4; i++) {
-        s->setStall(i, 0.2267);
-        s->setStallWidth(i, 1);
+        s->setStall(i, 0.2267f);
+        s->setStallWidth(i, 0.01);
     }
     
     if(flap0)   s->setFlapParams(_flap0Lift, _flap0Drag);
@@ -416,6 +470,8 @@ Surface* Wing::newSurface(float* pos, float* orient, float chord,
     if(slat)    _slatSurfs.add(s);
     if(spoiler) _spoilerSurfs.add(s);
 
+    s->setInducedDrag(_inducedDrag);
+
     return s;
 }