]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/propulsion/FGRotor.h
Merge branch 'next' into durk-atc
[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.9 2011/03/10 01:35:25 dpculp 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   <chord unit="{LENGTH}"> {number} </chord>
72   <liftcurveslope Xunit="1/RAD"> {number} </liftcurveslope>
73   <twist unit="{ANGLE}"> {number} </twist>
74   <hingeoffset unit="{LENGTH}"> {number} </hingeoffset>
75   <flappingmoment unit="{MOMENT}"> {number} </flappingmoment>
76   <massmoment Xunit="SLUG*FT"> {number} </massmoment>
77   <polarmoment unit="{MOMENT}"> {number} </polarmoment>
78   <inflowlag> {number} </inflowlag>
79   <tiplossfactor> {number} </tiplossfactor>
80   <maxbrakepower unit="{POWER}"> {number} </maxbrakepower>
81
82   <controlmap> {MAIN|TAIL|TANDEM} </controlmap>
83   <ExternalRPM> {number} </ExternalRPM>
84
85   <groundeffectexp> {number} </groundeffectexp>
86   <groundeffectshift unit="{LENGTH}"> {number} </groundeffectshift>
87
88   <freewheelthresh> {number} </freewheelthresh>
89 </rotor>
90
91 //  LENGTH means any of the supported units, same for ANGLE and MOMENT.
92 //  Xunit-attributes are a hint for currently unsupported units, so
93 //  values must be provided accordingly.
94
95 @endcode
96
97 <h3>Configuration Parameters:</h3>
98
99   Brief description and the symbol frequently found in the literature.
100
101 <pre>
102     \<diameter>           - Rotor disk diameter (2x R).
103     \<numblades>          - Number of blades (b).
104     \<gearratio>          - Ratio of (engine rpm) / (rotor rpm), usually > 1.
105     \<nominalrpm>         - RPM at which the rotor usally operates. 
106     \<chord>              - Blade chord, (c).
107     \<liftcurveslope>     - Slope of curve of section lift against section angle of attack,
108                              per rad (a).
109     \<twist>              - Blade twist from root to tip, (theta_1).
110     \<hingeoffset>        - Rotor flapping-hinge offset (e).
111     \<flappingmoment>     - Flapping moment of inertia (I_b).
112     \<massmoment>         - Blade mass moment. Mass of a single blade times the blade's
113                              cg-distance from the hub, optional.
114     \<polarmoment>        - Moment of inertia for the whole rotor disk, optional.
115     \<inflowlag>          - Rotor inflow time constant, sec. Smaller values yield to quicker
116                               responses (typical values for main rotor: 0.1 - 0.2 s).
117     \<tiplossfactor>      - Tip-loss factor. The Blade fraction that produces lift.
118                               Value usually ranges between 0.95 - 1.0, optional (B).
119     \<maxbrakepower>      - Rotor brake, 20-30 hp should work for a mid size helicopter.
120
121     \<controlmap>         - Defines the control inputs used (see notes).
122     \<ExternalRPM>        - Links the rotor to another rotor, or an user controllable property.
123
124     Experimental properties
125     
126     \<groundeffectexp>    - Exponent for ground effect approximation. Values usually range from 0.04
127                             for large rotors to 0.1 for smaller ones. As a rule of thumb the effect 
128                             vanishes at a height 2-3 times the rotor diameter.
129                               formula used: exp ( - groundeffectexp * (height+groundeffectshift) )
130                             Omitting or setting to 0.0 disables the effect calculation.
131     \<groundeffectshift>  - Further adjustment of ground effect, approx. hub height or slightly above. 
132
133     \<freewheelthresh>    - Ratio of thruster power to engine power. The FWU will release when above
134                               the threshold. The value shouldn't be too close to 1.0, 1.5 seems ok.
135                               0 disables this feature, which is also the default.
136
137 </pre>
138
139 <h3>Notes:</h3>  
140
141   <h4>- Controls -</h4>
142
143     The behavior of the rotor is controlled/influenced by following inputs.<ul>
144       <li> The power provided by the engine. This is handled by the regular engine controls.</li>
145       <li> The collective control input. This is read from the <tt>fdm</tt> property 
146            <tt>propulsion/engine[x]/collective-ctrl-rad</tt>. See below for tail rotor</li>
147       <li> The lateral cyclic input. Read from
148            <tt>propulsion/engine[x]/lateral-ctrl-rad</tt>.</li>
149       <li> The longitudinal cyclic input. Read from 
150            <tt>propulsion/engine[x]/longitudinal-ctrl-rad</tt>.</li>
151       <li> The tail collective (aka antitorque, aka pedal) control input. Read from
152            <tt>propulsion/engine[x]/antitorque-ctrl-rad</tt> or 
153            <tt>propulsion/engine[x]/tail-collective-ctrl-rad</tt>.</li> 
154
155     </ul>
156
157   <h4>- Tail/tandem rotor -</h4>
158
159     Providing <tt>\<ExternalRPM\> 0 \</ExternalRPM\></tt> the tail rotor's RPM
160     is linked to to the main (=first, =0) rotor, and specifing
161     <tt>\<controlmap\> TAIL \</controlmap\></tt> tells this rotor to read the
162     collective input from <tt>propulsion/engine[1]/antitorque-ctrl-rad</tt>
163     (The TAIL-map ignores lateral and longitudinal input). The rotor needs to be 
164     attached to a dummy engine, e.g. an 1HP electrical engine.
165     A tandem rotor is setup analogous. 
166
167   <h4>- Sense -</h4>
168
169     The 'sense' parameter from the thruster is interpreted as follows, sense=1 means
170     counter clockwise rotation of the main rotor, as viewed from above. This is as a far
171     as I know more popular than clockwise rotation, which is defined by setting sense to
172     -1. Concerning coaxial designs - by setting 'sense' to zero, a Kamov-style rotor is
173     modeled (i.e. the rotor produces no torque).
174
175   <h4>- Engine issues -</h4>
176
177     In order to keep the rotor speed constant, use of a RPM-Governor system is 
178     encouraged (see examples).
179
180   <h4>- Development hints -</h4>
181
182     Setting <tt>\<ExternalRPM> -1 \</ExternalRPM></tt> the rotor's RPM is controlled  by
183     the <tt>propulsion/engine[x]/x-rpm-dict</tt> property. This feature can be useful
184     when developing a FDM.
185   
186
187 <h3>References:</h3>  
188
189     <dl>    
190     <dt>/SH79/</dt><dd>Shaugnessy, J. D., Deaux, Thomas N., and Yenni, Kenneth R.,
191               "Development and Validation of a Piloted Simulation of a 
192               Helicopter and External Sling Load",  NASA TP-1285, 1979.</dd>
193     <dt>/BA41/</dt><dd>Bailey,F.J.,Jr., "A Simplified Theoretical Method of Determining
194               the Characteristics of a Lifting Rotor in Forward Flight", NACA Rep.716, 1941.</dd>
195     <dt>/AM50/</dt><dd>Amer, Kenneth B.,"Theory of Helicopter Damping in Pitch or Roll and a
196               Comparison With Flight Measurements", NACA TN-2136, 1950.</dd>
197     <dt>/TA77/</dt><dd>Talbot, Peter D., Corliss, Lloyd D., "A Mathematical Force and Moment
198               Model of a UH-1H Helicopter for Flight Dynamics Simulations", NASA TM-73,254, 1977.</dd> 
199     <dt>/GE49/</dt><dd>Gessow, Alfred, Amer, Kenneth B. "An Introduction to the Physical 
200               Aspects of Helicopter Stability", NACA TN-1982, 1949.</dd>  
201     </dl>
202
203     @author Thomas Kreitler
204     @version $Id: FGRotor.h,v 1.9 2011/03/10 01:35:25 dpculp Exp $
205   */
206
207
208
209 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 CLASS DECLARATION
211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
212
213 class FGRotor :  public FGThruster {
214
215   enum eCtrlMapping {eMainCtrl=0, eTailCtrl, eTandemCtrl};
216
217 public:
218
219   /** Constructor for FGRotor.
220       @param exec a pointer to the main executive object
221       @param rotor_element a pointer to the thruster config file XML element
222       @param num the number of this rotor */
223   FGRotor(FGFDMExec *exec, Element* rotor_element, int num);
224
225   /// Destructor for FGRotor
226   ~FGRotor();
227
228   /** Returns the power required by the rotor. */
229   double GetPowerRequired(void)const { return PowerRequired; }
230
231   /** Returns the scalar thrust of the rotor, and adjusts the RPM value. */
232   double Calculate(double EnginePower);
233
234
235   /// Retrieves the RPMs of the rotor.
236   double GetRPM(void) const { return RPM; }
237   
238   // void   SetRPM(double rpm) { RPM = rpm; }
239   
240   /// Retrieves the RPMs of the Engine, as seen from this rotor.
241   double GetEngineRPM(void) const { return GearRatio*RPM; } // bit of a hack.
242   /// Tells the rotor's gear ratio, usually the engine asks for this.
243   double GetGearRatio(void) { return GearRatio; }
244   /// Retrieves the thrust of the rotor.
245   double GetThrust(void) const { return Thrust; }
246
247   /// Retrieves the rotor's coning angle 
248   double GetA0(void) const { return a0; }
249   /// Retrieves the longitudinal flapping angle with respect to the rotor shaft
250   double GetA1(void) const { return a1s; }
251   /// Retrieves the lateral flapping angle with respect to the rotor shaft
252   double GetB1(void) const { return b1s; }
253
254   /// Retrieves the inflow ratio
255   double GetLambda(void) const { return lambda; }
256   /// Retrieves the tip-speed (aka advance) ratio
257   double GetMu(void) const { return mu; }
258   /// Retrieves the induced inflow ratio
259   double GetNu(void) const { return nu; }
260   /// Retrieves the induced velocity
261   double GetVi(void) const { return v_induced; }
262   /// Retrieves the thrust coefficient
263   double GetCT(void) const { return C_T; }
264   /// Retrieves the torque
265   double GetTorque(void) const { return Torque; }
266   /// Retrieves the state of the free-wheeling-unit (FWU).
267   double GetFreeWheelTransmission(void) const { return FreeWheelTransmission; }
268   
269   /// Downwash angle - currently only valid for a rotor that spins horizontally
270   double GetThetaDW(void) const { return theta_downwash; }
271   /// Downwash angle - currently only valid for a rotor that spins horizontally
272   double GetPhiDW(void) const { return phi_downwash; }
273
274   /// Retrieves the collective control input in radians.
275   double GetCollectiveCtrl(void) const { return CollectiveCtrl; }
276   /// Retrieves the lateral control input in radians.
277   double GetLateralCtrl(void) const { return LateralCtrl; }
278   /// Retrieves the longitudinal control input in radians.
279   double GetLongitudinalCtrl(void) const { return LongitudinalCtrl; }
280   /// Retrieves the normalized brake control input.
281   double GetBrakeCtrl(void) const { return BrakeCtrlNorm; }
282
283   /// Sets the collective control input in radians.
284   void SetCollectiveCtrl(double c) { CollectiveCtrl = c; }
285   /// Sets the lateral control input in radians.
286   void SetLateralCtrl(double c) { LateralCtrl = c; }
287   /// Sets the longitudinal control input in radians.
288   void SetLongitudinalCtrl(double c) { LongitudinalCtrl = c; }
289   /// Sets the normalized brake control input.
290   void SetBrakeCtrl(double c) { BrakeCtrlNorm = c; }
291
292   // Stubs. Only main rotor RPM is returned
293   string GetThrusterLabels(int id, string delimeter);
294   string GetThrusterValues(int id, string delimeter);
295
296 private:
297
298   // assist in parameter retrieval
299   double ConfigValueConv( Element* e, const string& ename, double default_val=0.0, 
300                                       const string& unit = "", bool tell=false);
301
302   double ConfigValue( Element* e, const string& ename, double default_val=0.0,
303                                   bool tell=false);
304
305   void Configure(Element* rotor_element);
306
307   // true entry points
308   void CalcStatePart1(void);
309   void CalcStatePart2(double PowerAvailable);
310
311   // rotor dynamics
312   void calc_flow_and_thrust(double theta_0, double Uw, double Ww, double flow_scale = 1.0);
313   void calc_coning_angle(double theta_0);
314   void calc_flapping_angles(double theta_0, const FGColumnVector3 &pqr_fus_w);
315   void calc_drag_and_side_forces(double theta_0);
316   void calc_torque(double theta_0);
317
318   void calc_freewheel_state(double pwr_in, double pwr_out);
319
320   // transformations
321   FGColumnVector3 hub_vel_body2ca( const FGColumnVector3 &uvw, const FGColumnVector3 &pqr, 
322                                    double a_ic = 0.0 , double b_ic = 0.0 );
323   FGColumnVector3 fus_angvel_body2ca( const FGColumnVector3 &pqr);
324   FGColumnVector3 body_forces(double a_ic = 0.0 , double b_ic = 0.0 );
325   FGColumnVector3 body_moments(double a_ic = 0.0 , double b_ic = 0.0 );
326
327   // interface
328   bool BindModel(void);
329   void Debug(int from);
330
331   // environment
332   double dt;
333   double rho;
334   Filter damp_hagl;
335
336   // configuration parameters
337   double Radius;
338   int    BladeNum;
339
340   double Sense;
341   double NominalRPM;
342   int    ExternalRPM;
343   int    RPMdefinition;
344   FGPropertyManager* ExtRPMsource;
345
346   double BladeChord;
347   double LiftCurveSlope;
348   double BladeTwist;
349   double HingeOffset;
350   double BladeFlappingMoment;
351   double BladeMassMoment;
352   double PolarMoment;
353   double InflowLag;
354   double TipLossB;
355
356   double GroundEffectExp;
357   double GroundEffectShift;
358
359   // derived parameters
360   double LockNumberByRho;
361   double Solidity; // aka sigma
362   double R[5]; // Radius powers
363   double B[5]; // TipLossB powers
364
365   // Some of the calculations require shaft axes. So the
366   // thruster orientation (Tbo, with b for body) needs to be
367   // expressed/represented in helicopter shaft coordinates (Hsr).
368   FGMatrix33 InvTransform;
369   FGMatrix33 TboToHsr;
370   FGMatrix33 HsrToTbo;
371
372   // dynamic values
373   double RPM;
374   double Omega;          // must be > 0 
375   double beta_orient;    // rotor orientation angle (rad)
376   double a0;             // coning angle (rad)
377   double a_1, b_1, a_dw; // flapping angles
378   double a1s, b1s;       // cyclic flapping relative to shaft axes, /SH79/ eqn(43)
379   double H_drag, J_side; // Forces
380
381   double Torque;
382   double C_T;        // rotor thrust coefficient
383   double lambda;     // inflow ratio
384   double mu;         // tip-speed ratio 
385   double nu;         // induced inflow ratio
386   double v_induced;  // induced velocity, always positive [ft/s]
387
388   double theta_downwash;
389   double phi_downwash;
390
391   // control
392   eCtrlMapping ControlMap;
393   double CollectiveCtrl;
394   double LateralCtrl;
395   double LongitudinalCtrl;
396
397   double BrakeCtrlNorm, MaxBrakePower;
398
399   // free-wheeling-unit (FWU)
400   int    FreeWheelPresent;        // 'installed' or not
401   double FreeWheelThresh;         // when to release
402   Filter FreeWheelLag;
403   double FreeWheelTransmission;   // state, 0: free, 1:locked
404
405
406 };
407
408 }
409 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
410 #endif