]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/propulsion/FGRotor.h
Merge branch 'next' into comm-subsystem
[flightgear.git] / src / FDM / JSBSim / models / propulsion / FGRotor.h
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Header:       FGRotor.h
4  Author:       T. Kreitler
5  Date started: 08/24/00
6
7  ------------- Copyright (C) 2010  T. Kreitler (t.kreitler@web.de) -------------
8
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
17  details.
18
19  You should have received a copy of the GNU Lesser General Public License along with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA  02111-1307, USA.
22
23  Further information about the GNU Lesser General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25
26 HISTORY
27 --------------------------------------------------------------------------------
28 01/01/10  T.Kreitler test implementation
29 01/10/11  T.Kreitler changed to single rotor model
30 03/06/11  T.Kreitler added brake, clutch, and experimental free-wheeling-unit
31
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 SENTRY
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
35
36 #ifndef FGROTOR_H
37 #define FGROTOR_H
38
39 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 INCLUDES
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
42
43 #include "FGThruster.h"
44
45 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46 DEFINITIONS
47 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
48
49 #define ID_ROTOR "$Id: FGRotor.h,v 1.12 2011/10/15 21:30:28 jentron Exp $"
50
51 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 FORWARD DECLARATIONS
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
54
55 namespace JSBSim {
56
57 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58 CLASS DOCUMENTATION
59 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
60
61 /** Models a helicopter rotor.
62
63
64 <h3>Configuration File Format</h3>
65 @code
66 <rotor name="{string}">
67   <diameter unit="{LENGTH}"> {number} </diameter>
68   <numblades> {number} </numblades>
69   <gearratio> {number} </gearratio>
70   <nominalrpm> {number} </nominalrpm>
71   <minrpm> {number} </minrpm>
72   <maxrpm> {number} </maxrpm>
73   <chord unit="{LENGTH}"> {number} </chord>
74   <liftcurveslope Xunit="1/RAD"> {number} </liftcurveslope>
75   <twist unit="{ANGLE}"> {number} </twist>
76   <hingeoffset unit="{LENGTH}"> {number} </hingeoffset>
77   <flappingmoment unit="{MOMENT}"> {number} </flappingmoment>
78   <massmoment Xunit="SLUG*FT"> {number} </massmoment>
79   <polarmoment unit="{MOMENT}"> {number} </polarmoment>
80   <inflowlag> {number} </inflowlag>
81   <tiplossfactor> {number} </tiplossfactor>
82   <maxbrakepower unit="{POWER}"> {number} </maxbrakepower>
83   <gearloss unit="{POWER}"> {number} </gearloss>
84   <gearmoment unit="{MOMENT}"> {number} </gearmoment>
85
86   <controlmap> {MAIN|TAIL|TANDEM} </controlmap>
87   <ExternalRPM> {number} </ExternalRPM>
88
89   <groundeffectexp> {number} </groundeffectexp>
90   <groundeffectshift unit="{LENGTH}"> {number} </groundeffectshift>
91
92   <freewheelthresh> {number} </freewheelthresh>
93 </rotor>
94
95 //  LENGTH means any of the supported units, same for ANGLE and MOMENT.
96 //  Xunit-attributes are a hint for currently unsupported units, so
97 //  values must be provided accordingly.
98
99 @endcode
100
101 <h3>Configuration Parameters:</h3>
102
103   Brief description and the symbol frequently found in the literature.
104
105 <pre>
106     \<diameter>           - Rotor disk diameter (2x R).
107     \<numblades>          - Number of blades (b).
108     \<gearratio>          - Ratio of (engine rpm) / (rotor rpm), usually > 1.
109     \<nominalrpm>         - RPM at which the rotor usally operates.
110     \<minrpm>             - Lowest RPM used in the model, optional and defaults to 1.
111     \<maxrpm>             - Largest RPM used in the model, optional and defaults to 2 x nominalrpm.
112     \<chord>              - Blade chord, (c).
113     \<liftcurveslope>     - Slope of curve of section lift against section angle of attack,
114                              per rad (a).
115     \<twist>              - Blade twist from root to tip, (theta_1).
116     \<hingeoffset>        - Rotor flapping-hinge offset (e).
117     \<flappingmoment>     - Flapping moment of inertia (I_b).
118     \<massmoment>         - Blade mass moment. Mass of a single blade times the blade's
119                              cg-distance from the hub, optional.
120     \<polarmoment>        - Moment of inertia for the whole rotor disk, optional.
121     \<inflowlag>          - Rotor inflow time constant, sec. Smaller values yield to quicker
122                               responses (typical values for main rotor: 0.1 - 0.2 s).
123     \<tiplossfactor>      - Tip-loss factor. The Blade fraction that produces lift.
124                               Value usually ranges between 0.95 - 1.0, optional (B).
125
126     \<maxbrakepower>      - Rotor brake, 20-30 hp should work for a mid size helicopter.
127     \<gearloss>           - Friction in gear, 0.2% to 3% of the engine power, optional (see notes).
128     \<gearmoment>         - Approximation for the moment of inertia of the gear (and engine),
129                               defaults to 0.1 * polarmoment, optional.
130
131     \<controlmap>         - Defines the control inputs used (see notes).
132
133     \<ExternalRPM>        - Links the rotor to another rotor, or an user controllable property.
134
135     Experimental properties
136
137     \<groundeffectexp>    - Exponent for ground effect approximation. Values usually range from 0.04
138                             for large rotors to 0.1 for smaller ones. As a rule of thumb the effect 
139                             vanishes at a height 2-3 times the rotor diameter.
140                               formula used: exp ( - groundeffectexp * (height+groundeffectshift) )
141                             Omitting or setting to 0.0 disables the effect calculation.
142     \<groundeffectshift>  - Further adjustment of ground effect, approx. hub height or slightly above. 
143
144 </pre>
145
146 <h3>Notes:</h3>  
147
148   <h4>- Controls -</h4>
149
150     The behavior of the rotor is controlled/influenced by following inputs.<ul>
151       <li> The power provided by the engine. This is handled by the regular engine controls.</li>
152       <li> The collective control input. This is read from the <tt>fdm</tt> property 
153            <tt>propulsion/engine[x]/collective-ctrl-rad</tt>. See below for tail rotor</li>
154       <li> The lateral cyclic input. Read from
155            <tt>propulsion/engine[x]/lateral-ctrl-rad</tt>.</li>
156       <li> The longitudinal cyclic input. Read from 
157            <tt>propulsion/engine[x]/longitudinal-ctrl-rad</tt>.</li>
158       <li> The tail collective (aka antitorque, aka pedal) control input. Read from
159            <tt>propulsion/engine[x]/antitorque-ctrl-rad</tt> or 
160            <tt>propulsion/engine[x]/tail-collective-ctrl-rad</tt>.</li>
161
162     </ul>
163
164   <h4>- Tail/tandem rotor -</h4>
165
166     Providing <tt>\<ExternalRPM\> 0 \</ExternalRPM\></tt> the tail rotor's RPM
167     is linked to to the main (=first, =0) rotor, and specifing
168     <tt>\<controlmap\> TAIL \</controlmap\></tt> tells this rotor to read the
169     collective input from <tt>propulsion/engine[1]/antitorque-ctrl-rad</tt>
170     (The TAIL-map ignores lateral and longitudinal input). The rotor needs to be 
171     attached to a dummy engine, e.g. an 1HP electrical engine.
172     A tandem rotor is setup analogous. 
173
174   <h4>- Sense -</h4>
175
176     The 'sense' parameter from the thruster is interpreted as follows, sense=1 means
177     counter clockwise rotation of the main rotor, as viewed from above. This is as a far
178     as I know more popular than clockwise rotation, which is defined by setting sense to
179     -1. Concerning coaxial designs - by setting 'sense' to zero, a Kamov-style rotor is
180     modeled (i.e. the rotor produces no torque).
181
182   <h4>- Engine issues -</h4>
183
184     In order to keep the rotor/engine speed constant, use of a RPM-Governor system is
185     encouraged (see examples).
186
187     In case the model requires the manual use of a clutch the <tt>\<gearloss\></tt>
188     property might need attention.<ul>
189
190     <li> Electrical: here the gear-loss should be rather large to keep the engine
191          controllable when the clutch is open (although full throttle might still make it
192          spin away).</li>
193     <li> Piston: this engine model already has some internal friction loss and also
194          looses power if it spins too high. Here the gear-loss could be set to 0.25%
195          of the engine power (which is also the approximated default).</li>
196     <li> Turboprop: Here the default value might be a bit too small. Also it's advisable
197          to adjust the power table for rpm values that are far beyond the nominal value.</li>
198
199     </ul>
200
201   <h4>- Development hints -</h4>
202
203     Setting <tt>\<ExternalRPM> -1 \</ExternalRPM></tt> the rotor's RPM is controlled  by
204     the <tt>propulsion/engine[x]/x-rpm-dict</tt> property. This feature can be useful
205     when developing a FDM.
206   
207
208 <h3>References:</h3>  
209
210     <dl>    
211     <dt>/SH79/</dt><dd>Shaugnessy, J. D., Deaux, Thomas N., and Yenni, Kenneth R.,
212               "Development and Validation of a Piloted Simulation of a 
213               Helicopter and External Sling Load",  NASA TP-1285, 1979.</dd>
214     <dt>/BA41/</dt><dd>Bailey,F.J.,Jr., "A Simplified Theoretical Method of Determining
215               the Characteristics of a Lifting Rotor in Forward Flight", NACA Rep.716, 1941.</dd>
216     <dt>/AM50/</dt><dd>Amer, Kenneth B.,"Theory of Helicopter Damping in Pitch or Roll and a
217               Comparison With Flight Measurements", NACA TN-2136, 1950.</dd>
218     <dt>/TA77/</dt><dd>Talbot, Peter D., Corliss, Lloyd D., "A Mathematical Force and Moment
219               Model of a UH-1H Helicopter for Flight Dynamics Simulations", NASA TM-73,254, 1977.</dd> 
220     <dt>/GE49/</dt><dd>Gessow, Alfred, Amer, Kenneth B. "An Introduction to the Physical 
221               Aspects of Helicopter Stability", NACA TN-1982, 1949.</dd>  
222     </dl>
223
224     @author Thomas Kreitler
225     @version $Id: FGRotor.h,v 1.12 2011/10/15 21:30:28 jentron Exp $
226   */
227
228
229
230 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
231 CLASS DECLARATION
232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
233
234 class FGTransmission :  public FGJSBBase {
235
236 public:
237   FGTransmission(FGFDMExec *exec, int num);
238   ~FGTransmission();
239
240   void Calculate(double EnginePower, double ThrusterTorque, double dt);
241
242   void   SetMaxBrakePower(double x) {MaxBrakePower=x;}
243   double GetMaxBrakePower() const {return MaxBrakePower;}
244   void   SetEngineFriction(double x) {EngineFriction=x;}
245   double GetEngineFriction() const {return EngineFriction;}
246   void   SetEngineMoment(double x) {EngineMoment=x;}
247   double GetEngineMoment() const {return EngineMoment;}
248   void   SetThrusterMoment(double x) {ThrusterMoment=x;}
249   double GetThrusterMoment() const {return ThrusterMoment;}
250
251   double GetFreeWheelTransmission() const {return FreeWheelTransmission;}
252   double GetEngineRPM() {return EngineRPM;}
253   double GetThrusterRPM() {return ThrusterRPM;}
254
255   double GetBrakeCtrl() const {return BrakeCtrlNorm;}
256   void   SetBrakeCtrl(double x) {BrakeCtrlNorm=x;}
257   void   SetClutchCtrlNorm(double x) {ClutchCtrlNorm=x;}
258
259 private:
260   bool BindModel(int num);
261   // void Debug(int from);
262
263   inline double omega_to_rpm(double w) {return w * 9.54929658551372014613302580235;} // omega/(2.0*PI) * 60.0
264   inline double rpm_to_omega(double r) {return r * .104719755119659774615421446109;} // (rpm/60.0)*2.0*PI
265
266   Filter FreeWheelLag;
267   double FreeWheelTransmission; // state, 0: free, 1:locked
268
269   double ThrusterMoment;
270   double EngineMoment;   // estimated MOI of gear and engine, influences acceleration
271   double EngineFriction; // estimated friction in gear and possibly engine
272
273   double ClutchCtrlNorm; // also in FGThruster.h
274   double BrakeCtrlNorm;
275   double MaxBrakePower;
276
277   double EngineRPM;
278   double ThrusterRPM;
279   FGPropertyManager* PropertyManager;
280
281 };
282
283 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284
285 class FGRotor :  public FGThruster {
286
287   enum eCtrlMapping {eMainCtrl=0, eTailCtrl, eTandemCtrl};
288
289 public:
290
291   /** Constructor for FGRotor.
292       @param exec a pointer to the main executive object
293       @param rotor_element a pointer to the thruster config file XML element
294       @param num the number of this rotor */
295   FGRotor(FGFDMExec *exec, Element* rotor_element, int num);
296
297   /// Destructor for FGRotor
298   ~FGRotor();
299
300   /** Returns the power required by the rotor. */
301   double GetPowerRequired(void)const { return PowerRequired; }
302
303   /** Returns the scalar thrust of the rotor, and adjusts the RPM value. */
304   double Calculate(double EnginePower);
305
306
307   /// Retrieves the RPMs of the rotor.
308   double GetRPM(void) const { return RPM; }
309   void   SetRPM(double rpm) { RPM = rpm; }
310   
311   /// Retrieves the RPMs of the Engine, as seen from this rotor.
312   double GetEngineRPM(void) const {return EngineRPM;} //{ return GearRatio*RPM; }
313   void SetEngineRPM(double rpm) {EngineRPM = rpm;} //{ RPM = rpm/GearRatio; }
314   /// Tells the rotor's gear ratio, usually the engine asks for this.
315   double GetGearRatio(void) { return GearRatio; }
316   /// Retrieves the thrust of the rotor.
317   double GetThrust(void) const { return Thrust; }
318
319   /// Retrieves the rotor's coning angle 
320   double GetA0(void) const { return a0; }
321   /// Retrieves the longitudinal flapping angle with respect to the rotor shaft
322   double GetA1(void) const { return a1s; }
323   /// Retrieves the lateral flapping angle with respect to the rotor shaft
324   double GetB1(void) const { return b1s; }
325
326   /// Retrieves the inflow ratio
327   double GetLambda(void) const { return lambda; }
328   /// Retrieves the tip-speed (aka advance) ratio
329   double GetMu(void) const { return mu; }
330   /// Retrieves the induced inflow ratio
331   double GetNu(void) const { return nu; }
332   /// Retrieves the induced velocity
333   double GetVi(void) const { return v_induced; }
334   /// Retrieves the thrust coefficient
335   double GetCT(void) const { return C_T; }
336   /// Retrieves the torque
337   double GetTorque(void) const { return Torque; }
338   
339   /// Downwash angle - currently only valid for a rotor that spins horizontally
340   double GetThetaDW(void) const { return theta_downwash; }
341   /// Downwash angle - currently only valid for a rotor that spins horizontally
342   double GetPhiDW(void) const { return phi_downwash; }
343
344   /// Retrieves the collective control input in radians.
345   double GetCollectiveCtrl(void) const { return CollectiveCtrl; }
346   /// Retrieves the lateral control input in radians.
347   double GetLateralCtrl(void) const { return LateralCtrl; }
348   /// Retrieves the longitudinal control input in radians.
349   double GetLongitudinalCtrl(void) const { return LongitudinalCtrl; }
350
351   /// Sets the collective control input in radians.
352   void SetCollectiveCtrl(double c) { CollectiveCtrl = c; }
353   /// Sets the lateral control input in radians.
354   void SetLateralCtrl(double c) { LateralCtrl = c; }
355   /// Sets the longitudinal control input in radians.
356   void SetLongitudinalCtrl(double c) { LongitudinalCtrl = c; }
357
358   // Stubs. Only main rotor RPM is returned
359   string GetThrusterLabels(int id, string delimeter);
360   string GetThrusterValues(int id, string delimeter);
361
362 private:
363
364   // assist in parameter retrieval
365   double ConfigValueConv( Element* e, const string& ename, double default_val=0.0, 
366                                       const string& unit = "", bool tell=false);
367
368   double ConfigValue( Element* e, const string& ename, double default_val=0.0,
369                                   bool tell=false);
370
371   void Configure(Element* rotor_element);
372
373   void CalcRotorState(void);
374
375   // rotor dynamics
376   void calc_flow_and_thrust(double theta_0, double Uw, double Ww, double flow_scale = 1.0);
377   void calc_coning_angle(double theta_0);
378   void calc_flapping_angles(double theta_0, const FGColumnVector3 &pqr_fus_w);
379   void calc_drag_and_side_forces(double theta_0);
380   void calc_torque(double theta_0);
381
382   // transformations
383   FGColumnVector3 hub_vel_body2ca( const FGColumnVector3 &uvw, const FGColumnVector3 &pqr, 
384                                    double a_ic = 0.0 , double b_ic = 0.0 );
385   FGColumnVector3 fus_angvel_body2ca( const FGColumnVector3 &pqr);
386   FGColumnVector3 body_forces(double a_ic = 0.0 , double b_ic = 0.0 );
387   FGColumnVector3 body_moments(double a_ic = 0.0 , double b_ic = 0.0 );
388
389   // interface
390   bool BindModel(void);
391   void Debug(int from);
392
393   // environment
394   double dt;
395   double rho;
396   Filter damp_hagl;
397
398   // configuration parameters
399   double Radius;
400   int    BladeNum;
401
402   // rpm control
403   double Sense;
404   double NominalRPM;
405   double MinimalRPM;
406   double MaximalRPM;
407   int    ExternalRPM;
408   int    RPMdefinition;
409   FGPropertyManager* ExtRPMsource;
410   double SourceGearRatio;
411
412   double BladeChord;
413   double LiftCurveSlope;
414   double BladeTwist;
415   double HingeOffset;
416   double BladeFlappingMoment;
417   double BladeMassMoment;
418   double PolarMoment;
419   double InflowLag;
420   double TipLossB;
421
422   double GroundEffectExp;
423   double GroundEffectShift;
424
425   // derived parameters
426   double LockNumberByRho;
427   double Solidity; // aka sigma
428   double R[5]; // Radius powers
429   double B[5]; // TipLossB powers
430
431   // Some of the calculations require shaft axes. So the
432   // thruster orientation (Tbo, with b for body) needs to be
433   // expressed/represented in helicopter shaft coordinates (Hsr).
434   FGMatrix33 InvTransform;
435   FGMatrix33 TboToHsr;
436   FGMatrix33 HsrToTbo;
437
438   // dynamic values
439   double RPM;
440   double Omega;          // must be > 0 
441   double beta_orient;    // rotor orientation angle (rad)
442   double a0;             // coning angle (rad)
443   double a_1, b_1, a_dw; // flapping angles
444   double a1s, b1s;       // cyclic flapping relative to shaft axes, /SH79/ eqn(43)
445   double H_drag, J_side; // Forces
446
447   double Torque;
448   double C_T;        // rotor thrust coefficient
449   double lambda;     // inflow ratio
450   double mu;         // tip-speed ratio 
451   double nu;         // induced inflow ratio
452   double v_induced;  // induced velocity, always positive [ft/s]
453
454   double theta_downwash;
455   double phi_downwash;
456
457   // control
458   eCtrlMapping ControlMap;
459   double CollectiveCtrl;
460   double LateralCtrl;
461   double LongitudinalCtrl;
462
463   // interaction with engine
464   FGTransmission *Transmission;
465   double EngineRPM;
466   double MaxBrakePower;
467   double GearLoss;
468   double GearMoment;
469
470 };
471
472 }
473 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
474 #endif