From 7b05646ed0bd2ebd832d88c83492b9a59e1ffd69 Mon Sep 17 00:00:00 2001 From: mfranz Date: Wed, 9 May 2007 20:36:43 +0000 Subject: [PATCH] Maik JUSTUS: "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 | 9 ++--- src/FDM/YASim/Rotor.cpp | 60 +++++++++++++++++----------- src/FDM/YASim/Rotor.hpp | 10 +++-- src/FDM/YASim/Rotorpart.cpp | 79 ++++++++++++++++++++----------------- src/FDM/YASim/Rotorpart.hpp | 8 ++-- 5 files changed, 95 insertions(+), 71 deletions(-) diff --git a/src/FDM/YASim/FGFDM.cpp b/src/FDM/YASim/FGFDM.cpp index 06a815f04..9e5c58598 100644 --- a/src/FDM/YASim/FGFDM.cpp +++ b/src/FDM/YASim/FGFDM.cpp @@ -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")) diff --git a/src/FDM/YASim/Rotor.cpp b/src/FDM/YASim/Rotor.cpp index d338ba5a7..7d02c48c5 100644 --- a/src/FDM/YASim/Rotor.cpp +++ b/src/FDM/YASim/Rotor.cpp @@ -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 << ")" <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] << ";" <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); diff --git a/src/FDM/YASim/Rotor.hpp b/src/FDM/YASim/Rotor.hpp index 2f8e1f87e..379a36a7b 100644 --- a/src/FDM/YASim/Rotor.hpp +++ b/src/FDM/YASim/Rotor.hpp @@ -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); diff --git a/src/FDM/YASim/Rotorpart.cpp b/src/FDM/YASim/Rotorpart.cpp index 1bd3a7088..450f93f14 100644 --- a/src/FDM/YASim/Rotorpart.cpp +++ b/src/FDM/YASim/Rotorpart.cpp @@ -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) diff --git a/src/FDM/YASim/Rotorpart.hpp b/src/FDM/YASim/Rotorpart.hpp index b722ab4b8..cfc50af08 100644 --- a/src/FDM/YASim/Rotorpart.hpp +++ b/src/FDM/YASim/Rotorpart.hpp @@ -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 -- 2.39.5