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