JSBSim Flight Dynamics Model 1.3.0 (09 Apr 2026)
An Open Source Flight Dynamics and Control Software Library in C++
Loading...
Searching...
No Matches
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
28FUNCTIONAL DESCRIPTION
29--------------------------------------------------------------------------------
30This class models the flight controls for a specific airplane
31
32HISTORY
33--------------------------------------------------------------------------------
3412/12/98 JSB Created
35
36%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37INCLUDES
38%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
39
40#include <iomanip>
41#include <array>
42
43#include "FGFCS.h"
44#include "input_output/FGModelLoader.h"
45#include "input_output/FGLog.h"
46
47#include "models/flight_control/FGFilter.h"
48#include "models/flight_control/FGDeadBand.h"
49#include "models/flight_control/FGGain.h"
50#include "models/flight_control/FGPID.h"
51#include "models/flight_control/FGSwitch.h"
52#include "models/flight_control/FGSummer.h"
53#include "models/flight_control/FGKinemat.h"
54#include "models/flight_control/FGFCSFunction.h"
55#include "models/flight_control/FGActuator.h"
56#include "models/flight_control/FGAccelerometer.h"
57#include "models/flight_control/FGMagnetometer.h"
58#include "models/flight_control/FGGyro.h"
59#include "models/flight_control/FGWaypoint.h"
60#include "models/flight_control/FGAngles.h"
61#include "models/flight_control/FGDistributor.h"
62#include "models/flight_control/FGLinearActuator.h"
63
64#include "FGFCSChannel.h"
65
66using namespace std;
67
68namespace JSBSim {
69
70/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71CLASS IMPLEMENTATION
72%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
73
74FGFCS::FGFCS(FGFDMExec* fdm) : FGModel(fdm), ChannelRate(1)
75{
76 int i;
77 Name = "FGFCS";
78 systype = stFCS;
79
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
118bool 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
154bool 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) {
171 FGLogging log(LogLevel::DEBUG);
172 log << " Executing System Channel: " << SystemChannels[i]->GetName() << endl;
173 }
174 ChannelRate = SystemChannels[i]->GetRate();
175 SystemChannels[i]->Execute();
176 }
177 ChannelRate = 1;
178
179 RunPostFunctions();
180
181 return false;
182}
183
184//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185
186void FGFCS::SetDaLPos( int form , double pos )
187{
188 switch(form) {
189 case ofRad:
190 DaLPos[ofRad] = pos;
191 DaLPos[ofDeg] = pos*radtodeg;
192 break;
193 case ofDeg:
194 DaLPos[ofRad] = pos*degtorad;
195 DaLPos[ofDeg] = pos;
196 break;
197 case ofNorm:
198 DaLPos[ofNorm] = pos;
199 }
200 DaLPos[ofMag] = fabs(DaLPos[ofRad]);
201}
202
203//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204
205void FGFCS::SetDaRPos( int form , double pos )
206{
207 switch(form) {
208 case ofRad:
209 DaRPos[ofRad] = pos;
210 DaRPos[ofDeg] = pos*radtodeg;
211 break;
212 case ofDeg:
213 DaRPos[ofRad] = pos*degtorad;
214 DaRPos[ofDeg] = pos;
215 break;
216 case ofNorm:
217 DaRPos[ofNorm] = pos;
218 }
219 DaRPos[ofMag] = fabs(DaRPos[ofRad]);
220}
221
222//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
223
224void FGFCS::SetDePos( int form , double pos )
225{
226 switch(form) {
227 case ofRad:
228 DePos[ofRad] = pos;
229 DePos[ofDeg] = pos*radtodeg;
230 break;
231 case ofDeg:
232 DePos[ofRad] = pos*degtorad;
233 DePos[ofDeg] = pos;
234 break;
235 case ofNorm:
236 DePos[ofNorm] = pos;
237 }
238 DePos[ofMag] = fabs(DePos[ofRad]);
239}
240
241//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242
243void FGFCS::SetDrPos( int form , double pos )
244{
245 switch(form) {
246 case ofRad:
247 DrPos[ofRad] = pos;
248 DrPos[ofDeg] = pos*radtodeg;
249 break;
250 case ofDeg:
251 DrPos[ofRad] = pos*degtorad;
252 DrPos[ofDeg] = pos;
253 break;
254 case ofNorm:
255 DrPos[ofNorm] = pos;
256 }
257 DrPos[ofMag] = fabs(DrPos[ofRad]);
258}
259
260//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261
262void FGFCS::SetDfPos( int form , double pos )
263{
264 switch(form) {
265 case ofRad:
266 DfPos[ofRad] = pos;
267 DfPos[ofDeg] = pos*radtodeg;
268 break;
269 case ofDeg:
270 DfPos[ofRad] = pos*degtorad;
271 DfPos[ofDeg] = pos;
272 break;
273 case ofNorm:
274 DfPos[ofNorm] = pos;
275 }
276 DfPos[ofMag] = fabs(DfPos[ofRad]);
277}
278
279//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280
281void FGFCS::SetDsbPos( int form , double pos )
282{
283 switch(form) {
284 case ofRad:
285 DsbPos[ofRad] = pos;
286 DsbPos[ofDeg] = pos*radtodeg;
287 break;
288 case ofDeg:
289 DsbPos[ofRad] = pos*degtorad;
290 DsbPos[ofDeg] = pos;
291 break;
292 case ofNorm:
293 DsbPos[ofNorm] = pos;
294 }
295 DsbPos[ofMag] = fabs(DsbPos[ofRad]);
296}
297
298//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299
300void FGFCS::SetDspPos( int form , double pos )
301{
302 switch(form) {
303 case ofRad:
304 DspPos[ofRad] = pos;
305 DspPos[ofDeg] = pos*radtodeg;
306 break;
307 case ofDeg:
308 DspPos[ofRad] = pos*degtorad;
309 DspPos[ofDeg] = pos;
310 break;
311 case ofNorm:
312 DspPos[ofNorm] = pos;
313 }
314 DspPos[ofMag] = fabs(DspPos[ofRad]);
315}
316
317//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318
319void FGFCS::SetThrottleCmd(int engineNum, double setting)
320{
321 if (engineNum < (int)ThrottleCmd.size()) {
322 if (engineNum < 0) {
323 for (unsigned int ctr=0; ctr<ThrottleCmd.size(); ctr++)
324 ThrottleCmd[ctr] = setting;
325 } else {
326 ThrottleCmd[engineNum] = setting;
327 }
328 } else {
329 FGLogging log(LogLevel::ERROR);
330 log << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
331 << " engines exist, but attempted throttle command is for engine "
332 << engineNum << endl;
333 }
334}
335
336//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337
338void FGFCS::SetThrottlePos(int engineNum, double setting)
339{
340 if (engineNum < (int)ThrottlePos.size()) {
341 if (engineNum < 0) {
342 for (unsigned int ctr=0; ctr<ThrottlePos.size(); ctr++)
343 ThrottlePos[ctr] = setting;
344 } else {
345 ThrottlePos[engineNum] = setting;
346 }
347 } else {
348 FGLogging log(LogLevel::ERROR);
349 log << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
350 << " engines exist, but attempted throttle position setting is for engine "
351 << engineNum << endl;
352 }
353}
354
355//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
356
357double FGFCS::GetThrottleCmd(int engineNum) const
358{
359 if (engineNum < (int)ThrottleCmd.size()) {
360 if (engineNum < 0) {
361 FGLogging log(LogLevel::ERROR);
362 log << "Cannot get throttle value for ALL engines" << endl;
363 } else {
364 return ThrottleCmd[engineNum];
365 }
366 } else {
367 FGLogging log(LogLevel::ERROR);
368 log << "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
377double FGFCS::GetThrottlePos(int engineNum) const
378{
379 if (engineNum < (int)ThrottlePos.size()) {
380 if (engineNum < 0) {
381 FGLogging log(LogLevel::ERROR);
382 log << "Cannot get throttle value for ALL engines" << endl;
383 } else {
384 return ThrottlePos[engineNum];
385 }
386 } else {
387 FGLogging log(LogLevel::ERROR);
388 log << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
389 << " engines exist, but attempted throttle position setting is for engine "
390 << engineNum << endl;
391 }
392 return 0.0;
393}
394
395//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
396
397void FGFCS::SetMixtureCmd(int engineNum, double setting)
398{
399 if (engineNum < (int)MixtureCmd.size()) {
400 if (engineNum < 0) {
401 for (unsigned int ctr=0; ctr<MixtureCmd.size(); ctr++)
402 MixtureCmd[ctr] = setting;
403 } else {
404 MixtureCmd[engineNum] = setting;
405 }
406 }
407}
408
409//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
410
411void FGFCS::SetMixturePos(int engineNum, double setting)
412{
413 if (engineNum < (int)MixturePos.size()) {
414 if (engineNum < 0) {
415 for (unsigned int ctr=0; ctr<MixtureCmd.size(); ctr++)
416 MixturePos[ctr] = MixtureCmd[ctr];
417 } else {
418 MixturePos[engineNum] = setting;
419 }
420 }
421}
422
423//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424
425void FGFCS::SetPropAdvanceCmd(int engineNum, double setting)
426{
427 if (engineNum < (int)PropAdvanceCmd.size()) {
428 if (engineNum < 0) {
429 for (unsigned int ctr=0; ctr<PropAdvanceCmd.size(); ctr++)
430 PropAdvanceCmd[ctr] = setting;
431 } else {
432 PropAdvanceCmd[engineNum] = setting;
433 }
434 }
435}
436
437//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
438
439void FGFCS::SetPropAdvance(int engineNum, double setting)
440{
441 if (engineNum < (int)PropAdvance.size()) {
442 if (engineNum < 0) {
443 for (unsigned int ctr=0; ctr<PropAdvanceCmd.size(); ctr++)
444 PropAdvance[ctr] = PropAdvanceCmd[ctr];
445 } else {
446 PropAdvance[engineNum] = setting;
447 }
448 }
449}
450
451//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
452
453void FGFCS::SetFeatherCmd(int engineNum, bool setting)
454{
455 if (engineNum < (int)PropFeatherCmd.size()) {
456 if (engineNum < 0) {
457 for (unsigned int ctr=0; ctr<PropFeatherCmd.size(); ctr++)
458 PropFeatherCmd[ctr] = setting;
459 } else {
460 PropFeatherCmd[engineNum] = setting;
461 }
462 }
463}
464
465//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
466
467void FGFCS::SetPropFeather(int engineNum, bool setting)
468{
469 if (engineNum < (int)PropFeather.size()) {
470 if (engineNum < 0) {
471 for (unsigned int ctr=0; ctr<PropFeatherCmd.size(); ctr++)
472 PropFeather[ctr] = PropFeatherCmd[ctr];
473 } else {
474 PropFeather[engineNum] = setting;
475 }
476 }
477}
478
479//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
480
481bool FGFCS::Load(Element* document)
482{
483 if (document->GetName() == "autopilot") {
484 Name = "Autopilot: ";
485 systype = stAutoPilot;
486 } else if (document->GetName() == "flight_control") {
487 Name = "FCS: ";
488 systype = stFCS;
489 } else if (document->GetName() == "system") {
490 Name = "System: ";
491 systype = stSystem;
492 }
493
494 // Load interface properties from document
495 if (!FGModel::Upload(document, true))
496 return false;
497
498 Name += document->GetAttributeValue("name");
499
500 Debug(2);
501
502 Element* channel_element = document->FindElement("channel");
503
504 while (channel_element) {
505
506 FGFCSChannel* newChannel = 0;
507
508 string sOnOffProperty = channel_element->GetAttributeValue("execute");
509 string sChannelName = channel_element->GetAttributeValue("name");
510
511 if (!channel_element->GetAttributeValue("execrate").empty())
512 ChannelRate = channel_element->GetAttributeValueAsNumber("execrate");
513 else
514 ChannelRate = 1;
515
516 if (sOnOffProperty.length() > 0) {
517 SGPropertyNode* OnOffPropertyNode = PropertyManager->GetNode(sOnOffProperty);
518 if (OnOffPropertyNode == nullptr) {
519 XMLLogException err(channel_element);
520 err << LogFormat::BOLD << LogFormat::RED
521 << "The On/Off property, " << sOnOffProperty << " specified for channel "
522 << channel_element->GetAttributeValue("name") << " is undefined or not "
523 << "understood. The simulation will abort" << LogFormat::RESET << endl;
524 throw err;
525 } else
526 newChannel = new FGFCSChannel(this, sChannelName, ChannelRate,
527 OnOffPropertyNode);
528 } else
529 newChannel = new FGFCSChannel(this, sChannelName, ChannelRate);
530
531 SystemChannels.push_back(newChannel);
532
533 if (debug_lvl > 0) {
534 FGLogging log(LogLevel::DEBUG);
535 log << endl << LogFormat::BOLD << LogFormat::BLUE << " Channel "
536 << LogFormat::NORMAL << channel_element->GetAttributeValue("name") << LogFormat::RESET << endl;
537 }
538
539 Element* component_element = channel_element->GetElement();
540 while (component_element) {
541 try {
542 if ((component_element->GetName() == string("lag_filter")) ||
543 (component_element->GetName() == string("lead_lag_filter")) ||
544 (component_element->GetName() == string("washout_filter")) ||
545 (component_element->GetName() == string("second_order_filter")) )
546 {
547 newChannel->Add(new FGFilter(this, component_element));
548 } else if ((component_element->GetName() == string("pure_gain")) ||
549 (component_element->GetName() == string("scheduled_gain")) ||
550 (component_element->GetName() == string("aerosurface_scale")))
551 {
552 newChannel->Add(new FGGain(this, component_element));
553 } else if (component_element->GetName() == string("summer")) {
554 newChannel->Add(new FGSummer(this, component_element));
555 } else if (component_element->GetName() == string("deadband")) {
556 newChannel->Add(new FGDeadBand(this, component_element));
557 } else if (component_element->GetName() == string("switch")) {
558 newChannel->Add(new FGSwitch(this, component_element));
559 } else if (component_element->GetName() == string("kinematic")) {
560 newChannel->Add(new FGKinemat(this, component_element));
561 } else if (component_element->GetName() == string("fcs_function")) {
562 newChannel->Add(new FGFCSFunction(this, component_element));
563 } else if (component_element->GetName() == string("pid")) {
564 newChannel->Add(new FGPID(this, component_element));
565 } else if (component_element->GetName() == string("integrator")) {
566 // <integrator> is equivalent to <pid type="trap">
567 Element* c1_el = component_element->FindElement("c1");
568 if (!c1_el) {
569 XMLLogException err(component_element);
570 err << "INTEGRATOR component " << component_element->GetAttributeValue("name")
571 << " does not provide the parameter <c1>" << endl;
572 throw err;
573 }
574 c1_el->ChangeName("ki");
575 if (!c1_el->HasAttribute("type"))
576 c1_el->AddAttribute("type", "trap");
577 newChannel->Add(new FGPID(this, component_element));
578 } else if (component_element->GetName() == string("actuator")) {
579 newChannel->Add(new FGActuator(this, component_element));
580 } else if (component_element->GetName() == string("sensor")) {
581 newChannel->Add(new FGSensor(this, component_element));
582 } else if (component_element->GetName() == string("accelerometer")) {
583 newChannel->Add(new FGAccelerometer(this, component_element));
584 } else if (component_element->GetName() == string("magnetometer")) {
585 newChannel->Add(new FGMagnetometer(this, component_element));
586 } else if (component_element->GetName() == string("gyro")) {
587 newChannel->Add(new FGGyro(this, component_element));
588 } else if ((component_element->GetName() == string("waypoint_heading")) ||
589 (component_element->GetName() == string("waypoint_distance")))
590 {
591 newChannel->Add(new FGWaypoint(this, component_element));
592 } else if (component_element->GetName() == string("angle")) {
593 newChannel->Add(new FGAngles(this, component_element));
594 } else if (component_element->GetName() == string("distributor")) {
595 newChannel->Add(new FGDistributor(this, component_element));
596 } else if (component_element->GetName() == string("linear_actuator")) {
597 newChannel->Add(new FGLinearActuator(this, component_element));
598 } else {
599 FGXMLLogging log(component_element, LogLevel::ERROR);
600 log << "Unknown FCS component: " << component_element->GetName() << endl;
601 }
602 } catch(string& s) {
603 FGXMLLogging log(component_element, LogLevel::ERROR);
604 log << LogFormat::BOLD << LogFormat::RED << endl << " " << s << endl;
605 log << LogFormat::RESET << endl;
606 return false;
607 }
608 component_element = channel_element->GetNextElement();
609 }
610 channel_element = document->FindNextElement("channel");
611 }
612
613 PostLoad(document, FDMExec);
614
615 return true;
616}
617
618//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
619
621{
622 return BrakePos[bg];
623}
624
625//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
626
627SGPath FGFCS::FindFullPathName(const SGPath& path) const
628{
629 SGPath name = FGModel::FindFullPathName(path);
630 if (systype != stSystem || !name.isNull()) return name;
631
632#ifdef _WIN32
633 const array<string, 1> dir_names = {"Systems"};
634#else
635 // Check alternative capitalization for case sensitive OSes.
636 const array<string, 2> dir_names = {"Systems", "systems"};
637#endif
638
639 for(const string& dir_name: dir_names) {
640 name = CheckPathName(FDMExec->GetFullAircraftPath()/dir_name, path);
641 if (!name.isNull()) return name;
642 }
643
644 return CheckPathName(FDMExec->GetSystemsPath(), path);
645}
646
647//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
648
649string FGFCS::GetComponentStrings(const string& delimiter) const
650{
651 string CompStrings = "";
652 bool firstime = true;
653 int total_count=0;
654
655 for (unsigned int i=0; i<SystemChannels.size(); i++)
656 {
657 for (unsigned int c=0; c<SystemChannels[i]->GetNumComponents(); c++)
658 {
659 if (firstime) firstime = false;
660 else CompStrings += delimiter;
661
662 CompStrings += SystemChannels[i]->GetComponent(c)->GetName();
663 total_count++;
664 }
665 }
666
667 return CompStrings;
668}
669
670//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671
672string FGFCS::GetComponentValues(const string& delimiter) const
673{
674 std::ostringstream buf;
675
676 bool firstime = true;
677 int total_count=0;
678
679 for (unsigned int i=0; i<SystemChannels.size(); i++)
680 {
681 for (unsigned int c=0; c<SystemChannels[i]->GetNumComponents(); c++)
682 {
683 if (firstime) firstime = false;
684 else buf << delimiter;
685
686 buf << setprecision(9) << SystemChannels[i]->GetComponent(c)->GetOutput();
687 total_count++;
688 }
689 }
690
691 return buf.str();
692}
693
694//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
695
696void FGFCS::AddThrottle(void)
697{
698 ThrottleCmd.push_back(0.0);
699 ThrottlePos.push_back(0.0);
700 MixtureCmd.push_back(0.0); // assume throttle and mixture are coupled
701 MixturePos.push_back(0.0);
702 PropAdvanceCmd.push_back(0.0); // assume throttle and prop pitch are coupled
703 PropAdvance.push_back(0.0);
704 PropFeatherCmd.push_back(false);
705 PropFeather.push_back(false);
706
707 unsigned int num = (unsigned int)ThrottleCmd.size()-1;
708 bindThrottle(num);
709}
710
711//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
712
713double FGFCS::GetDt(void) const
714{
715 return FDMExec->GetDeltaT()*rate;
716}
717
718//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
719
720void FGFCS::bind(void)
721{
722 PropertyManager->Tie("fcs/aileron-cmd-norm", this, &FGFCS::GetDaCmd, &FGFCS::SetDaCmd);
723 PropertyManager->Tie("fcs/elevator-cmd-norm", this, &FGFCS::GetDeCmd, &FGFCS::SetDeCmd);
724 PropertyManager->Tie("fcs/rudder-cmd-norm", this, &FGFCS::GetDrCmd, &FGFCS::SetDrCmd);
725 PropertyManager->Tie("fcs/flap-cmd-norm", this, &FGFCS::GetDfCmd, &FGFCS::SetDfCmd);
726 PropertyManager->Tie("fcs/speedbrake-cmd-norm", this, &FGFCS::GetDsbCmd, &FGFCS::SetDsbCmd);
727 PropertyManager->Tie("fcs/spoiler-cmd-norm", this, &FGFCS::GetDspCmd, &FGFCS::SetDspCmd);
728 PropertyManager->Tie("fcs/pitch-trim-cmd-norm", this, &FGFCS::GetPitchTrimCmd, &FGFCS::SetPitchTrimCmd);
729 PropertyManager->Tie("fcs/roll-trim-cmd-norm", this, &FGFCS::GetRollTrimCmd, &FGFCS::SetRollTrimCmd);
730 PropertyManager->Tie("fcs/yaw-trim-cmd-norm", this, &FGFCS::GetYawTrimCmd, &FGFCS::SetYawTrimCmd);
731
732 PropertyManager->Tie("fcs/left-aileron-pos-rad", this, ofRad, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
733 PropertyManager->Tie("fcs/left-aileron-pos-deg", this, ofDeg, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
734 PropertyManager->Tie("fcs/left-aileron-pos-norm", this, ofNorm, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
735 PropertyManager->Tie("fcs/mag-left-aileron-pos-rad", this, ofMag, &FGFCS::GetDaLPos);
736
737 PropertyManager->Tie("fcs/right-aileron-pos-rad", this, ofRad, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
738 PropertyManager->Tie("fcs/right-aileron-pos-deg", this, ofDeg, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
739 PropertyManager->Tie("fcs/right-aileron-pos-norm", this, ofNorm, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
740 PropertyManager->Tie("fcs/mag-right-aileron-pos-rad", this, ofMag, &FGFCS::GetDaRPos);
741
742 PropertyManager->Tie("fcs/elevator-pos-rad", this, ofRad, &FGFCS::GetDePos, &FGFCS::SetDePos);
743 PropertyManager->Tie("fcs/elevator-pos-deg", this, ofDeg, &FGFCS::GetDePos, &FGFCS::SetDePos);
744 PropertyManager->Tie("fcs/elevator-pos-norm", this, ofNorm, &FGFCS::GetDePos, &FGFCS::SetDePos);
745 PropertyManager->Tie("fcs/mag-elevator-pos-rad", this, ofMag, &FGFCS::GetDePos);
746
747 PropertyManager->Tie("fcs/rudder-pos-rad", this,ofRad, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
748 PropertyManager->Tie("fcs/rudder-pos-deg", this,ofDeg, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
749 PropertyManager->Tie("fcs/rudder-pos-norm", this,ofNorm, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
750 PropertyManager->Tie("fcs/mag-rudder-pos-rad", this,ofMag, &FGFCS::GetDrPos);
751
752 PropertyManager->Tie("fcs/flap-pos-rad", this,ofRad, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
753 PropertyManager->Tie("fcs/flap-pos-deg", this,ofDeg, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
754 PropertyManager->Tie("fcs/flap-pos-norm", this,ofNorm, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
755
756 PropertyManager->Tie("fcs/speedbrake-pos-rad", this,ofRad, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
757 PropertyManager->Tie("fcs/speedbrake-pos-deg", this,ofDeg, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
758 PropertyManager->Tie("fcs/speedbrake-pos-norm", this,ofNorm, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
759 PropertyManager->Tie("fcs/mag-speedbrake-pos-rad", this,ofMag, &FGFCS::GetDsbPos);
760
761 PropertyManager->Tie("fcs/spoiler-pos-rad", this, ofRad, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
762 PropertyManager->Tie("fcs/spoiler-pos-deg", this, ofDeg, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
763 PropertyManager->Tie("fcs/spoiler-pos-norm", this, ofNorm, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
764 PropertyManager->Tie("fcs/mag-spoiler-pos-rad", this, ofMag, &FGFCS::GetDspPos);
765
766 PropertyManager->Tie("gear/gear-pos-norm", this, &FGFCS::GetGearPos, &FGFCS::SetGearPos);
767 PropertyManager->Tie("gear/gear-cmd-norm", this, &FGFCS::GetGearCmd, &FGFCS::SetGearCmd);
768 PropertyManager->Tie("fcs/left-brake-cmd-norm", this, &FGFCS::GetLBrake, &FGFCS::SetLBrake);
769 PropertyManager->Tie("fcs/right-brake-cmd-norm", this, &FGFCS::GetRBrake, &FGFCS::SetRBrake);
770 PropertyManager->Tie("fcs/center-brake-cmd-norm", this, &FGFCS::GetCBrake, &FGFCS::SetCBrake);
771
772 PropertyManager->Tie("gear/tailhook-pos-norm", this, &FGFCS::GetTailhookPos, &FGFCS::SetTailhookPos);
773 PropertyManager->Tie("fcs/wing-fold-pos-norm", this, &FGFCS::GetWingFoldPos, &FGFCS::SetWingFoldPos);
774 PropertyManager->Tie("simulation/channel-dt", this, &FGFCS::GetChannelDeltaT);
775}
776
777//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
778// Technically, this function should probably bind propulsion type specific controls
779// rather than mixture and prop-advance.
780
781void FGFCS::bindThrottle(unsigned int num)
782{
783 string tmp;
784
785 tmp = CreateIndexedPropertyName("fcs/throttle-cmd-norm", num);
786 PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetThrottleCmd,
788 tmp = CreateIndexedPropertyName("fcs/throttle-pos-norm", num);
789 PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetThrottlePos,
791 tmp = CreateIndexedPropertyName("fcs/mixture-cmd-norm", num);
792 PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetMixtureCmd,
794 tmp = CreateIndexedPropertyName("fcs/mixture-pos-norm", num);
795 PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetMixturePos,
797 tmp = CreateIndexedPropertyName("fcs/advance-cmd-norm", num);
798 PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropAdvanceCmd,
800 tmp = CreateIndexedPropertyName("fcs/advance-pos-norm", num);
801 PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropAdvance,
803 tmp = CreateIndexedPropertyName("fcs/feather-cmd-norm", num);
804 PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetFeatherCmd,
806 tmp = CreateIndexedPropertyName("fcs/feather-pos-norm", num);
807 PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropFeather,
809}
810
811//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
812// The bitmasked value choices are as follows:
813// unset: In this case (the default) JSBSim would only print
814// out the normally expected messages, essentially echoing
815// the config files as they are read. If the environment
816// variable is not set, debug_lvl is set to 1 internally
817// 0: This requests JSBSim not to output any messages
818// whatsoever.
819// 1: This value explicity requests the normal JSBSim
820// startup messages
821// 2: This value asks for a message to be printed out when
822// a class is instantiated
823// 4: When this value is set, a message is displayed when a
824// FGModel object executes its Run() method
825// 8: When this value is set, various runtime state variables
826// are printed out periodically
827// 16: When set various parameters are sanity checked and
828// a message is printed out when they go out of bounds
829
830void FGFCS::Debug(int from)
831{
832 if (debug_lvl <= 0) return;
833
834 if (debug_lvl & 1) { // Standard console startup message output
835 FGLogging log(LogLevel::DEBUG);
836 if (from == 2) { // Loader
837 log << endl << " " << Name << endl;
838 }
839 }
840 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
841 FGLogging log(LogLevel::DEBUG);
842 if (from == 0) log << "Instantiated: FGFCS" << endl;
843 if (from == 1) log << "Destroyed: FGFCS" << endl;
844 }
845 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
846 }
847 if (debug_lvl & 8 ) { // Runtime state variables
848 }
849 if (debug_lvl & 16) { // Sanity checking
850 }
851 if (debug_lvl & 64) {
852 if (from == 0) { // Constructor
853 }
854 }
855}
856
857}
Element * FindElement(const std::string &el="")
Searches for a specified element.
const std::string & GetName(void) const
Retrieves the element name.
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.
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.
Element * GetNextElement(void)
Returns a pointer to the next element in the list.
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.
Models a FCSFunction object.
void SetThrottlePos(int engine, double cmd)
Sets the actual throttle setting for the specified engine.
Definition FGFCS.cpp:338
void SetPitchTrimCmd(double cmd)
Sets the pitch trim command.
Definition FGFCS.h:410
void SetDaLPos(int form, double pos)
Sets the left aileron position.
Definition FGFCS.cpp:186
bool Load(Element *el) override
Loads the Flight Control System.
Definition FGFCS.cpp:481
void SetGearPos(double gearpos)
Set the gear extend/retract position, defaults to down.
Definition FGFCS.h:498
double GetCBrake(void) const
Gets the center brake.
Definition FGFCS.h:550
void SetDsbPos(int form, double pos)
Sets the speedbrake position.
Definition FGFCS.cpp:281
double GetLBrake(void) const
Gets the left brake.
Definition FGFCS.h:542
double GetDfPos(int form=ofRad) const
Gets the flaps position.
Definition FGFCS.h:319
void SetDsbCmd(double cmd)
Sets the speedbrake command.
Definition FGFCS.h:402
bool GetFeatherCmd(int engine) const
Gets the prop feather command.
Definition FGFCS.h:265
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:649
void SetMixtureCmd(int engine, double cmd)
Sets the mixture command for the specified engine.
Definition FGFCS.cpp:397
double GetTailhookPos(void) const
Gets the tailhook position (0 up, 1 down)
Definition FGFCS.h:346
void SetPropFeather(int engine, bool cmd)
Sets the actual prop feather setting for the specified engine.
Definition FGFCS.cpp:467
double GetPropAdvanceCmd(int engine) const
Gets the prop pitch command.
Definition FGFCS.h:260
void SetFeatherCmd(int engine, bool cmd)
Sets the propeller feather command for the specified engine.
Definition FGFCS.cpp:453
void SetDeCmd(double cmd)
Sets the elevator command.
Definition FGFCS.h:386
double GetDePos(int form=ofRad) const
Gets the elevator position.
Definition FGFCS.h:299
void SetDrPos(int form, double pos)
Sets the rudder position.
Definition FGFCS.cpp:243
void SetMixturePos(int engine, double cmd)
Sets the actual mixture setting for the specified engine.
Definition FGFCS.cpp:411
void SetDaCmd(double cmd)
Sets the aileron command.
Definition FGFCS.h:382
double GetDsbPos(int form=ofRad) const
Gets the speedbrake position.
Definition FGFCS.h:309
double GetRBrake(void) const
Gets the right brake.
Definition FGFCS.h:546
void SetDaRPos(int form, double pos)
Sets the right aileron position.
Definition FGFCS.cpp:205
void SetDePos(int form, double pos)
Sets the elevator position.
Definition FGFCS.cpp:224
void SetRBrake(double cmd)
Sets the right brake group.
Definition FGFCS.h:527
void SetDrCmd(double cmd)
Sets the rudder command.
Definition FGFCS.h:390
double GetDrCmd(void) const
Gets the rudder command.
Definition FGFCS.h:221
FGFCS(FGFDMExec *)
Constructor.
Definition FGFCS.cpp:74
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:289
double GetRollTrimCmd(void) const
Gets the aileron trim command.
Definition FGFCS.h:277
~FGFCS() override
Destructor.
Definition FGFCS.cpp:97
void SetDfPos(int form, double pos)
Sets the flaps position.
Definition FGFCS.cpp:262
double GetDaRPos(int form=ofRad) const
Gets the right aileron position.
Definition FGFCS.h:294
void SetDspPos(int form, double pos)
Sets the spoiler position.
Definition FGFCS.cpp:300
void SetTailhookPos(double hookpos)
Set the tailhook position.
Definition FGFCS.h:502
void SetDfCmd(double cmd)
Sets the flaps command.
Definition FGFCS.h:398
double GetBrake(FGLGear::BrakeGroup bg)
Gets the brake for a specified group.
Definition FGFCS.cpp:620
double GetWingFoldPos(void) const
Gets the wing fold position (0 unfolded, 1 folded)
Definition FGFCS.h:350
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:439
std::string GetComponentValues(const std::string &delimiter) const
Retrieves all component outputs for inclusion in output stream.
Definition FGFCS.cpp:672
double GetPitchTrimCmd(void) const
Gets the pitch trim command.
Definition FGFCS.h:269
void SetThrottleCmd(int engine, double cmd)
Sets the throttle command for the specified engine.
Definition FGFCS.cpp:319
double GetGearPos(void) const
Gets the gear position (0 up, 1 down), defaults to down.
Definition FGFCS.h:342
double GetDsbCmd(void) const
Gets the speedbrake command.
Definition FGFCS.h:233
void SetDspCmd(double cmd)
Sets the spoilers command.
Definition FGFCS.h:406
void SetLBrake(double cmd)
Sets the left brake group.
Definition FGFCS.h:523
double GetDspPos(int form=ofRad) const
Gets the spoiler position.
Definition FGFCS.h:314
void SetCBrake(double cmd)
Sets the center brake group.
Definition FGFCS.h:531
double GetYawTrimCmd(void) const
Gets the rudder trim command.
Definition FGFCS.h:273
void SetPropAdvanceCmd(int engine, double cmd)
Sets the propeller pitch command for the specified engine.
Definition FGFCS.cpp:425
void SetRollTrimCmd(double cmd)
Sets the aileron trim command.
Definition FGFCS.h:418
void SetYawTrimCmd(double cmd)
Sets the rudder trim command.
Definition FGFCS.h:414
double GetGearCmd(void) const
Get the gear extend/retract command.
Definition FGFCS.h:282
void SetWingFoldPos(double foldpos)
Set the wing fold position.
Definition FGFCS.h:506
double GetDrPos(int form=ofRad) const
Gets the rudder position.
Definition FGFCS.h:304
void SetGearCmd(double gearcmd)
Set the gear extend/retract command, defaults to down.
Definition FGFCS.h:436
Encapsulates the JSBSim simulation executive.
Definition FGFDMExec.h:185
const SGPath & GetFullAircraftPath(void)
Retrieves the full aircraft path name.
Definition FGFDMExec.h:402
double GetDeltaT(void) const
Returns the simulation delta T.
Definition FGFDMExec.h:553
const SGPath & GetSystemsPath(void)
Retrieves the systems path.
Definition FGFDMExec.h:400
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
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:90
bool Upload(Element *el, bool preLoad)
Uploads this model in memory.
Definition FGModel.cpp:111
Encapsulates a PID control component for the flight control system.
Definition FGPID.h:126
Encapsulates a Sensor component for the flight control system.
Definition FGSensor.h:134
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
A node in a property tree.
Definition props.hxx:747
Main namespace for the JSBSim Flight Dynamics Model.
Definition FGFDMExec.cpp:71