]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/YASim/Model.cpp
Constant-speed props were seeking to engine speed, not prop speed.
[flightgear.git] / src / FDM / YASim / Model.cpp
index 1a44230cfcec481517d699cebe73330417cb33d3..24c2940c006257c3482d9c9a93dd877adb54e595 100644 (file)
@@ -1,5 +1,3 @@
-#include <stdio.h>
-
 #include "Atmosphere.hpp"
 #include "Thruster.hpp"
 #include "Math.hpp"
@@ -17,6 +15,7 @@
 #include "Model.hpp"
 namespace yasim {
 
+#if 0
 void printState(State* s)
 {
     State tmp = *s;
@@ -39,6 +38,7 @@ void printState(State* s)
     printf("rot: %6.2f %6.2f %6.2f\n", tmp.rot[0], tmp.rot[1], tmp.rot[2]);
     printf("rac: %6.2f %6.2f %6.2f\n", tmp.racc[0], tmp.racc[1], tmp.racc[2]);
 }
+#endif
 
 Model::Model()
 {
@@ -53,6 +53,7 @@ Model::Model()
 
     _agl = 0;
     _crashed = false;
+    _turb = 0;
 }
 
 Model::~Model()
@@ -72,19 +73,24 @@ void Model::getThrust(float* out)
     }
 }
 
-void Model::initIteration(float dt)
+void Model::initIteration()
 {
     // Precompute torque and angular momentum for the thrusters
     int i;
     for(i=0; i<3; i++)
        _gyro[i] = _torque[i] = 0;
+
+    // Need a local altitude for the wind calculation
+    float dummy[3];
+    float alt = Math::abs(localGround(_s, dummy));
+
     for(i=0; i<_thrusters.size(); i++) {
        Thruster* t = (Thruster*)_thrusters.get(i);
        
         // Get the wind velocity at the thruster location
         float pos[3], v[3];
        t->getPosition(pos);
-        localWind(pos, _s, v);
+        localWind(pos, _s, v, alt);
 
        t->setWind(v);
        t->setAir(_pressure, _temp, _rho);
@@ -97,9 +103,24 @@ void Model::initIteration(float dt)
        Math::add3(v, _gyro, _gyro);
     }
 
+    // Displace the turbulence coordinates according to the local wind.
+    if(_turb) {
+        float toff[3];
+        Math::mul3(_integrator.getInterval(), _wind, toff);
+        _turb->offset(toff);
+    }
+}
 
-    
-
+// FIXME: This method looks to me like it's doing *integration*, not
+// initialization.  Integration code should ideally go into
+// calcForces.  Only very "unstiff" problems can be solved well like
+// this (see the engine code for an example); I don't know if rotor
+// dynamics qualify or not.
+// -Andy
+void Model::initRotorIteration()
+{
+    int i;
+    float dt = _integrator.getInterval();
     float lrot[3];
     Math::vmul33(_s->orient, _s->rot, lrot);
     Math::mul3(dt,lrot,lrot);
@@ -115,12 +136,12 @@ void Model::initIteration(float dt)
         Rotorblade* rp = (Rotorblade*)_rotorblades.get(i);
         rp->inititeration(dt,lrot);
     }
-    
 }
 
-void Model::iterate(float dt)
+void Model::iterate()
 {
-    initIteration(dt);
+    initIteration();
+    initRotorIteration();
     _body.recalc(); // FIXME: amortize this, somehow
     _integrator.calcNewInterval();
 }
@@ -145,12 +166,6 @@ State* Model::getState()
     return _s;
 }
 
-void Model::resetState()
-{
-    //_s->resetState();
-}
-
-
 void Model::setState(State* s)
 {
     _integrator.setState(s);
@@ -241,8 +256,7 @@ void Model::setGroundEffect(float* pos, float span, float mul)
 // (v dot _ground)-_ground[3] gives the distance AGL.
 void Model::setGroundPlane(double* planeNormal, double fromOrigin)
 {
-    int i;
-    for(i=0; i<3; i++) _ground[i] = planeNormal[i];
+    for(int i=0; i<3; i++) _ground[i] = planeNormal[i];
     _ground[3] = fromOrigin;
 }
 
@@ -265,7 +279,6 @@ void Model::calcForces(State* s)
     // velocity), and are therefore constant across the four calls to
     // calcForces.  They get computed before we begin the integration
     // step.
-    //printf("f");
     _body.setGyro(_gyro);
     _body.addTorque(_torque);
     int i;
@@ -277,6 +290,14 @@ void Model::calcForces(State* s)
        _body.addForce(pos, thrust);
     }
 
+    // Get a ground plane in local coordinates.  The first three
+    // elements are the normal vector, the final one is the distance
+    // from the local origin along that vector to the ground plane
+    // (negative for objects "above" the ground)
+    float ground[4];
+    ground[3] = localGround(s, ground);
+    float alt = Math::abs(ground[3]);
+
     // Gravity, convert to a force, then to local coordinates
     float grav[3];
     Glue::geodUp(s->pos, grav);
@@ -294,14 +315,12 @@ void Model::calcForces(State* s)
        // Vsurf = wind - velocity + (rot cross (cg - pos))
        float vs[3], pos[3];
        sf->getPosition(pos);
-        localWind(pos, s, vs);
+        localWind(pos, s, vs, alt);
 
        float force[3], torque[3];
        sf->calcForce(vs, _rho, force, torque);
        Math::add3(faero, force, faero);
 
-        
-
        _body.addForce(pos, force);
        _body.addTorque(torque);
     }
@@ -311,7 +330,7 @@ void Model::calcForces(State* s)
        // Vsurf = wind - velocity + (rot cross (cg - pos))
        float vs[3], pos[3];
        sf->getPosition(pos);
-        localWind(pos, s, vs);
+        localWind(pos, s, vs, alt);
 
        float force[3], torque[3];
        sf->calcForce(vs, _rho, force, torque);
@@ -328,7 +347,7 @@ void Model::calcForces(State* s)
        // Vsurf = wind - velocity + (rot cross (cg - pos))
        float vs[3], pos[3];
        sf->getPosition(pos);
-        localWind(pos, s, vs);
+        localWind(pos, s, vs, alt);
 
        float force[3], torque[3];
        sf->calcForce(vs, _rho, force, torque);
@@ -339,20 +358,6 @@ void Model::calcForces(State* s)
        _body.addForce(pos, force);
        _body.addTorque(torque);
     }
-    /*
-    {
-      float cg[3];
-      _body.getCG(cg);
-      //printf("cg: %5.3lf %5.3lf %5.3lf ",cg[0],cg[1],cg[2]);
-    }
-    */
-
-    // Get a ground plane in local coordinates.  The first three
-    // elements are the normal vector, the final one is the distance
-    // from the local origin along that vector to the ground plane
-    // (negative for objects "above" the ground)
-    float ground[4];
-    ground[3] = localGround(s, ground);
 
     // Account for ground effect by multiplying the vertical force
     // component by an amount linear with the fraction of the wingspan
@@ -385,8 +390,6 @@ void Model::newState(State* s)
 {
     _s = s;
 
-    //printState(s);
-
     // Some simple collision detection
     float min = 1e8;
     float ground[4], pos[3], cmpr[3];
@@ -435,11 +438,27 @@ float Model::localGround(State* s, float* out)
 
 // Calculates the airflow direction at the given point and for the
 // specified aircraft velocity.
-void Model::localWind(float* pos, State* s, float* out)
-{
-    // Most of the input is in global coordinates.  Fix that.
-    float lwind[3], lrot[3], lv[3];
-    Math::vmul33(s->orient, _wind, lwind);
+void Model::localWind(float* pos, State* s, float* out, float alt)
+{
+    float tmp[3], lwind[3], lrot[3], lv[3];
+
+    // Get a global coordinate for our local position, and calculate
+    // turbulence.
+    if(_turb) {
+        double gpos[3]; float up[3];
+        Math::tmul33(s->orient, pos, tmp);
+        for(int i=0; i<3; i++) {
+            gpos[i] = s->pos[i] + tmp[i];
+            up[i] = _ground[i];
+        }
+        _turb->getTurbulence(gpos, alt, up, lwind);
+        Math::add3(_wind, lwind, lwind);
+    } else {
+        Math::set3(_wind, lwind);
+    }
+
+    // Convert to local coordinates
+    Math::vmul33(s->orient, lwind, lwind);
     Math::vmul33(s->orient, s->rot, lrot);
     Math::vmul33(s->orient, s->v, lv);