1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7 ------------- Copyright (C) 2010 T. Kreitler -------------
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
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
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.
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.
27 --------------------------------------------------------------------------------
28 01/01/10 T.Kreitler test implementation
30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
37 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
41 #include "FGThruster.h"
42 #include "math/FGTable.h"
43 #include "math/FGRungeKutta.h"
45 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
49 #define ID_ROTOR "$Id: FGRotor.h,v 1.6 2010/06/02 04:05:13 jberndt Exp $"
51 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
57 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
61 /** Models a rotor system. The default configuration consists of main and
62 tail rotor. A practical way to define the positions is to start with an
63 imaginary gear-box near the cg of the vehicle.
65 In this case the location in the thruster definition should be
66 approximately equal to the cg defined in the <tt>fdm_config/mass_balance</tt>
67 section. If the default orientation (roll=pitch=yaw=0) is used the
68 positions of the rotor hubs are now defined relative to the location
69 of the thruster (i.e. the cg-centered body coordinate system).
72 <h3>Configuration File Format:</h3>
74 <rotor name="{string}" variant="{string}">
75 <diameter unit="{LENGTH}"> {number} </diameter>
76 <numblades> {number} </numblades>
77 <xhub unit="{LENGTH}"> {number} </xhub>
78 <zhub unit="{LENGTH}"> {number} </zhub>
79 <nominalrpm> {number} </nominalrpm>
80 <minrpm> {number} </minrpm>
81 <chord unit="{LENGTH}"> {number} </chord>
82 <liftcurveslope Xunit="1/RAD"> {number} </liftcurveslope>
83 <flappingmoment unit="{MOMENT}"> {number} </flappingmoment>
84 <twist unit="{ANGLE}"> {number} </twist>
85 <massmoment Xunit="SLUG*FT"> {number} </massmoment>
86 <tiplossfactor> {number} </tiplossfactor>
87 <polarmoment unit="{MOMENT}"> {number}</polarmoment>
88 <inflowlag> {number} </inflowlag>
89 <shafttilt unit="{ANGLE}"> {number} </shafttilt>
90 <hingeoffset unit="{LENGTH}"> {number} </hingeoffset>
92 <diameter unit="{LENGTH}"> {number} </diameter>
93 <numblades> {number} </numblades>
94 <xhub unit="{LENGTH}">{number} </xhub>
95 <zhub unit="{LENGTH}">{number} </zhub>
96 <nominalrpm> {number} </nominalrpm>
97 <chord unit="{LENGTH}"> {number} </chord>
98 <liftcurveslope Xunit="1/RAD"> {number} </liftcurveslope>
99 <flappingmoment unit="{MOMENT}"> {number} </flappingmoment>
100 <twist unit="RAD"> {number} </twist>
101 <massmoment Xunit="SLUG*FT"> {number} </massmoment>
102 <tiplossfactor> {number} </tiplossfactor>
103 <inflowlag> {number} </inflowlag>
104 <hingeoffset unit="{LENGTH}"> {number} </hingeoffset>
105 <cantangle unit="{ANGLE}"> {number} </cantangle>
107 <cgroundeffect> {number} </cgroundeffect>
108 <groundeffectshift unit="{LENGTH}"> {number} </groundeffectshift>
111 // LENGTH means any of the supported units, same for ANGLE and MOMENT.
112 // Xunit-attributes are a hint for currently unsupported units, so
113 // values must be provided accordingly.
117 <h3>Configuration Parameters:</h3>
119 Brief description and the symbol frequently found in the literature.
122 \<diameter> - Rotor disk diameter (R).
123 \<numblades> - Number of blades (b).
124 \<xhub> - Relative height in body coordinate system, thus usually negative.
125 \<zhub> - Relative distance in body coordinate system, close to zero
126 for main rotor, and usually negative for the tail rotor.
127 \<nominalrpm> - RPM at which the rotor usally operates.
128 \<minrpm> - Lowest RPM generated by the code, optional.
129 \<chord> - Blade chord, (c).
130 \<liftcurveslope> - Slope of curve of section lift against section angle of attack,
132 \<flappingmoment> - Flapping moment of inertia (I_b).
133 \<twist> - Blade twist from root to tip, (theta_1).
134 \<massmoment> - Blade mass moment. (Biege/Widerstands-moment)
135 \<tiplossfactor> - Tip-loss factor. The Blade fraction that produces lift.
136 Value usually ranges between 0.95 - 1.0, optional (B).
137 \<polarmoment> - Moment of inertia for the whole rotor disk, optional.
138 \<inflowlag> - Rotor inflow time constant, sec.
139 \<shafttilt> - Orientation of the rotor shaft, negative angles define
140 a 'forward' tilt. Used by main rotor, optional.
141 \<hingeoffset> - Rotor flapping-hinge offset (e).
143 Experimental properties
145 \<cantangle> - Flapping hinge cantangle used by tail rotor, optional.
146 \<cgroundeffect> - Parameter for exponent in ground effect approximation. Value should
147 be in the range 0.2 - 0.35, 0.0 disables, optional.
148 \<groundeffectshift> - Further adjustment of ground effect.
154 The behavior of the rotor is controlled/influenced by 5 inputs.<ul>
155 <li> The power provided by the engine. This is handled by the regular engine controls.</li>
156 <li> The collective control input. This is read from the <tt>fdm</tt> property
157 <tt>propulsion/engine[x]/collective-ctrl-rad</tt>.</li>
158 <li> The lateral cyclic input. Read from
159 <tt>propulsion/engine[x]/lateral-ctrl-rad</tt>.</li>
160 <li> The longitudinal cyclic input. Read from
161 <tt>propulsion/engine[x]/longitudinal-ctrl-rad</tt>.</li>
162 <li> The tail collective (aka antitorque, aka pedal) control input. Read from
163 <tt>propulsion/engine[x]/antitorque-ctrl-rad</tt>.</li>
167 In order to keep the rotor speed constant, use of a RPM-Governor system is encouraged.
169 It is possible to use different orientation/locations for the rotor system, but then xhub
170 and zhub are no longer aligned to the body frame and need proper recalculation.
172 To model a standalone main rotor just omit the <tailrotor/> element. If you provide
173 a plain <tailrotor/> element all tail rotor parameters are estimated.
175 The 'sense' parameter from the thruster is interpreted as follows, sense=1 means
176 counter clockwise rotation of the main rotor, as viewed from above. This is as a far
177 as I know more popular than clockwise rotation, which is defined by setting sense to
178 -1 (to be honest, I'm just 99.9% sure that the orientation is handled properly).
180 Concerning coaxial designs: By providing the 'variant' attribute with value 'coaxial'
181 a Kamov-style rotor is modeled - i.e. the rotor produces no torque.
187 <dt>/SH79/</dt><dd>Shaugnessy, J. D., Deaux, Thomas N., and Yenni, Kenneth R.,
188 "Development and Validation of a Piloted Simulation of a
189 Helicopter and External Sling Load", NASA TP-1285, 1979.</dd>
190 <dt>/BA41/</dt><dd>Bailey,F.J.,Jr., "A Simplified Theoretical Method of Determining
191 the Characteristics of a Lifting Rotor in Forward Flight", NACA Rep.716, 1941.</dd>
192 <dt>/AM50/</dt><dd>Amer, Kenneth B.,"Theory of Helicopter Damping in Pitch or Roll and a
193 Comparison With Flight Measurements", NACA TN-2136, 1950.</dd>
194 <dt>/TA77/</dt><dd>Talbot, Peter D., Corliss, Lloyd D., "A Mathematical Force and Moment
195 Model of a UH-1H Helicopter for Flight Dynamics Simulations", NASA TM-73,254, 1977.</dd>
198 @author Thomas Kreitler
199 @version $Id: FGRotor.h,v 1.6 2010/06/02 04:05:13 jberndt Exp $
202 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
206 class FGRotor : public FGThruster {
208 enum eRotorFlags {eNone=0, eMain=1, eTail=2, eCoaxial=4, eRotCW=8} ;
213 void configure(int f, const rotor *xmain = NULL);
215 // assist in parameter retrieval
216 double cnf_elem(const string& ename, double default_val=0.0, const string& unit = "", bool tell=false);
217 double cnf_elem(const string& ename, double default_val=0.0, bool tell=false);
220 void calc_flow_and_thrust(double dt, double rho, double theta_0, double Uw, double Ww, double flow_scale = 1.0);
222 void calc_torque(double rho, double theta_0);
223 void calc_coning_angle(double rho, double theta_0);
224 void calc_flapping_angles(double rho, double theta_0, const FGColumnVector3 &pqr_fus_w);
225 void calc_drag_and_side_forces(double rho, double theta_0);
228 FGColumnVector3 hub_vel_body2ca( const FGColumnVector3 &uvw, const FGColumnVector3 &pqr,
229 double a_ic = 0.0 , double b_ic = 0.0 );
230 FGColumnVector3 fus_angvel_body2ca( const FGColumnVector3 &pqr);
232 FGColumnVector3 body_forces(double a_ic = 0.0 , double b_ic = 0.0 );
233 FGColumnVector3 body_moments(FGColumnVector3 F_h, double a_ic = 0.0 , double b_ic = 0.0 );
239 // used in flow calculation
240 // FGRK4 rk ; // use this after checking
244 // configuration parameters
247 double RelDistance_xhub ;
248 double RelShift_yhub ;
249 double RelHeight_zhub ;
253 double LiftCurveSlope ;
254 double BladeFlappingMoment ;
256 double BladeMassMoment ;
262 double HingeOffset_hover ;
268 // derived parameters
269 double LockNumberByRho ;
270 double solidity ; // aka sigma
271 double RpmRatio ; // main_to_tail, hmm
272 double R[5] ; // Radius powers
273 double B[6] ; // TipLossB powers
275 FGMatrix33 BodyToShaft ; // [S]T, see /SH79/ eqn(17,18)
276 FGMatrix33 ShaftToBody ; // [S]
280 double Omega ; // must be > 0
282 double a0 ; // coning angle (rad)
283 double a_1, b_1, a_dw ;
284 double a1s, b1s ; // cyclic flapping relative to shaft axes, /SH79/ eqn(43)
285 double H_drag, J_side ;
290 double lambda ; // inflow ratio
291 double mu ; // tip-speed ratio
292 double nu ; // induced inflow ratio
293 double v_induced ; // always positive [ft/s]
296 FGColumnVector3 force ;
297 FGColumnVector3 moment ;
300 // declare the problem function
301 class dnuFunction : public FGRungeKuttaProblem {
303 void update_params(rotor *r, double ct_t01, double fs, double w);
305 double pFunc(double x, double y);
307 double k_sat, ct_lambda, k_wor, k_theta, mu2, k_flowscale;
316 @param exec pointer to executive structure
317 @param rotor_element pointer to XML element in the config file
318 @param num the number of this rotor */
319 FGRotor(FGFDMExec *exec, Element* rotor_element, int num);
324 void SetRPM(double rpm) {RPM = rpm;}
326 /** Calculates forces and moments created by the rotor(s) and updates
327 vFn,vMn state variables. RPM changes are handled inside, too.
328 The RPM change is based on estimating the torque provided by the engine.
330 @param PowerAvailable here this is the thrust (not power) provided by a turbine
331 @return PowerAvailable */
332 double Calculate(double);
334 double GetRPM(void) const { return RPM; }
335 double GetDiameter(void) { return mr.Radius*2.0; }
337 // Stubs. Right now this rotor-to-engine interface is just a hack.
338 double GetTorque(void) { return 0.0; /* return mr.Torque;*/ }
339 double GetPowerRequired(void);
341 // Stubs. Only main rotor RPM is returned
342 string GetThrusterLabels(int id, string delimeter);
343 string GetThrusterValues(int id, string delimeter);
350 double Sense; // default is counter clockwise rotation of the main rotor (viewed from above)
351 bool tailRotorPresent;
353 void Debug(int from);
355 FGPropertyManager* PropertyManager;
364 double effective_tail_col; // /SH79/ eqn(47)
366 double ground_effect_exp;
367 double ground_effect_shift;
369 double hover_threshold;
372 // fdm imported controls
373 FGPropertyManager* prop_collective_ctrl;
374 FGPropertyManager* prop_lateral_ctrl;
375 FGPropertyManager* prop_longitudinal_ctrl;
376 FGPropertyManager* prop_antitorque_ctrl;
378 FGPropertyManager* prop_freewheel_factor;
379 FGPropertyManager* prop_rotorbrake;
382 double prop_inflow_ratio_lambda;
383 double prop_advance_ratio_mu;
384 double prop_inflow_ratio_induced_nu;
385 double prop_mr_torque;
386 double prop_coning_angle;
388 double prop_theta_downwash;
389 double prop_phi_downwash;
391 double prop_thrust_coefficient;
392 double prop_lift_coefficient;
394 double dt; // deltaT doesn't do the thing
397 int prop_DumpFlag; // causes 1-time dump on stdout
401 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%