Branch data Line data Source code
1 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 : :
3 : : Module: FGAerodynamics.cpp
4 : : Author: Jon S. Berndt
5 : : Date started: 09/13/00
6 : : Purpose: Encapsulates the aerodynamic forces
7 : :
8 : : ------------- Copyright (C) 2000 Jon S. Berndt (jon@jsbsim.org) -------------
9 : :
10 : : This program is free software; you can redistribute it and/or modify it under
11 : : the terms of the GNU Lesser General Public License as published by the Free Software
12 : : Foundation; either version 2 of the License, or (at your option) any later
13 : : version.
14 : :
15 : : This program is distributed in the hope that it will be useful, but WITHOUT
16 : : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 : : FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18 : : details.
19 : :
20 : : You should have received a copy of the GNU Lesser General Public License along with
21 : : this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22 : : Place - Suite 330, Boston, MA 02111-1307, USA.
23 : :
24 : : Further information about the GNU Lesser General Public License can also be found on
25 : : the world wide web at http://www.gnu.org.
26 : :
27 : : FUNCTIONAL DESCRIPTION
28 : : --------------------------------------------------------------------------------
29 : :
30 : : HISTORY
31 : : --------------------------------------------------------------------------------
32 : : 09/13/00 JSB Created
33 : : 04/22/01 JSB Moved code into here from FGAircraft
34 : :
35 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 : : INCLUDES
37 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
38 : :
39 : : #include <iostream>
40 : : #include <sstream>
41 : : #include <iomanip>
42 : : #include <cstdlib>
43 : : #include <FGFDMExec.h>
44 : : #include "FGAerodynamics.h"
45 : : #include "FGPropagate.h"
46 : : #include "FGAircraft.h"
47 : : #include "FGAuxiliary.h"
48 : : #include "FGMassBalance.h"
49 : : #include "input_output/FGPropertyManager.h"
50 : :
51 : : using namespace std;
52 : :
53 : : namespace JSBSim {
54 : :
55 : : static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.31 2009/11/28 14:30:11 andgi Exp $";
56 : : static const char *IdHdr = ID_AERODYNAMICS;
57 : :
58 : : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59 : : CLASS IMPLEMENTATION
60 : : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
61 : :
62 : :
63 : 2 : FGAerodynamics::FGAerodynamics(FGFDMExec* FDMExec) : FGModel(FDMExec)
64 : : {
65 : 1 : Name = "FGAerodynamics";
66 : :
67 : 1 : AxisIdx["DRAG"] = 0;
68 : 1 : AxisIdx["SIDE"] = 1;
69 : 1 : AxisIdx["LIFT"] = 2;
70 : 1 : AxisIdx["ROLL"] = 3;
71 : 1 : AxisIdx["PITCH"] = 4;
72 : 1 : AxisIdx["YAW"] = 5;
73 : :
74 : 1 : AxisIdx["AXIAL"] = 0;
75 : 1 : AxisIdx["NORMAL"] = 2;
76 : :
77 : 1 : AxisIdx["X"] = 0;
78 : 1 : AxisIdx["Y"] = 1;
79 : 1 : AxisIdx["Z"] = 2;
80 : :
81 : 1 : axisType = atNone;
82 : :
83 [ + + ][ # # ]: 7 : Coeff = new CoeffArray[6];
84 : :
85 : 1 : impending_stall = stall_hyst = 0.0;
86 : 1 : alphaclmin = alphaclmax = 0.0;
87 : 1 : alphahystmin = alphahystmax = 0.0;
88 : 1 : clsq = lod = 0.0;
89 : 1 : alphaw = 0.0;
90 : 1 : bi2vel = ci2vel = 0.0;
91 : 1 : AeroRPShift = 0;
92 : 1 : vDeltaRP.InitMatrix();
93 : :
94 : 1 : bind();
95 : :
96 : 1 : Debug(0);
97 : 1 : }
98 : :
99 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100 : :
101 : 1 : FGAerodynamics::~FGAerodynamics()
102 : : {
103 : : unsigned int i,j;
104 : :
105 [ + + ][ # # ]: 7 : for (i=0; i<6; i++)
106 [ + + ][ # # ]: 9 : for (j=0; j<Coeff[i].size(); j++)
107 [ + - ][ # # ]: 3 : delete Coeff[i][j];
108 : :
109 [ + - ][ + + ]: 7 : delete[] Coeff;
[ # # ][ # # ]
110 : :
111 [ - + ][ # # ]: 1 : delete AeroRPShift;
112 : :
113 : 1 : Debug(1);
114 : 2 : }
115 : :
116 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
117 : :
118 : 1 : bool FGAerodynamics::InitModel(void)
119 : : {
120 [ - + ]: 1 : if (!FGModel::InitModel()) return false;
121 : :
122 : 1 : impending_stall = stall_hyst = 0.0;
123 : 1 : alphaclmin = alphaclmax = 0.0;
124 : 1 : alphahystmin = alphahystmax = 0.0;
125 : 1 : clsq = lod = 0.0;
126 : 1 : alphaw = 0.0;
127 : 1 : bi2vel = ci2vel = 0.0;
128 : 1 : AeroRPShift = 0;
129 : 1 : vDeltaRP.InitMatrix();
130 : :
131 : 1 : return true;
132 : : }
133 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 : :
135 : 54005 : bool FGAerodynamics::Run(void)
136 : : {
137 : : unsigned int axis_ctr, ctr;
138 : : double alpha, twovel;
139 : :
140 [ - + ]: 54005 : if (FGModel::Run()) return true;
141 [ - + ]: 54005 : if (FDMExec->Holding()) return false; // if paused don't execute
142 : :
143 : 54005 : RunPreFunctions();
144 : :
145 : : // calculate some oft-used quantities for speed
146 : :
147 : 108010 : twovel = 2*Auxiliary->GetVt();
148 [ + + ]: 54005 : if (twovel != 0) {
149 : 108006 : bi2vel = Aircraft->GetWingSpan() / twovel;
150 : 54003 : ci2vel = Aircraft->Getcbar() / twovel;
151 : : }
152 : 162015 : alphaw = Auxiliary->Getalpha() + Aircraft->GetWingIncidence();
153 : 108010 : alpha = Auxiliary->Getalpha();
154 : 162015 : qbar_area = Aircraft->GetWingArea() * Auxiliary->Getqbar();
155 : :
156 [ - + ]: 54005 : if (alphaclmax != 0) {
157 [ # # ]: 0 : if (alpha > 0.85*alphaclmax) {
158 : 0 : impending_stall = 10*(alpha/alphaclmax - 0.85);
159 : : } else {
160 : 0 : impending_stall = 0;
161 : : }
162 : : }
163 : :
164 [ - + ][ # # ]: 54005 : if (alphahystmax != 0.0 && alphahystmin != 0.0) {
165 [ # # ]: 0 : if (alpha > alphahystmax) {
166 : 0 : stall_hyst = 1;
167 [ # # ]: 0 : } else if (alpha < alphahystmin) {
168 : 0 : stall_hyst = 0;
169 : : }
170 : : }
171 : :
172 : 54005 : vFw.InitMatrix();
173 : 54005 : vFnative.InitMatrix();
174 : :
175 [ + + ]: 216020 : for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
176 [ + + ]: 324030 : for (ctr=0; ctr < Coeff[axis_ctr].size(); ctr++) {
177 : 162015 : vFnative(axis_ctr+1) += Coeff[axis_ctr][ctr]->GetValue();
178 : : }
179 : : }
180 : :
181 : : // Note that we still need to convert to wind axes here, because it is
182 : : // used in the L/D calculation, and we still may want to look at Lift
183 : : // and Drag.
184 : :
185 [ - + - - ]: 54005 : switch (axisType) {
186 : : case atBodyXYZ: // Forces already in body axes; no manipulation needed
187 : 0 : vFw = GetTb2w()*vFnative;
188 : 0 : vForces = vFnative;
189 : : break;
190 : : case atLiftDrag: // Copy forces into wind axes
191 : 54005 : vFw = vFnative;
192 : 162015 : vFw(eDrag)*=-1; vFw(eLift)*=-1;
193 : 54005 : vForces = GetTw2b()*vFw;
194 : : break;
195 : : case atAxialNormal: // Convert native forces into Axial|Normal|Side system
196 : 0 : vFw = GetTb2w()*vFnative;
197 : 0 : vFnative(eX)*=-1; vFnative(eZ)*=-1;
198 : 0 : vForces = vFnative;
199 : : break;
200 : : default:
201 : : cerr << endl << " A proper axis type has NOT been selected. Check "
202 : 0 : << "your aerodynamics definition." << endl;
203 : 0 : exit(-1);
204 : : }
205 : :
206 : : // Calculate aerodynamic reference point shift, if any
207 [ - + ]: 54005 : if (AeroRPShift) vDeltaRP(eX) = AeroRPShift->GetValue()*Aircraft->Getcbar()*12.0;
208 : :
209 : : // Calculate lift coefficient squared
210 [ + + ]: 54005 : if ( Auxiliary->Getqbar() > 0) {
211 : 216012 : clsq = vFw(eLift) / (Aircraft->GetWingArea()*Auxiliary->Getqbar());
212 : 54003 : clsq *= clsq;
213 : : }
214 : :
215 : : // Calculate lift Lift over Drag
216 [ + + ]: 54005 : if ( fabs(vFw(eDrag)) > 0.0) lod = fabs( vFw(eLift) / vFw(eDrag) );
217 : :
218 : 54005 : vDXYZcg = MassBalance->StructuralToBody(Aircraft->GetXYZrp() + vDeltaRP);
219 : :
220 : 108010 : vMoments = vDXYZcg*vForces; // M = r X F
221 : :
222 [ + + ]: 216020 : for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
223 [ - + ]: 162015 : for (ctr = 0; ctr < Coeff[axis_ctr+3].size(); ctr++) {
224 : 0 : vMoments(axis_ctr+1) += Coeff[axis_ctr+3][ctr]->GetValue();
225 : : }
226 : : }
227 : :
228 : 54005 : RunPostFunctions();
229 : :
230 : 54005 : return false;
231 : : }
232 : :
233 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234 : : //
235 : : // From Stevens and Lewis, "Aircraft Control and Simulation", 3rd Ed., the
236 : : // transformation from body to wind axes is defined (where "a" is alpha and "B"
237 : : // is beta):
238 : : //
239 : : // cos(a)*cos(B) sin(B) sin(a)*cos(B)
240 : : // -cos(a)*sin(B) cos(B) -sin(a)*sin(B)
241 : : // -sin(a) 0 cos(a)
242 : : //
243 : : // The transform from wind to body axes is then,
244 : : //
245 : : // cos(a)*cos(B) -cos(a)*sin(B) -sin(a)
246 : : // sin(B) cos(B) 0
247 : : // sin(a)*cos(B) -sin(a)*sin(B) cos(a)
248 : :
249 : 54005 : FGMatrix33& FGAerodynamics::GetTw2b(void)
250 : : {
251 : : double ca, cb, sa, sb;
252 : :
253 : 108010 : double alpha = Auxiliary->Getalpha();
254 : 108010 : double beta = Auxiliary->Getbeta();
255 : :
256 : 54005 : ca = cos(alpha);
257 : 54005 : sa = sin(alpha);
258 : 54005 : cb = cos(beta);
259 : 54005 : sb = sin(beta);
260 : :
261 : 108010 : mTw2b(1,1) = ca*cb;
262 : 108010 : mTw2b(1,2) = -ca*sb;
263 : 108010 : mTw2b(1,3) = -sa;
264 : 108010 : mTw2b(2,1) = sb;
265 : 108010 : mTw2b(2,2) = cb;
266 : 108010 : mTw2b(2,3) = 0.0;
267 : 108010 : mTw2b(3,1) = sa*cb;
268 : 108010 : mTw2b(3,2) = -sa*sb;
269 : 108010 : mTw2b(3,3) = ca;
270 : :
271 : 54005 : return mTw2b;
272 : : }
273 : :
274 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275 : :
276 : 54005 : FGMatrix33& FGAerodynamics::GetTb2w(void)
277 : : {
278 : : double alpha,beta;
279 : : double ca, cb, sa, sb;
280 : :
281 : 108010 : alpha = Auxiliary->Getalpha();
282 : 108010 : beta = Auxiliary->Getbeta();
283 : :
284 : 54005 : ca = cos(alpha);
285 : 54005 : sa = sin(alpha);
286 : 54005 : cb = cos(beta);
287 : 54005 : sb = sin(beta);
288 : :
289 : 108010 : mTb2w(1,1) = ca*cb;
290 : 108010 : mTb2w(1,2) = sb;
291 : 108010 : mTb2w(1,3) = sa*cb;
292 : 108010 : mTb2w(2,1) = -ca*sb;
293 : 108010 : mTb2w(2,2) = cb;
294 : 108010 : mTb2w(2,3) = -sa*sb;
295 : 108010 : mTb2w(3,1) = -sa;
296 : 108010 : mTb2w(3,2) = 0.0;
297 : 108010 : mTb2w(3,3) = ca;
298 : :
299 : 54005 : return mTb2w;
300 : : }
301 : :
302 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303 : :
304 : 1 : bool FGAerodynamics::Load(Element *element)
305 : : {
306 : 1 : string parameter, axis, scratch;
307 : 1 : string scratch_unit="";
308 : 1 : string fname="", file="";
309 : : Element *temp_element, *axis_element, *function_element;
310 : :
311 : 1 : string separator = "/";
312 : :
313 : 2 : fname = element->GetAttributeValue("file");
314 [ - + ]: 1 : if (!fname.empty()) {
315 : 0 : file = FDMExec->GetFullAircraftPath() + separator + fname;
316 : 0 : document = LoadXMLDocument(file);
317 : : } else {
318 : 1 : document = element;
319 : : }
320 : :
321 : 1 : FGModel::Load(document); // Perform base class Pre-Load
322 : :
323 : 1 : DetermineAxisSystem(); // Detemine if Lift/Side/Drag, etc. is used.
324 : :
325 : 1 : Debug(2);
326 : :
327 [ - + ]: 1 : if ((temp_element = document->FindElement("alphalimits"))) {
328 : 0 : scratch_unit = temp_element->GetAttributeValue("unit");
329 [ # # ]: 0 : if (scratch_unit.empty()) scratch_unit = "RAD";
330 : 0 : alphaclmin = temp_element->FindElementValueAsNumberConvertFromTo("min", scratch_unit, "RAD");
331 : 0 : alphaclmax = temp_element->FindElementValueAsNumberConvertFromTo("max", scratch_unit, "RAD");
332 : : }
333 : :
334 [ - + ]: 1 : if ((temp_element = document->FindElement("hysteresis_limits"))) {
335 : 0 : scratch_unit = temp_element->GetAttributeValue("unit");
336 [ # # ]: 0 : if (scratch_unit.empty()) scratch_unit = "RAD";
337 : 0 : alphahystmin = temp_element->FindElementValueAsNumberConvertFromTo("min", scratch_unit, "RAD");
338 : 0 : alphahystmax = temp_element->FindElementValueAsNumberConvertFromTo("max", scratch_unit, "RAD");
339 : : }
340 : :
341 [ - + ]: 1 : if ((temp_element = document->FindElement("aero_ref_pt_shift_x"))) {
342 : 0 : function_element = temp_element->FindElement("function");
343 : 0 : AeroRPShift = new FGFunction(PropertyManager, function_element);
344 : : }
345 : :
346 : 1 : axis_element = document->FindElement("axis");
347 [ + + ]: 7 : while (axis_element) {
348 : : CoeffArray ca;
349 : 12 : axis = axis_element->GetAttributeValue("name");
350 : 6 : function_element = axis_element->FindElement("function");
351 [ + + ]: 9 : while (function_element) {
352 : 6 : ca.push_back( new FGFunction(PropertyManager, function_element) );
353 : 3 : function_element = axis_element->FindNextElement("function");
354 : : }
355 : 6 : Coeff[AxisIdx[axis]] = ca;
356 : 6 : axis_element = document->FindNextElement("axis");
357 : : }
358 : :
359 : 1 : PostLoad(document, PropertyManager); // Perform base class Post-Load
360 : :
361 : 1 : return true;
362 : : }
363 : :
364 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
365 : : //
366 : : // This private class function checks to verify consistency in the choice of
367 : : // aerodynamic axes used in the config file. One set of LIFT|DRAG|SIDE, or
368 : : // X|Y|Z, or AXIAL|NORMAL|SIDE must be chosen; mixed system axes are not allowed.
369 : : // Note that if the "SIDE" axis specifier is entered first in a config file,
370 : : // a warning message will be given IF the AXIAL|NORMAL specifiers are also given.
371 : : // This is OK, and the warning is due to the SIDE specifier used for both
372 : : // the Lift/Drag and Axial/Normal axis systems.
373 : :
374 : 1 : void FGAerodynamics::DetermineAxisSystem()
375 : : {
376 : 1 : Element* axis_element = document->FindElement("axis");
377 : 1 : string axis;
378 [ + + ]: 7 : while (axis_element) {
379 : 12 : axis = axis_element->GetAttributeValue("name");
380 [ + + + + : 15 : if (axis == "LIFT" || axis == "DRAG" || axis == "SIDE") {
+ + ][ + + ]
381 [ + + ]: 3 : if (axisType == atNone) axisType = atLiftDrag;
382 [ - + ]: 2 : else if (axisType != atLiftDrag) {
383 : : cerr << endl << " Mixed aerodynamic axis systems have been used in the"
384 : 0 : << " aircraft config file." << endl;
385 : : }
386 [ + - - + ]: 6 : } else if (axis == "AXIAL" || axis == "NORMAL") {
[ - + ]
387 [ # # ]: 0 : if (axisType == atNone) axisType = atAxialNormal;
388 [ # # ]: 0 : else if (axisType != atAxialNormal) {
389 : : cerr << endl << " Mixed aerodynamic axis systems have been used in the"
390 : 0 : << " aircraft config file." << endl;
391 : : }
392 [ + - + - : 9 : } else if (axis == "X" || axis == "Y" || axis == "Z") {
- + ][ - + ]
393 [ # # ]: 0 : if (axisType == atNone) axisType = atBodyXYZ;
394 [ # # ]: 0 : else if (axisType != atBodyXYZ) {
395 : : cerr << endl << " Mixed aerodynamic axis systems have been used in the"
396 : 0 : << " aircraft config file." << endl;
397 : : }
398 [ + + + + : 6 : } else if (axis != "ROLL" && axis != "PITCH" && axis != "YAW") { // error
- + ][ - + ]
399 : : cerr << endl << " An unknown axis type, " << axis << " has been specified"
400 : 0 : << " in the aircraft configuration file." << endl;
401 : 0 : exit(-1);
402 : : }
403 : 6 : axis_element = document->FindNextElement("axis");
404 : : }
405 [ - + ]: 1 : if (axisType == atNone) {
406 : 0 : axisType = atLiftDrag;
407 : : cerr << endl << " The aerodynamic axis system has been set by default"
408 : 0 : << " to the Lift/Side/Drag system." << endl;
409 : 1 : }
410 : 1 : }
411 : :
412 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
413 : :
414 : 0 : string FGAerodynamics::GetCoefficientStrings(const string& delimeter) const
415 : : {
416 : 0 : string CoeffStrings = "";
417 : 0 : bool firstime = true;
418 : : unsigned int axis, sd;
419 : :
420 [ # # ]: 0 : for (axis = 0; axis < 6; axis++) {
421 [ # # ]: 0 : for (sd = 0; sd < Coeff[axis].size(); sd++) {
422 [ # # ]: 0 : if (firstime) {
423 : 0 : firstime = false;
424 : : } else {
425 : 0 : CoeffStrings += delimeter;
426 : : }
427 : 0 : CoeffStrings += Coeff[axis][sd]->GetName();
428 : : }
429 : : }
430 : 0 : return CoeffStrings;
431 : : }
432 : :
433 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434 : :
435 : 0 : string FGAerodynamics::GetCoefficientValues(const string& delimeter) const
436 : : {
437 : 0 : ostringstream buf;
438 : :
439 [ # # ]: 0 : for (unsigned int axis = 0; axis < 6; axis++) {
440 [ # # ]: 0 : for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) {
441 [ # # ]: 0 : if (buf.tellp() > 0) buf << delimeter;
442 : 0 : buf << setw(9) << Coeff[axis][sd]->GetValue();
443 : : }
444 : : }
445 : :
446 : 0 : return buf.str();
447 : : }
448 : :
449 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450 : :
451 : 1 : void FGAerodynamics::bind(void)
452 : : {
453 : : typedef double (FGAerodynamics::*PMF)(int) const;
454 : :
455 : : PropertyManager->Tie("forces/fbx-aero-lbs", this,1,
456 : 1 : (PMF)&FGAerodynamics::GetForces);
457 : : PropertyManager->Tie("forces/fby-aero-lbs", this,2,
458 : 1 : (PMF)&FGAerodynamics::GetForces);
459 : : PropertyManager->Tie("forces/fbz-aero-lbs", this,3,
460 : 1 : (PMF)&FGAerodynamics::GetForces);
461 : : PropertyManager->Tie("moments/l-aero-lbsft", this,1,
462 : 1 : (PMF)&FGAerodynamics::GetMoments);
463 : : PropertyManager->Tie("moments/m-aero-lbsft", this,2,
464 : 1 : (PMF)&FGAerodynamics::GetMoments);
465 : : PropertyManager->Tie("moments/n-aero-lbsft", this,3,
466 : 1 : (PMF)&FGAerodynamics::GetMoments);
467 : : PropertyManager->Tie("forces/fwx-aero-lbs", this,1,
468 : 1 : (PMF)&FGAerodynamics::GetvFw);
469 : : PropertyManager->Tie("forces/fwy-aero-lbs", this,2,
470 : 1 : (PMF)&FGAerodynamics::GetvFw);
471 : : PropertyManager->Tie("forces/fwz-aero-lbs", this,3,
472 : 1 : (PMF)&FGAerodynamics::GetvFw);
473 : : PropertyManager->Tie("forces/lod-norm", this,
474 : 1 : &FGAerodynamics::GetLoD);
475 : : PropertyManager->Tie("aero/cl-squared", this,
476 : 1 : &FGAerodynamics::GetClSquared);
477 : 1 : PropertyManager->Tie("aero/qbar-area", &qbar_area);
478 : : PropertyManager->Tie("aero/alpha-max-rad", this,
479 : : &FGAerodynamics::GetAlphaCLMax,
480 : : &FGAerodynamics::SetAlphaCLMax,
481 : 1 : true);
482 : : PropertyManager->Tie("aero/alpha-min-rad", this,
483 : : &FGAerodynamics::GetAlphaCLMin,
484 : : &FGAerodynamics::SetAlphaCLMin,
485 : 1 : true);
486 : : PropertyManager->Tie("aero/bi2vel", this,
487 : 1 : &FGAerodynamics::GetBI2Vel);
488 : : PropertyManager->Tie("aero/ci2vel", this,
489 : 1 : &FGAerodynamics::GetCI2Vel);
490 : : PropertyManager->Tie("aero/alpha-wing-rad", this,
491 : 1 : &FGAerodynamics::GetAlphaW);
492 : : PropertyManager->Tie("systems/stall-warn-norm", this,
493 : 1 : &FGAerodynamics::GetStallWarn);
494 : : PropertyManager->Tie("aero/stall-hyst-norm", this,
495 : 1 : &FGAerodynamics::GetHysteresisParm);
496 : 1 : }
497 : :
498 : : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499 : : // The bitmasked value choices are as follows:
500 : : // unset: In this case (the default) JSBSim would only print
501 : : // out the normally expected messages, essentially echoing
502 : : // the config files as they are read. If the environment
503 : : // variable is not set, debug_lvl is set to 1 internally
504 : : // 0: This requests JSBSim not to output any messages
505 : : // whatsoever.
506 : : // 1: This value explicity requests the normal JSBSim
507 : : // startup messages
508 : : // 2: This value asks for a message to be printed out when
509 : : // a class is instantiated
510 : : // 4: When this value is set, a message is displayed when a
511 : : // FGModel object executes its Run() method
512 : : // 8: When this value is set, various runtime state variables
513 : : // are printed out periodically
514 : : // 16: When set various parameters are sanity checked and
515 : : // a message is printed out when they go out of bounds
516 : :
517 : 3 : void FGAerodynamics::Debug(int from)
518 : : {
519 [ + - ]: 3 : if (debug_lvl <= 0) return;
520 : :
521 [ + - ]: 3 : if (debug_lvl & 1) { // Standard console startup message output
522 [ + + ]: 3 : if (from == 2) { // Loader
523 [ + - - - : 1 : switch (axisType) {
- ]
524 : : case (atLiftDrag):
525 : 1 : cout << endl << " Aerodynamics (Lift|Side|Drag axes):" << endl << endl;
526 : : break;
527 : : case (atAxialNormal):
528 : 0 : cout << endl << " Aerodynamics (Axial|Side|Normal axes):" << endl << endl;
529 : : break;
530 : : case (atBodyXYZ):
531 : 0 : cout << endl << " Aerodynamics (X|Y|Z axes):" << endl << endl;
532 : : break;
533 : : case (atNone):
534 : 0 : cout << endl << " Aerodynamics (undefined axes):" << endl << endl;
535 : : break;
536 : : }
537 : : }
538 : : }
539 [ - + ]: 3 : if (debug_lvl & 2 ) { // Instantiation/Destruction notification
540 [ # # ]: 0 : if (from == 0) cout << "Instantiated: FGAerodynamics" << endl;
541 [ # # ]: 0 : if (from == 1) cout << "Destroyed: FGAerodynamics" << endl;
542 : : }
543 : 3 : if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
544 : : }
545 : 3 : if (debug_lvl & 8 ) { // Runtime state variables
546 : : }
547 : 3 : if (debug_lvl & 16) { // Sanity checking
548 : : }
549 [ - + ]: 3 : if (debug_lvl & 64) {
550 [ # # ]: 0 : if (from == 0) { // Constructor
551 : 0 : cout << IdSrc << endl;
552 : 0 : cout << IdHdr << endl;
553 : : }
554 : : }
555 : : }
556 : :
557 [ + + ][ + - ]: 12 : } // namespace JSBSim
|