JSBSim Flight Dynamics Model  1.0 (02 March 2017)
An Open Source Flight Dynamics and Control Software Library in C++
FGFCS.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3  Module: FGFCS.cpp
4  Author: Jon Berndt
5  Date started: 12/12/98
6  Purpose: Model the flight controls
7  Called by: FDMExec
8 
9  ------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
10 
11  This program is free software; you can redistribute it and/or modify it under
12  the terms of the GNU Lesser General Public License as published by the Free Software
13  Foundation; either version 2 of the License, or (at your option) any later
14  version.
15 
16  This program is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
19  details.
20 
21  You should have received a copy of the GNU Lesser General Public License along with
22  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23  Place - Suite 330, Boston, MA 02111-1307, USA.
24 
25  Further information about the GNU Lesser General Public License can also be found on
26  the world wide web at http://www.gnu.org.
27 
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 This class models the flight controls for a specific airplane
31 
32 HISTORY
33 --------------------------------------------------------------------------------
34 12/12/98 JSB Created
35 
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37 INCLUDES
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
39 
40 #include <fstream>
41 #include <sstream>
42 #include <iomanip>
43 
44 #include "FGFCS.h"
45 #include "FGFDMExec.h"
46 #include "FGGroundReactions.h"
47 #include "input_output/FGXMLElement.h"
48 #include "input_output/FGModelLoader.h"
49 
50 #include "models/flight_control/FGFilter.h"
51 #include "models/flight_control/FGDeadBand.h"
52 #include "models/flight_control/FGGain.h"
53 #include "models/flight_control/FGPID.h"
54 #include "models/flight_control/FGSwitch.h"
55 #include "models/flight_control/FGSummer.h"
56 #include "models/flight_control/FGKinemat.h"
57 #include "models/flight_control/FGFCSFunction.h"
58 #include "models/flight_control/FGSensor.h"
59 #include "models/flight_control/FGActuator.h"
60 #include "models/flight_control/FGAccelerometer.h"
61 #include "models/flight_control/FGMagnetometer.h"
62 #include "models/flight_control/FGGyro.h"
63 #include "models/flight_control/FGWaypoint.h"
64 #include "models/flight_control/FGAngles.h"
65 #include "models/flight_control/FGDistributor.h"
66 
67 #include "FGFCSChannel.h"
68 
69 using namespace std;
70 
71 namespace JSBSim {
72 
73 IDENT(IdSrc,"$Id: FGFCS.cpp,v 1.98 2017/02/25 14:23:18 bcoconni Exp $");
74 IDENT(IdHdr,ID_FCS);
75 
76 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77 CLASS IMPLEMENTATION
78 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
79 
80 FGFCS::FGFCS(FGFDMExec* fdm) : FGModel(fdm), ChannelRate(1)
81 {
82  int i;
83  Name = "FGFCS";
84  systype = stFCS;
85 
86  fdmex = fdm;
87  DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = 0;
88  PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
89  GearCmd = GearPos = 1; // default to gear down
90  BrakePos.resize(FGLGear::bgNumBrakeGroups);
91  TailhookPos = WingFoldPos = 0.0;
92 
93  bind();
94  for (i=0;i<NForms;i++) {
95  DePos[i] = DaLPos[i] = DaRPos[i] = DrPos[i] = 0.0;
96  DfPos[i] = DsbPos[i] = DspPos[i] = 0.0;
97  }
98 
99  Debug(0);
100 }
101 
102 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103 
105 {
106  ThrottleCmd.clear();
107  ThrottlePos.clear();
108  MixtureCmd.clear();
109  MixturePos.clear();
110  PropAdvanceCmd.clear();
111  PropAdvance.clear();
112  PropFeatherCmd.clear();
113  PropFeather.clear();
114 
115  unsigned int i;
116 
117  for (i=0;i<SystemChannels.size();i++) delete SystemChannels[i];
118  SystemChannels.clear();
119 
120  Debug(1);
121 }
122 
123 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124 
125 bool FGFCS::InitModel(void)
126 {
127  if (!FGModel::InitModel()) return false;
128 
129  unsigned int i;
130 
131  for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = 0.0;
132  for (i=0; i<MixturePos.size(); i++) MixturePos[i] = 0.0;
133  for (i=0; i<ThrottleCmd.size(); i++) ThrottleCmd[i] = 0.0;
134  for (i=0; i<MixtureCmd.size(); i++) MixtureCmd[i] = 0.0;
135  for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = 0.0;
136  for (i=0; i<PropFeather.size(); i++) PropFeather[i] = 0.0;
137 
138  DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = 0;
139  PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
140  TailhookPos = WingFoldPos = 0.0;
141 
142  for (i=0;i<NForms;i++) {
143  DePos[i] = DaLPos[i] = DaRPos[i] = DrPos[i] = 0.0;
144  DfPos[i] = DsbPos[i] = DspPos[i] = 0.0;
145  }
146 
147  // Reset the channels components.
148  for (unsigned int i=0; i<SystemChannels.size(); i++) SystemChannels[i]->Reset();
149 
150  return true;
151 }
152 
153 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 // Notes: In this logic the default engine commands are set. This is simply a
155 // sort of safe-mode method in case the user has not defined control laws for
156 // throttle, mixture, and prop-advance. The throttle, mixture, and prop advance
157 // positions are set equal to the respective commands. Any control logic that is
158 // actually present in the flight_control or autopilot section will override
159 // these simple assignments.
160 
161 bool FGFCS::Run(bool Holding)
162 {
163  unsigned int i;
164 
165  if (FGModel::Run(Holding)) return true; // fast exit if nothing to do
166  if (Holding) return false;
167 
168  RunPreFunctions();
169 
170  for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
171  for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];
172  for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
173  for (i=0; i<PropFeather.size(); i++) PropFeather[i] = PropFeatherCmd[i];
174 
175  // Execute system channels in order
176  for (i=0; i<SystemChannels.size(); i++) {
177  if (debug_lvl & 4) cout << " Executing System Channel: " << SystemChannels[i]->GetName() << endl;
178  ChannelRate = SystemChannels[i]->GetRate();
179  SystemChannels[i]->Execute();
180  }
181  ChannelRate = 1;
182 
183  RunPostFunctions();
184 
185  return false;
186 }
187 
188 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189 
190 void FGFCS::SetDaLPos( int form , double pos )
191 {
192  switch(form) {
193  case ofRad:
194  DaLPos[ofRad] = pos;
195  DaLPos[ofDeg] = pos*radtodeg;
196  break;
197  case ofDeg:
198  DaLPos[ofRad] = pos*degtorad;
199  DaLPos[ofDeg] = pos;
200  break;
201  case ofNorm:
202  DaLPos[ofNorm] = pos;
203  }
204  DaLPos[ofMag] = fabs(DaLPos[ofRad]);
205 }
206 
207 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208 
209 void FGFCS::SetDaRPos( int form , double pos )
210 {
211  switch(form) {
212  case ofRad:
213  DaRPos[ofRad] = pos;
214  DaRPos[ofDeg] = pos*radtodeg;
215  break;
216  case ofDeg:
217  DaRPos[ofRad] = pos*degtorad;
218  DaRPos[ofDeg] = pos;
219  break;
220  case ofNorm:
221  DaRPos[ofNorm] = pos;
222  }
223  DaRPos[ofMag] = fabs(DaRPos[ofRad]);
224 }
225 
226 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227 
228 void FGFCS::SetDePos( int form , double pos )
229 {
230  switch(form) {
231  case ofRad:
232  DePos[ofRad] = pos;
233  DePos[ofDeg] = pos*radtodeg;
234  break;
235  case ofDeg:
236  DePos[ofRad] = pos*degtorad;
237  DePos[ofDeg] = pos;
238  break;
239  case ofNorm:
240  DePos[ofNorm] = pos;
241  }
242  DePos[ofMag] = fabs(DePos[ofRad]);
243 }
244 
245 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246 
247 void FGFCS::SetDrPos( int form , double pos )
248 {
249  switch(form) {
250  case ofRad:
251  DrPos[ofRad] = pos;
252  DrPos[ofDeg] = pos*radtodeg;
253  break;
254  case ofDeg:
255  DrPos[ofRad] = pos*degtorad;
256  DrPos[ofDeg] = pos;
257  break;
258  case ofNorm:
259  DrPos[ofNorm] = pos;
260  }
261  DrPos[ofMag] = fabs(DrPos[ofRad]);
262 }
263 
264 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265 
266 void FGFCS::SetDfPos( int form , double pos )
267 {
268  switch(form) {
269  case ofRad:
270  DfPos[ofRad] = pos;
271  DfPos[ofDeg] = pos*radtodeg;
272  break;
273  case ofDeg:
274  DfPos[ofRad] = pos*degtorad;
275  DfPos[ofDeg] = pos;
276  break;
277  case ofNorm:
278  DfPos[ofNorm] = pos;
279  }
280  DfPos[ofMag] = fabs(DfPos[ofRad]);
281 }
282 
283 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284 
285 void FGFCS::SetDsbPos( int form , double pos )
286 {
287  switch(form) {
288  case ofRad:
289  DsbPos[ofRad] = pos;
290  DsbPos[ofDeg] = pos*radtodeg;
291  break;
292  case ofDeg:
293  DsbPos[ofRad] = pos*degtorad;
294  DsbPos[ofDeg] = pos;
295  break;
296  case ofNorm:
297  DsbPos[ofNorm] = pos;
298  }
299  DsbPos[ofMag] = fabs(DsbPos[ofRad]);
300 }
301 
302 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303 
304 void FGFCS::SetDspPos( int form , double pos )
305 {
306  switch(form) {
307  case ofRad:
308  DspPos[ofRad] = pos;
309  DspPos[ofDeg] = pos*radtodeg;
310  break;
311  case ofDeg:
312  DspPos[ofRad] = pos*degtorad;
313  DspPos[ofDeg] = pos;
314  break;
315  case ofNorm:
316  DspPos[ofNorm] = pos;
317  }
318  DspPos[ofMag] = fabs(DspPos[ofRad]);
319 }
320 
321 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322 
323 void FGFCS::SetThrottleCmd(int engineNum, double setting)
324 {
325  if (engineNum < (int)ThrottlePos.size()) {
326  if (engineNum < 0) {
327  for (unsigned int ctr=0; ctr<ThrottleCmd.size(); ctr++)
328  ThrottleCmd[ctr] = setting;
329  } else {
330  ThrottleCmd[engineNum] = setting;
331  }
332  } else {
333  cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
334  << " engines exist, but attempted throttle command is for engine "
335  << engineNum << endl;
336  }
337 }
338 
339 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340 
341 void FGFCS::SetThrottlePos(int engineNum, double setting)
342 {
343  if (engineNum < (int)ThrottlePos.size()) {
344  if (engineNum < 0) {
345  for (unsigned int ctr=0; ctr<ThrottlePos.size(); ctr++)
346  ThrottlePos[ctr] = setting;
347  } else {
348  ThrottlePos[engineNum] = setting;
349  }
350  } else {
351  cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
352  << " engines exist, but attempted throttle position setting is for engine "
353  << engineNum << endl;
354  }
355 }
356 
357 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
358 
359 double FGFCS::GetThrottleCmd(int engineNum) const
360 {
361  if (engineNum < (int)ThrottlePos.size()) {
362  if (engineNum < 0) {
363  cerr << "Cannot get throttle value for ALL engines" << endl;
364  } else {
365  return ThrottleCmd[engineNum];
366  }
367  } else {
368  cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
369  << " engines exist, but throttle setting for engine " << engineNum
370  << " is selected" << endl;
371  }
372  return 0.0;
373 }
374 
375 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376 
377 double FGFCS::GetThrottlePos(int engineNum) const
378 {
379  if (engineNum < (int)ThrottlePos.size()) {
380  if (engineNum < 0) {
381  cerr << "Cannot get throttle value for ALL engines" << endl;
382  } else {
383  return ThrottlePos[engineNum];
384  }
385  } else {
386  cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
387  << " engines exist, but attempted throttle position setting is for engine "
388  << engineNum << endl;
389  }
390  return 0.0;
391 }
392 
393 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394 
395 void FGFCS::SetMixtureCmd(int engineNum, double setting)
396 {
397  if (engineNum < (int)ThrottlePos.size()) {
398  if (engineNum < 0) {
399  for (unsigned int ctr=0; ctr<MixtureCmd.size(); ctr++)
400  MixtureCmd[ctr] = setting;
401  } else {
402  MixtureCmd[engineNum] = setting;
403  }
404  }
405 }
406 
407 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408 
409 void FGFCS::SetMixturePos(int engineNum, double setting)
410 {
411  if (engineNum < (int)ThrottlePos.size()) {
412  if (engineNum < 0) {
413  for (unsigned int ctr=0; ctr<MixtureCmd.size(); ctr++)
414  MixturePos[ctr] = MixtureCmd[ctr];
415  } else {
416  MixturePos[engineNum] = setting;
417  }
418  }
419 }
420 
421 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
422 
423 void FGFCS::SetPropAdvanceCmd(int engineNum, double setting)
424 {
425  if (engineNum < (int)ThrottlePos.size()) {
426  if (engineNum < 0) {
427  for (unsigned int ctr=0; ctr<PropAdvanceCmd.size(); ctr++)
428  PropAdvanceCmd[ctr] = setting;
429  } else {
430  PropAdvanceCmd[engineNum] = setting;
431  }
432  }
433 }
434 
435 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
436 
437 void FGFCS::SetPropAdvance(int engineNum, double setting)
438 {
439  if (engineNum < (int)ThrottlePos.size()) {
440  if (engineNum < 0) {
441  for (unsigned int ctr=0; ctr<PropAdvanceCmd.size(); ctr++)
442  PropAdvance[ctr] = PropAdvanceCmd[ctr];
443  } else {
444  PropAdvance[engineNum] = setting;
445  }
446  }
447 }
448 
449 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450 
451 void FGFCS::SetFeatherCmd(int engineNum, bool setting)
452 {
453  if (engineNum < (int)ThrottlePos.size()) {
454  if (engineNum < 0) {
455  for (unsigned int ctr=0; ctr<PropFeatherCmd.size(); ctr++)
456  PropFeatherCmd[ctr] = setting;
457  } else {
458  PropFeatherCmd[engineNum] = setting;
459  }
460  }
461 }
462 
463 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464 
465 void FGFCS::SetPropFeather(int engineNum, bool setting)
466 {
467  if (engineNum < (int)ThrottlePos.size()) {
468  if (engineNum < 0) {
469  for (unsigned int ctr=0; ctr<PropFeatherCmd.size(); ctr++)
470  PropFeather[ctr] = PropFeatherCmd[ctr];
471  } else {
472  PropFeather[engineNum] = setting;
473  }
474  }
475 }
476 
477 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
478 
479 bool FGFCS::Load(Element* document)
480 {
481  if (document->GetName() == "autopilot") {
482  Name = "Autopilot: ";
483  systype = stAutoPilot;
484  } else if (document->GetName() == "flight_control") {
485  Name = "FCS: ";
486  systype = stFCS;
487  } else if (document->GetName() == "system") {
488  Name = "System: ";
489  systype = stSystem;
490  }
491 
492  // Load interface properties from document
493  if (!FGModel::Load(document))
494  return false;
495 
496  Name += document->GetAttributeValue("name");
497 
498  Debug(2);
499 
500  Element* channel_element = document->FindElement("channel");
501 
502  while (channel_element) {
503 
504  FGFCSChannel* newChannel = 0;
505 
506  string sOnOffProperty = channel_element->GetAttributeValue("execute");
507  string sChannelName = channel_element->GetAttributeValue("name");
508 
509  int Rate = 0;
510  if (!channel_element->GetAttributeValue("execrate").empty())
511  Rate = channel_element->GetAttributeValueAsNumber("execrate");
512 
513  if (sOnOffProperty.length() > 0) {
514  FGPropertyNode* OnOffPropertyNode = PropertyManager->GetNode(sOnOffProperty);
515  if (OnOffPropertyNode == 0) {
516  cerr << channel_element->ReadFrom() << highint << fgred
517  << "The On/Off property, " << sOnOffProperty << " specified for channel "
518  << channel_element->GetAttributeValue("name") << " is undefined or not "
519  << "understood. The simulation will abort" << reset << endl;
520  throw("Bad system definition");
521  } else
522  newChannel = new FGFCSChannel(this, sChannelName, Rate,
523  OnOffPropertyNode);
524  } else
525  newChannel = new FGFCSChannel(this, sChannelName, Rate);
526 
527  SystemChannels.push_back(newChannel);
528 
529  if (debug_lvl > 0)
530  cout << endl << highint << fgblue << " Channel "
531  << normint << channel_element->GetAttributeValue("name") << reset << endl;
532 
533  Element* component_element = channel_element->GetElement();
534  while (component_element) {
535  try {
536  if ((component_element->GetName() == string("lag_filter")) ||
537  (component_element->GetName() == string("lead_lag_filter")) ||
538  (component_element->GetName() == string("washout_filter")) ||
539  (component_element->GetName() == string("second_order_filter")) ||
540  (component_element->GetName() == string("integrator")) )
541  {
542  newChannel->Add(new FGFilter(this, component_element));
543  } else if ((component_element->GetName() == string("pure_gain")) ||
544  (component_element->GetName() == string("scheduled_gain")) ||
545  (component_element->GetName() == string("aerosurface_scale")))
546  {
547  newChannel->Add(new FGGain(this, component_element));
548  } else if (component_element->GetName() == string("summer")) {
549  newChannel->Add(new FGSummer(this, component_element));
550  } else if (component_element->GetName() == string("deadband")) {
551  newChannel->Add(new FGDeadBand(this, component_element));
552  } else if (component_element->GetName() == string("switch")) {
553  newChannel->Add(new FGSwitch(this, component_element));
554  } else if (component_element->GetName() == string("kinematic")) {
555  newChannel->Add(new FGKinemat(this, component_element));
556  } else if (component_element->GetName() == string("fcs_function")) {
557  newChannel->Add(new FGFCSFunction(this, component_element));
558  } else if (component_element->GetName() == string("pid")) {
559  newChannel->Add(new FGPID(this, component_element));
560  } else if (component_element->GetName() == string("actuator")) {
561  newChannel->Add(new FGActuator(this, component_element));
562  } else if (component_element->GetName() == string("sensor")) {
563  newChannel->Add(new FGSensor(this, component_element));
564  } else if (component_element->GetName() == string("accelerometer")) {
565  newChannel->Add(new FGAccelerometer(this, component_element));
566  } else if (component_element->GetName() == string("magnetometer")) {
567  newChannel->Add(new FGMagnetometer(this, component_element));
568  } else if (component_element->GetName() == string("gyro")) {
569  newChannel->Add(new FGGyro(this, component_element));
570  } else if ((component_element->GetName() == string("waypoint_heading")) ||
571  (component_element->GetName() == string("waypoint_distance")))
572  {
573  newChannel->Add(new FGWaypoint(this, component_element));
574  } else if (component_element->GetName() == string("angle")) {
575  newChannel->Add(new FGAngles(this, component_element));
576  } else if (component_element->GetName() == string("distributor")) {
577  newChannel->Add(new FGDistributor(this, component_element));
578  } else {
579  cerr << "Unknown FCS component: " << component_element->GetName() << endl;
580  }
581  } catch(string& s) {
582  cerr << highint << fgred << endl << " " << s << endl;
583  cerr << reset << endl;
584  return false;
585  }
586  component_element = channel_element->GetNextElement();
587  }
588  channel_element = document->FindNextElement("channel");
589  }
590 
591  PostLoad(document, PropertyManager);
592 
593  return true;
594 }
595 
596 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
597 
599 {
600  return BrakePos[bg];
601 }
602 
603 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 
605 SGPath FGFCS::FindFullPathName(const SGPath& path) const
606 {
607  SGPath name = FGModel::FindFullPathName(path);
608  if (systype != stSystem || !name.isNull()) return name;
609 
610  name = CheckPathName(FDMExec->GetFullAircraftPath()/string("Systems"), path);
611  if (!name.isNull()) return name;
612 
613  return CheckPathName(FDMExec->GetSystemsPath(), path);
614 }
615 
616 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617 
618 string FGFCS::GetComponentStrings(const string& delimiter) const
619 {
620  string CompStrings = "";
621  bool firstime = true;
622  int total_count=0;
623 
624  for (unsigned int i=0; i<SystemChannels.size(); i++)
625  {
626  for (unsigned int c=0; c<SystemChannels[i]->GetNumComponents(); c++)
627  {
628  if (firstime) firstime = false;
629  else CompStrings += delimiter;
630 
631  CompStrings += SystemChannels[i]->GetComponent(c)->GetName();
632  total_count++;
633  }
634  }
635 
636  return CompStrings;
637 }
638 
639 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640 
641 string FGFCS::GetComponentValues(const string& delimiter) const
642 {
643  std::ostringstream buf;
644 
645  bool firstime = true;
646  int total_count=0;
647 
648  for (unsigned int i=0; i<SystemChannels.size(); i++)
649  {
650  for (unsigned int c=0; c<SystemChannels[i]->GetNumComponents(); c++)
651  {
652  if (firstime) firstime = false;
653  else buf << delimiter;
654 
655  buf << setprecision(9) << SystemChannels[i]->GetComponent(c)->GetOutput();
656  total_count++;
657  }
658  }
659 
660  return buf.str();
661 }
662 
663 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
664 
665 void FGFCS::AddThrottle(void)
666 {
667  ThrottleCmd.push_back(0.0);
668  ThrottlePos.push_back(0.0);
669  MixtureCmd.push_back(0.0); // assume throttle and mixture are coupled
670  MixturePos.push_back(0.0);
671  PropAdvanceCmd.push_back(0.0); // assume throttle and prop pitch are coupled
672  PropAdvance.push_back(0.0);
673  PropFeatherCmd.push_back(false);
674  PropFeather.push_back(false);
675 
676  unsigned int num = (unsigned int)ThrottleCmd.size()-1;
677  bindThrottle(num);
678 }
679 
680 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
681 
682 double FGFCS::GetDt(void) const
683 {
684  return FDMExec->GetDeltaT()*rate;
685 }
686 
687 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
688 
689 void FGFCS::bind(void)
690 {
691  PropertyManager->Tie("fcs/aileron-cmd-norm", this, &FGFCS::GetDaCmd, &FGFCS::SetDaCmd);
692  PropertyManager->Tie("fcs/elevator-cmd-norm", this, &FGFCS::GetDeCmd, &FGFCS::SetDeCmd);
693  PropertyManager->Tie("fcs/rudder-cmd-norm", this, &FGFCS::GetDrCmd, &FGFCS::SetDrCmd);
694  PropertyManager->Tie("fcs/flap-cmd-norm", this, &FGFCS::GetDfCmd, &FGFCS::SetDfCmd);
695  PropertyManager->Tie("fcs/speedbrake-cmd-norm", this, &FGFCS::GetDsbCmd, &FGFCS::SetDsbCmd);
696  PropertyManager->Tie("fcs/spoiler-cmd-norm", this, &FGFCS::GetDspCmd, &FGFCS::SetDspCmd);
697  PropertyManager->Tie("fcs/pitch-trim-cmd-norm", this, &FGFCS::GetPitchTrimCmd, &FGFCS::SetPitchTrimCmd);
698  PropertyManager->Tie("fcs/roll-trim-cmd-norm", this, &FGFCS::GetRollTrimCmd, &FGFCS::SetRollTrimCmd);
699  PropertyManager->Tie("fcs/yaw-trim-cmd-norm", this, &FGFCS::GetYawTrimCmd, &FGFCS::SetYawTrimCmd);
700 
701  PropertyManager->Tie("fcs/left-aileron-pos-rad", this, ofRad, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
702  PropertyManager->Tie("fcs/left-aileron-pos-deg", this, ofDeg, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
703  PropertyManager->Tie("fcs/left-aileron-pos-norm", this, ofNorm, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
704  PropertyManager->Tie("fcs/mag-left-aileron-pos-rad", this, ofMag, &FGFCS::GetDaLPos);
705 
706  PropertyManager->Tie("fcs/right-aileron-pos-rad", this, ofRad, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
707  PropertyManager->Tie("fcs/right-aileron-pos-deg", this, ofDeg, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
708  PropertyManager->Tie("fcs/right-aileron-pos-norm", this, ofNorm, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
709  PropertyManager->Tie("fcs/mag-right-aileron-pos-rad", this, ofMag, &FGFCS::GetDaRPos);
710 
711  PropertyManager->Tie("fcs/elevator-pos-rad", this, ofRad, &FGFCS::GetDePos, &FGFCS::SetDePos);
712  PropertyManager->Tie("fcs/elevator-pos-deg", this, ofDeg, &FGFCS::GetDePos, &FGFCS::SetDePos);
713  PropertyManager->Tie("fcs/elevator-pos-norm", this, ofNorm, &FGFCS::GetDePos, &FGFCS::SetDePos);
714  PropertyManager->Tie("fcs/mag-elevator-pos-rad", this, ofMag, &FGFCS::GetDePos);
715 
716  PropertyManager->Tie("fcs/rudder-pos-rad", this,ofRad, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
717  PropertyManager->Tie("fcs/rudder-pos-deg", this,ofDeg, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
718  PropertyManager->Tie("fcs/rudder-pos-norm", this,ofNorm, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
719  PropertyManager->Tie("fcs/mag-rudder-pos-rad", this,ofMag, &FGFCS::GetDrPos);
720 
721  PropertyManager->Tie("fcs/flap-pos-rad", this,ofRad, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
722  PropertyManager->Tie("fcs/flap-pos-deg", this,ofDeg, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
723  PropertyManager->Tie("fcs/flap-pos-norm", this,ofNorm, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
724 
725  PropertyManager->Tie("fcs/speedbrake-pos-rad", this,ofRad, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
726  PropertyManager->Tie("fcs/speedbrake-pos-deg", this,ofDeg, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
727  PropertyManager->Tie("fcs/speedbrake-pos-norm", this,ofNorm, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
728  PropertyManager->Tie("fcs/mag-speedbrake-pos-rad", this,ofMag, &FGFCS::GetDsbPos);
729 
730  PropertyManager->Tie("fcs/spoiler-pos-rad", this, ofRad, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
731  PropertyManager->Tie("fcs/spoiler-pos-deg", this, ofDeg, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
732  PropertyManager->Tie("fcs/spoiler-pos-norm", this, ofNorm, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
733  PropertyManager->Tie("fcs/mag-spoiler-pos-rad", this, ofMag, &FGFCS::GetDspPos);
734 
735  PropertyManager->Tie("gear/gear-pos-norm", this, &FGFCS::GetGearPos, &FGFCS::SetGearPos);
736  PropertyManager->Tie("gear/gear-cmd-norm", this, &FGFCS::GetGearCmd, &FGFCS::SetGearCmd);
737  PropertyManager->Tie("fcs/left-brake-cmd-norm", this, &FGFCS::GetLBrake, &FGFCS::SetLBrake);
738  PropertyManager->Tie("fcs/right-brake-cmd-norm", this, &FGFCS::GetRBrake, &FGFCS::SetRBrake);
739  PropertyManager->Tie("fcs/center-brake-cmd-norm", this, &FGFCS::GetCBrake, &FGFCS::SetCBrake);
740 
741  PropertyManager->Tie("gear/tailhook-pos-norm", this, &FGFCS::GetTailhookPos, &FGFCS::SetTailhookPos);
742  PropertyManager->Tie("fcs/wing-fold-pos-norm", this, &FGFCS::GetWingFoldPos, &FGFCS::SetWingFoldPos);
743  PropertyManager->Tie("simulation/channel-dt", this, &FGFCS::GetChannelDeltaT);
744 }
745 
746 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
747 // Technically, this function should probably bind propulsion type specific controls
748 // rather than mixture and prop-advance.
749 
750 void FGFCS::bindThrottle(unsigned int num)
751 {
752  string tmp;
753 
754  tmp = CreateIndexedPropertyName("fcs/throttle-cmd-norm", num);
755  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetThrottleCmd,
757  tmp = CreateIndexedPropertyName("fcs/throttle-pos-norm", num);
758  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetThrottlePos,
760  tmp = CreateIndexedPropertyName("fcs/mixture-cmd-norm", num);
761  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetMixtureCmd,
763  tmp = CreateIndexedPropertyName("fcs/mixture-pos-norm", num);
764  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetMixturePos,
766  tmp = CreateIndexedPropertyName("fcs/advance-cmd-norm", num);
767  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropAdvanceCmd,
769  tmp = CreateIndexedPropertyName("fcs/advance-pos-norm", num);
770  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropAdvance,
772  tmp = CreateIndexedPropertyName("fcs/feather-cmd-norm", num);
773  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetFeatherCmd,
775  tmp = CreateIndexedPropertyName("fcs/feather-pos-norm", num);
776  PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropFeather,
778 }
779 
780 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
781 // The bitmasked value choices are as follows:
782 // unset: In this case (the default) JSBSim would only print
783 // out the normally expected messages, essentially echoing
784 // the config files as they are read. If the environment
785 // variable is not set, debug_lvl is set to 1 internally
786 // 0: This requests JSBSim not to output any messages
787 // whatsoever.
788 // 1: This value explicity requests the normal JSBSim
789 // startup messages
790 // 2: This value asks for a message to be printed out when
791 // a class is instantiated
792 // 4: When this value is set, a message is displayed when a
793 // FGModel object executes its Run() method
794 // 8: When this value is set, various runtime state variables
795 // are printed out periodically
796 // 16: When set various parameters are sanity checked and
797 // a message is printed out when they go out of bounds
798 
799 void FGFCS::Debug(int from)
800 {
801  if (debug_lvl <= 0) return;
802 
803  if (debug_lvl & 1) { // Standard console startup message output
804  if (from == 2) { // Loader
805  cout << endl << " " << Name << endl;
806  }
807  }
808  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
809  if (from == 0) cout << "Instantiated: FGFCS" << endl;
810  if (from == 1) cout << "Destroyed: FGFCS" << endl;
811  }
812  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
813  }
814  if (debug_lvl & 8 ) { // Runtime state variables
815  }
816  if (debug_lvl & 16) { // Sanity checking
817  }
818  if (debug_lvl & 64) {
819  if (from == 0) { // Constructor
820  cout << IdSrc << endl;
821  cout << IdHdr << endl;
822  }
823  }
824 }
825 
826 }
void SetDePos(int form, double pos)
Sets the elevator position.
Definition: FGFCS.cpp:228
Provides a way to determine the smallest included angle.
Definition: FGAngles.h:85
void SetDsbCmd(double cmd)
Sets the speedbrake command.
Definition: FGFCS.h:399
double GetRBrake(void) const
Gets the right brake.
Definition: FGFCS.h:532
void SetRollTrimCmd(double cmd)
Sets the aileron trim command.
Definition: FGFCS.h:415
Encapsulates a Accelerometer component for the flight control system.
double GetDsbCmd(void) const
Gets the speedbrake command.
Definition: FGFCS.h:238
double GetDfPos(int form=ofRad) const
Gets the flaps position.
Definition: FGFCS.h:320
double GetDeCmd(void) const
Gets the elevator command.
Definition: FGFCS.h:222
void SetLBrake(double cmd)
Sets the left brake group.
Definition: FGFCS.h:509
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
Encapsulates a PID control component for the flight control system.
Definition: FGPID.h:126
double GetDePos(int form=ofRad) const
Gets the elevator position.
Definition: FGFCS.h:300
double GetDfCmd(void) const
Gets the flaps command.
Definition: FGFCS.h:234
void SetPropAdvanceCmd(int engine, double cmd)
Sets the propeller pitch command for the specified engine.
Definition: FGFCS.cpp:423
void SetDrPos(int form, double pos)
Sets the rudder position.
Definition: FGFCS.cpp:247
double GetDaLPos(int form=ofRad) const
Gets the left aileron position.
Definition: FGFCS.h:290
void SetDspPos(int form, double pos)
Sets the spoiler position.
Definition: FGFCS.cpp:304
BrakeGroup
Brake grouping enumerators.
Definition: FGLGear.h:219
void SetRBrake(double cmd)
Sets the right brake group.
Definition: FGFCS.h:513
const SGPath & GetFullAircraftPath(void)
Retrieves the full aircraft path name.
Definition: FGFDMExec.h:397
Encapsulates a magnetometer component for the flight control system.
Class wrapper for property handling.
static char reset[5]
resets text properties
Definition: FGJSBBase.h:131
double GetRollTrimCmd(void) const
Gets the aileron trim command.
Definition: FGFCS.h:278
STL namespace.
Element * FindElement(const std::string &el="")
Searches for a specified element.
void SetDsbPos(int form, double pos)
Sets the speedbrake position.
Definition: FGFCS.cpp:285
Encapsulates a gain component for the flight control system.
Definition: FGGain.h:218
static char normint[6]
normal intensity text
Definition: FGJSBBase.h:129
void SetPropFeather(int engine, bool cmd)
Sets the actual prop feather setting for the specified engine.
Definition: FGFCS.cpp:465
void SetThrottleCmd(int engine, double cmd)
Sets the throttle command for the specified engine.
Definition: FGFCS.cpp:323
void SetDaCmd(double cmd)
Sets the aileron command.
Definition: FGFCS.h:379
bool Run(bool Holding)
Runs the Flight Controls model; called by the Executive Can pass in a value indicating if the executi...
Definition: FGFCS.cpp:161
void SetDaRPos(int form, double pos)
Sets the right aileron position.
Definition: FGFCS.cpp:209
Encapsulates an Actuator component for the flight control system.
Definition: FGActuator.h:129
void SetDfPos(int form, double pos)
Sets the flaps position.
Definition: FGFCS.cpp:266
void SetPitchTrimCmd(double cmd)
Sets the pitch trim command.
Definition: FGFCS.h:407
double GetCBrake(void) const
Gets the center brake.
Definition: FGFCS.h:536
Encapsulates a Sensor component for the flight control system.
Definition: FGSensor.h:134
static char fgred[6]
red text
Definition: FGJSBBase.h:141
~FGFCS()
Destructor.
Definition: FGFCS.cpp:104
double GetPitchTrimCmd(void) const
Gets the pitch trim command.
Definition: FGFCS.h:270
void SetDaLPos(int form, double pos)
Sets the left aileron position.
Definition: FGFCS.cpp:190
virtual bool Run(bool Holding)
Runs the model; called by the Executive.
Definition: FGModel.cpp:92
Models a flight control system summing component.
Definition: FGSummer.h:109
void Tie(const std::string &name, bool *pointer, bool useDefault=true)
Tie a property to an external bool variable.
void Add(FGFCSComponent *comp)
Adds a component to a channel.
Definition: FGFCSChannel.h:99
void SetYawTrimCmd(double cmd)
Sets the rudder trim command.
Definition: FGFCS.h:411
bool GetFeatherCmd(int engine) const
Gets the prop feather command.
Definition: FGFCS.h:266
void SetCBrake(double cmd)
Sets the center brake group.
Definition: FGFCS.h:517
void SetDspCmd(double cmd)
Sets the spoilers command.
Definition: FGFCS.h:403
double GetAttributeValueAsNumber(const std::string &key)
Retrieves an attribute value as a double precision real number.
const std::string & GetName(void) const
Retrieves the element name.
Definition: FGXMLElement.h:186
std::string GetComponentValues(const std::string &delimiter) const
Retrieves all component outputs for inclusion in output stream.
Definition: FGFCS.cpp:641
Base class for all scheduled JSBSim models.
Definition: FGModel.h:74
Encapsulates a filter for the flight control system.
Definition: FGFilter.h:239
void SetDrCmd(double cmd)
Sets the rudder command.
Definition: FGFCS.h:387
double GetDsbPos(int form=ofRad) const
Gets the speedbrake position.
Definition: FGFCS.h:310
double GetYawTrimCmd(void) const
Gets the rudder trim command.
Definition: FGFCS.h:274
void SetDeCmd(double cmd)
Sets the elevator command.
Definition: FGFCS.h:383
std::string GetComponentStrings(const std::string &delimiter) const
Retrieves all component names for inclusion in output stream.
Definition: FGFCS.cpp:618
void SetGearPos(double gearpos)
Set the gear extend/retract position, defaults to down.
Definition: FGFCS.h:484
void SetMixturePos(int engine, double cmd)
Sets the actual mixture setting for the specified engine.
Definition: FGFCS.cpp:409
bool Load(Element *el)
Loads the Flight Control System.
Definition: FGFCS.cpp:479
void SetTailhookPos(double hookpos)
Set the tailhook position.
Definition: FGFCS.h:488
double GetDaCmd(void) const
Gets the aileron command.
Definition: FGFCS.h:218
static char fgblue[6]
blue text
Definition: FGJSBBase.h:137
double GetGearCmd(void) const
Get the gear extend/retract command.
Definition: FGFCS.h:283
void SetDfCmd(double cmd)
Sets the flaps command.
Definition: FGFCS.h:395
std::string ReadFrom(void) const
Return a string that contains a description of the location where the current XML element was read fr...
void SetWingFoldPos(double foldpos)
Set the wing fold position.
Definition: FGFCS.h:492
Encapsulates a kinematic (mechanical) component for the flight control system.
Definition: FGKinemat.h:120
Element * FindNextElement(const std::string &el="")
Searches for the next element as specified.
static char highint[5]
highlights text
Definition: FGJSBBase.h:125
double GetPropAdvanceCmd(int engine) const
Gets the prop pitch command.
Definition: FGFCS.h:261
void SetThrottlePos(int engine, double cmd)
Sets the actual throttle setting for the specified engine.
Definition: FGFCS.cpp:341
void SetPropAdvance(int engine, double cmd)
Sets the actual prop pitch setting for the specified engine.
Definition: FGFCS.cpp:437
void SetMixtureCmd(int engine, double cmd)
Sets the mixture command for the specified engine.
Definition: FGFCS.cpp:395
double GetDspPos(int form=ofRad) const
Gets the spoiler position.
Definition: FGFCS.h:315
Element * GetElement(unsigned int el=0)
Returns a pointer to the element requested by index.
double GetDeltaT(void) const
Returns the simulation delta T.
Definition: FGFDMExec.h:536
Encapsulates a distributor for the flight control system.
Models a deadband object.
Definition: FGDeadBand.h:89
double GetGearPos(void) const
Gets the gear position (0 up, 1 down), defaults to down.
Definition: FGFCS.h:339
Encapsulates the JSBSim simulation executive.
Definition: FGFDMExec.h:189
double GetBrake(FGLGear::BrakeGroup bg)
Gets the brake for a specified group.
Definition: FGFCS.cpp:598
const SGPath & GetSystemsPath(void)
Retrieves the systems path.
Definition: FGFDMExec.h:395
Encapsulates a Gyro component for the flight control system.
Definition: FGGyro.h:113
double GetDspCmd(void) const
Gets the spoiler command.
Definition: FGFCS.h:242
double GetLBrake(void) const
Gets the left brake.
Definition: FGFCS.h:528
Encapsulates a switch for the flight control system.
Definition: FGSwitch.h:137
double GetDrCmd(void) const
Gets the rudder command.
Definition: FGFCS.h:226
void SetGearCmd(double gearcmd)
Set the gear extend/retract command, defaults to down.
Definition: FGFCS.h:429
Models a FCSFunction object.
void SetFeatherCmd(int engine, bool cmd)
Sets the propeller feather command for the specified engine.
Definition: FGFCS.cpp:451
Element * GetNextElement(void)
Returns a pointer to the next element in the list.
virtual bool Load(Element *el)
Loads this model.
Definition: FGModel.cpp:113
Models a Waypoint object.
Definition: FGWaypoint.h:103
double GetDaRPos(int form=ofRad) const
Gets the right aileron position.
Definition: FGFCS.h:295
double GetTailhookPos(void) const
Gets the tailhook position (0 up, 1 down)
Definition: FGFCS.h:343
double GetWingFoldPos(void) const
Gets the wing fold position (0 unfolded, 1 folded)
Definition: FGFCS.h:347
double GetDrPos(int form=ofRad) const
Gets the rudder position.
Definition: FGFCS.h:305