]> git.mxchange.org Git - flightgear.git/commitdiff
Maik JUSTUS:
authormfranz <mfranz>
Wed, 9 May 2007 20:36:43 +0000 (20:36 +0000)
committermfranz <mfranz>
Wed, 9 May 2007 20:36:43 +0000 (20:36 +0000)
"minor update for the rotor FDM. It results in a more realistic
calculation of the phase shift of rotor and therefor in a little bit
more realistic flight behavior.
(Additionally you can modify the initial position of the rotor and some
(not finished) modifications for the jet ranger rotor)."

src/FDM/YASim/FGFDM.cpp
src/FDM/YASim/Rotor.cpp
src/FDM/YASim/Rotor.hpp
src/FDM/YASim/Rotorpart.cpp
src/FDM/YASim/Rotorpart.hpp

index 06a815f046f4b244b60ffff81a92be9bc1122aa7..9e5c585988205f52ac995ef4741b5d46b21de099 100644 (file)
@@ -708,6 +708,7 @@ Rotor* FGFDM::parseRotor(XMLAttributes* a, const char* type)
     w->setTranslift(attrf(a, "translift", 0.05));
     w->setC2(attrf(a, "dragfactor", 1));
     w->setStepspersecond(attrf(a, "stepspersecond", 120));
+    w->setPhiNull((attrf(a, "phi0", 0))*YASIM_PI/180);
     w->setRPM(attrf(a, "rpm", 424));
     w->setRelLenHinge(attrf(a, "rellenflaphinge", 0.07));
     w->setAlpha0((attrf(a, "flap0", -5))*YASIM_PI/180);
@@ -717,13 +718,11 @@ Rotor* FGFDM::parseRotor(XMLAttributes* a, const char* type)
     w->setTeeterdamp(attrf(a,"teeterdamp",.0001));
     w->setMaxteeterdamp(attrf(a,"maxteeterdamp",1000));
     w->setRelLenTeeterHinge(attrf(a,"rellenteeterhinge",0.01));
-    void setAlphamin(float f);
-    void setAlphamax(float f);
-    void setAlpha0factor(float f);
-
     if(attrb(a,"ccw"))
        w->setCcw(1); 
-    
+    if(attrb(a,"sharedflaphinge"))
+       w->setSharedFlapHinge(true); 
+
     if(a->hasAttribute("name"))
        w->setName(a->getValue("name") );
     if(a->hasAttribute("alphaout0"))
index d338ba5a71bb9cd057de8dbe9329ad2b1b6ec706..7d02c48c5ee43359f577b82704db2382391607b1 100644 (file)
@@ -67,6 +67,7 @@ Rotor::Rotor()
     _normal_with_yaw_roll[2]=1;
     _number_of_blades=4;
     _omega=_omegan=_omegarel=_omegarelneu=0;
+    _phi_null=0;
     _ddt_omega=0;
     _pitch_a=0;
     _pitch_b=0;
@@ -75,6 +76,7 @@ Rotor::Rotor()
     _no_torque=0;
     _rel_blade_center=.7;
     _rel_len_hinge=0.01;
+    _shared_flap_hinge=false;
     _rellenteeterhinge=0.01;
     _rotor_rpm=442;
     _sim_blades=0;
@@ -149,8 +151,8 @@ void Rotor::inititeration(float dt,float omegarel,float ddt_omegarel,float *rot)
     _ddt_omega=_omegan*ddt_omegarel;
     int i;
     for(i=0; i<_rotorparts.size(); i++) {
-        float s = Math::sin(2*pi*i/_number_of_parts);
-        float c = Math::cos(2*pi*i/_number_of_parts);
+        float s = Math::sin(float(2*pi*i/_number_of_parts+(_phi-pi/2.)*(_ccw?1:-1)));
+        float c = Math::cos(float(2*pi*i/_number_of_parts+(_phi-pi/2.)*(_ccw?1:-1)));
         Rotorpart* r = (Rotorpart*)_rotorparts.get(i);
         r->setOmega(_omega);
         r->setDdtOmega(_ddt_omega);
@@ -522,6 +524,11 @@ void Rotor::setTranslift(float value)
     _translift=value;
 }
 
+void Rotor::setSharedFlapHinge(bool s)
+{
+    _shared_flap_hinge=s;
+}
+
 void Rotor::setC2(float value)
 {
     _c2=value;
@@ -537,6 +544,11 @@ void Rotor::setRPM(float value)
     _rotor_rpm=value;
 }
 
+void Rotor::setPhiNull(float value)
+{
+    _phi_null=value;
+}
+
 void Rotor::setRelLenHinge(float value)
 {
     _rel_len_hinge=value;
@@ -635,10 +647,10 @@ void Rotor::setCollective(float lval)
 {
     lval = Math::clamp(lval, -1, 1);
     int i;
+    _collective=_min_pitch+(lval+1)/2*(_max_pitch-_min_pitch);
     for(i=0; i<_rotorparts.size(); i++) {
-        ((Rotorpart*)_rotorparts.get(i))->setCollective(lval);
+        ((Rotorpart*)_rotorparts.get(i))->setCollective(_collective);
     }
-    _collective=_min_pitch+(lval+1)/2*(_max_pitch-_min_pitch);
 }
 
 void Rotor::setCyclicele(float lval,float rval)
@@ -919,11 +931,17 @@ void Rotor::compile()
     float omega=_rotor_rpm/60*2*pi;
     _omegan=omega;
     float omega0=omega*Math::sqrt(1/(1-_rel_len_hinge));
-    _delta*=pitchaforce/(_pitch_a*omega*lentocenter*2*rotorpartmass);
+    float delta_theoretical=pitchaforce/(_pitch_a*omega*lentocenter*2*rotorpartmass);
+    _delta*=delta_theoretical;
 
-    float phi=Math::atan2(2*omega*_delta,omega0*omega0-omega*omega);
     float relamp=(omega*omega/(2*_delta*Math::sqrt(sqr(omega0*omega0-omega*omega)
         +4*_delta*_delta*omega*omega)))*_cyclic_factor;
+    float relamp_theoretical=(omega*omega/(2*delta_theoretical*Math::sqrt(sqr(omega0*omega0-omega*omega)
+        +4*delta_theoretical*delta_theoretical*omega*omega)))*_cyclic_factor;
+    _phi=Math::acos(_rel_len_hinge);
+    SG_LOG(SG_GENERAL, SG_ALERT,
+        "phi: " << _phi*180/3.14 << " delta3: " << _delta3 << "(" << Math::atan(_delta3)*180/3.14 << ")" <<endl);
+    _phi-=Math::atan(_delta3);
     if (!_no_torque)
     {
         torque0=_power_at_pitch_0/_number_of_parts*1000/omega;  
@@ -945,13 +963,19 @@ void Rotor::compile()
         float lpos[3],lforceattac[3],lspeed[3],dirzentforce[3];
         float s = Math::sin(2*pi*i/_number_of_parts);
         float c = Math::cos(2*pi*i/_number_of_parts);
-        float direction[3],nextdirection[3],help[3];
+        float sp = Math::sin(float(2*pi*i/_number_of_parts-pi/2.+_phi));
+        float cp = Math::cos(float(2*pi*i/_number_of_parts-pi/2.+_phi));
+        float direction[3],nextdirection[3],help[3],direction90deg[3];
         Math::mul3(c ,directions[0],help);
         Math::mul3(s ,directions[1],direction);
         Math::add3(help,direction,direction);
 
         Math::mul3(c ,directions[1],help);
-        Math::mul3(s ,directions[2],nextdirection);
+        Math::mul3(s ,directions[2],direction90deg);
+        Math::add3(help,direction90deg,direction90deg);
+        
+        Math::mul3(cp ,directions[1],help);
+        Math::mul3(sp ,directions[2],nextdirection);
         Math::add3(help,nextdirection,nextdirection);
 
         Math::mul3(lentocenter,direction,lpos);
@@ -960,17 +984,12 @@ void Rotor::compile()
         //nextdirection: +90deg (gyro)!!!
 
         Math::add3(lforceattac,_base,lforceattac);
-        Math::mul3(speed,nextdirection,lspeed);
+        Math::mul3(speed,direction90deg,lspeed);
         Math::mul3(1,nextdirection,dirzentforce);
 
-
-        float maxcyclic=(i&1)?_maxcyclicele:_maxcyclicail;
-        float mincyclic=(i&1)?_mincyclicele:_mincyclicail;
-
         Rotorpart* rp=rps[i]=newRotorpart(lpos, lforceattac, _normal,
-            lspeed,dirzentforce,zentforce,pitchaforce, _max_pitch,_min_pitch,
-            mincyclic,maxcyclic,_delta3,rotorpartmass,_translift,
-            _rel_len_hinge,lentocenter);
+            lspeed,dirzentforce,zentforce,pitchaforce,_delta3,rotorpartmass,
+            _translift,_rel_len_hinge,lentocenter);
         int k = i*4/_number_of_parts;
         rp->setAlphaoutput(_alphaoutput[k&1?k:(_ccw?k^2:k)],0);
         rp->setAlphaoutput(_alphaoutput[4+(k&1?k:(_ccw?k^2:k))],1+(k>1));
@@ -1083,7 +1102,7 @@ void Rotor::compile()
     rps[0]->setOmega(0);
     writeInfo();
 }
-std::ostream &  operator<<(std::ostream & out, /*const*/ Rotor& r)
+std::ostream &  operator<<(std::ostream & out, Rotor& r)
 {
 #define i(x) << #x << ":" << r.x << endl
 #define iv(x) << #x << ":" << r.x[0] << ";" << r.x[1] << ";" <<r.x[2] << ";" << endl
@@ -1192,7 +1211,6 @@ void Rotor:: writeInfo()
 }
 Rotorpart* Rotor::newRotorpart(float* pos, float *posforceattac, float *normal,
     float* speed,float *dirzentforce, float zentforce,float maxpitchforce,
-    float maxpitch, float minpitch, float mincyclic,float maxcyclic,
     float delta3,float mass,float translift,float rellenhinge,float len)
 {
     Rotorpart *r = new Rotorpart();
@@ -1202,17 +1220,15 @@ Rotorpart* Rotor::newRotorpart(float* pos, float *posforceattac, float *normal,
     r->setPositionForceAttac(posforceattac);
     r->setSpeed(speed);
     r->setDirectionofZentipetalforce(dirzentforce);
-    r->setMaxpitch(maxpitch);
-    r->setMinpitch(minpitch);
-    r->setMaxcyclic(maxcyclic);
-    r->setMincyclic(mincyclic);
     r->setDelta3(delta3);
     r->setDynamic(_dynamic);
     r->setTranslift(_translift);
     r->setC2(_c2);
     r->setWeight(mass);
     r->setRelLenHinge(rellenhinge);
+    r->setSharedFlapHinge(_shared_flap_hinge);
     r->setOmegaN(_omegan);
+    r->setPhi(_phi_null);
     r->setAlpha0(_alpha0);
     r->setAlphamin(_alphamin);
     r->setAlphamax(_alphamax);
index 2f8e1f87e8f026bb0fb0becce473f3ce8ad8302a..379a36a7b6ba1429514bc8882cecc9cac9d95426 100644 (file)
@@ -19,6 +19,7 @@ class Rotor {
 private:
     float _torque;
     float _omega,_omegan,_omegarel,_ddt_omega,_omegarelneu;
+    float _phi_null;
     float _chord;
     float _taper;
     float _airfoil_incidence_no_lift;
@@ -64,6 +65,7 @@ public:
     void setC2(float value);
     void setStepspersecond(float steps);
     void setRPM(float value);
+    void setPhiNull(float value);
     void setRelLenHinge(float value);
     void setBase(float* base);        // in local coordinates
     void getPosition(float* out);
@@ -111,12 +113,11 @@ public:
     float getOverallStall() 
         {if (_stall_v2sum !=0 ) return _stall_sum/_stall_v2sum; else return 0;}
     float getAirfoilIncidenceNoLift() {return _airfoil_incidence_no_lift;}
-    
-    
+
     Vector _rotorparts;
     void findGroundEffectAltitude(Ground * ground_cb,State *s);
     void writeInfo();
-
+    void setSharedFlapHinge(bool s);
 
 private:
     void strncpy(char *dest,const char *src,int maxlen);
@@ -127,7 +128,6 @@ private:
         int iteration=0,float a0=-1,float a1=-1,float a2=-1,float a3=-1);
     Rotorpart* newRotorpart(float* pos, float *posforceattac, float *normal,
         float* speed,float *dirzentforce, float zentforce,float maxpitchforce,
-        float maxpitch, float minpitch, float mincyclic,float maxcyclic,
         float delta3,float mass,float translift,float rellenhinge,float len);
     float _base[3];
     float _groundeffectpos[4][3];
@@ -199,6 +199,8 @@ private:
     float _cyclicele;
     float _cyclic_factor;
     float _rotor_correction_factor;
+    float _phi;
+    bool _shared_flap_hinge;
 };
 std::ostream &  operator<<(std::ostream & out, /*const*/ Rotor& r);
 
index 1bd3a70887ad00c3cadf84df19b50d2f08e47ea2..450f93f14993b2ce1ea7437bcb4cbb1cd7eee9bc 100644 (file)
@@ -14,6 +14,7 @@ Rotorpart::Rotorpart()
     _cyclic=0;
     _collective=0;
     _rellenhinge=0;
+    _shared_flap_hinge=false;
     _dt=0;
 #define set3(x,a,b,c) x[0]=a;x[1]=b;x[2]=c;
     set3 (_speed,1,0,0);
@@ -23,10 +24,6 @@ Rotorpart::Rotorpart()
     set3 (_last_torque,0,0,0);
 #undef set3
     _centripetalforce=1;
-    _maxpitch=.02;
-    _minpitch=0;
-    _maxcyclic=0.02;
-    _mincyclic=-0.02;
     _delta3=0.5;
     _cyclic=0;
     _collective=-1;
@@ -187,6 +184,11 @@ void Rotorpart::setOmega(float value)
     _omega=value;
 }
 
+void Rotorpart::setPhi(float value)
+{
+    _phi=value;
+}
+
 void Rotorpart::setOmegaN(float value)
 {
     _omegan=value;
@@ -202,25 +204,6 @@ void Rotorpart::setZentipetalForce(float f)
     _centripetalforce=f;
 } 
 
-void Rotorpart::setMinpitch(float f)
-{
-    _minpitch=f;
-} 
-
-void Rotorpart::setMaxpitch(float f)
-{
-    _maxpitch=f;
-} 
-
-void Rotorpart::setMaxcyclic(float f)
-{
-    _maxcyclic=f;
-} 
-
-void Rotorpart::setMincyclic(float f)
-{
-    _mincyclic=f;
-} 
 
 void Rotorpart::setDelta3(float f)
 {
@@ -247,6 +230,11 @@ void Rotorpart::setRelLenHinge(float f)
     _rellenhinge=f;
 }
 
+void Rotorpart::setSharedFlapHinge(bool s)
+{
+    _shared_flap_hinge=s;
+}
+
 void Rotorpart::setC2(float f)
 {
     _c2=f;
@@ -378,9 +366,6 @@ float Rotorpart::calculateAlpha(float* v_rel_air, float rho,
     if((_nextrp==NULL)||(_lastrp==NULL)||(_rotor==NULL)) 
         return 0.0;//not initialized. Can happen during startupt of flightgear
     if (returnlift!=NULL) *returnlift=0;
-    /*float flap_omega=(_nextrp->getrealAlpha()-_lastrp->getrealAlpha())
-        *_omega / pi*_rotor->getNumberOfParts()/4; hier mal die alte version probieren?
-        */
     float flap_omega=(_next90rp->getrealAlpha()-_last90rp->getrealAlpha())
         *_omega / pi;
     float local_width=_diameter*(1-_rel_len_blade_start)/2.
@@ -432,7 +417,7 @@ float Rotorpart::calculateAlpha(float* v_rel_air, float rho,
             *_rotor_correction_factor-_rotor->getAirfoilIncidenceNoLift();
         ias = incidence_of_airspeed;
         float lift_wo_cyc = _rotor->getLiftCoef(incidence_of_airspeed
-            -cyc*_rotor_correction_factor,v_local_scalar)
+            -cyc*_rotor_correction_factor*prantl_factor,v_local_scalar)
             * v_local_scalar * v_local_scalar * A *rho *0.5;
         float lift_with_cyc = 
             _rotor->getLiftCoef(incidence_of_airspeed,v_local_scalar)
@@ -464,8 +449,31 @@ float Rotorpart::calculateAlpha(float* v_rel_air, float rho,
     //as above, use 1st order approximation
     //float alpha=Math::atan2(lift_moment,_centripetalforce * _len); 
     float alpha;
-    alpha=lift_moment/(_centripetalforce * _len - _mass * _len * 9.81 /_alpha0);
-    //centripetalforce is >=0 and _alpha0<-0.01
+    if (_shared_flap_hinge)
+    {
+        float div=0;
+        if (Math::abs(_alphaalt) >1e-6)
+            div=(_centripetalforce * _len - _mass * _len * 9.81 /_alpha0*(_alphaalt+_oppositerp->getAlphaAlt())/(2.0*_alphaalt));
+        if (Math::abs(div)>1e-6)
+            alpha=lift_moment/div;
+        else if(Math::abs(_alphaalt+_oppositerp->getAlphaAlt())>1e-6)
+        {
+            float div=(_centripetalforce * _len - _mass * _len * 9.81 *0.5)*(_alphaalt+_oppositerp->getAlphaAlt());
+            if (Math::abs(div)>1e-6)
+                alpha=_oppositerp->getAlphaAlt()+lift_moment/div*_alphaalt;
+        }
+        else
+            alpha=_alphaalt;
+    }
+    else
+    {
+        float div=(_centripetalforce * _len - _mass * _len * 9.81 /_alpha0);
+        if (Math::abs(div)>1e-6)
+            alpha=lift_moment/div;
+        else
+            alpha=_alphaalt;
+    }
     return (alpha);
 }
 
@@ -490,10 +498,12 @@ void Rotorpart::calcForce(float* v, float rho,  float* out, float* torque,
     //Angle of blade which would produce no vertical force (where the 
     //effective incidence is zero)
 
-    //float cyc=_mincyclic+(_cyclic+1)/2*(_maxcyclic-_mincyclic);
     float cyc=_cyclic;
-    float col=_minpitch+(_collective+1)/2*(_maxpitch-_minpitch);
-    _incidence=(col+cyc)-_delta3*_alphaalt;
+    float col=_collective;
+    if (_shared_flap_hinge)
+        _incidence=(col+cyc)-_delta3*0.5*(_alphaalt-_oppositerp->getAlphaAlt());
+    else
+        _incidence=(col+cyc)-_delta3*_alphaalt;
     //the incidence of the rotorblade due to control input reduced by the
     //delta3 effect, see README.YASIM
     //float beta=_relamp*cyc+col; 
@@ -503,6 +513,7 @@ void Rotorpart::calcForce(float* v, float rho,  float* out, float* torque,
     //the new flapping angle will be the old flapping angle
     //+ factor *(alpha - "old flapping angle")
     alpha=calculateAlpha(v,rho,_incidence,cyc,0,&scalar_torque);
+    alpha=Math::clamp(alpha,_alphamin,_alphamax);
     //the incidence is a function of alpha (if _delta* != 0)
     //Therefore missing: wrap this function in an integrator
     //(runge kutta e. g.)
@@ -564,10 +575,6 @@ std::ostream &  operator<<(std::ostream & out, const Rotorpart& rp)
         iv( _directionofcentripetalforce)
         iv( _directionofrotorpart)
         i( _centripetalforce)
-        i( _maxpitch)
-        i( _minpitch)
-        i( _maxcyclic)
-        i( _mincyclic)
         i( _cyclic)
         i( _collective)
         i( _delta3)
index b722ab4b817db9b6d1bca7c495bcc04ccaaaaf4e..cfc50af08909bb66752e5d75b863971708a224cf 100644 (file)
@@ -60,6 +60,7 @@ namespace yasim {
         void setTorque(float torque_max_force,float torque_no_force);
         void setOmega(float value);
         void setOmegaN(float value);
+        void setPhi(float value);
         void setDdtOmega(float value);
         float getIncidence();
         float getPhi();
@@ -72,6 +73,8 @@ namespace yasim {
         void setRotor(Rotor *rotor);
         void setTorqueOfInertia(float toi);
         void writeInfo(std::ostringstream &buffer);
+        void setSharedFlapHinge(bool s);
+        float getAlphaAlt() {return _alphaalt;}
 
     private:
         void strncpy(char *dest,const char *src,int maxlen);
@@ -88,10 +91,6 @@ namespace yasim {
         float _directionofcentripetalforce[3];
         float _directionofrotorpart[3];
         float _centripetalforce;
-        float _maxpitch;
-        float _minpitch;
-        float _maxcyclic;
-        float _mincyclic;
         float _cyclic;
         float _collective;
         float _delta3;
@@ -119,6 +118,7 @@ namespace yasim {
         char _alphaoutputbuf[2][256];
         int _alpha2type;
         float _rotor_correction_factor;
+        bool _shared_flap_hinge;
     };
     std::ostream &  operator<<(std::ostream & out, const Rotorpart& rp);
 }; // namespace yasim