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
FGSwitch.cpp
1/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3 Module: FGSwitch.cpp
4 Author: Jon S. Berndt
5 Date started: 4/2000
6
7 ------------- Copyright (C) 2000 -------------
8
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 2 of the License, or (at your option) any
12 later version.
13
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 details.
18
19 You should have received a copy of the GNU Lesser General Public License along
20 with this program; if not, write to the Free Software Foundation, Inc., 59
21 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23 Further information about the GNU Lesser General Public License can also be
24 found on the world wide web at http://www.gnu.org.
25
26FUNCTIONAL DESCRIPTION
27--------------------------------------------------------------------------------
28
29HISTORY
30--------------------------------------------------------------------------------
31
32%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33COMMENTS, REFERENCES, and NOTES
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35
36The switch component is defined as follows (see the API documentation for more
37information):
38
39@code
40<switch name="switch1">
41 <default value="{property|value}"/>
42 <test logic="{AND|OR}" value="{property|value}">
43 {property} {conditional} {property|value}
44 <test logic="{AND|OR}">
45 {property} {conditional} {property|value}
46 ...
47 </test>
48 ...
49 </test>
50 <test logic="{AND|OR}" value="{property|value}">
51 {property} {conditional} {property|value}
52 ...
53 </test>
54 ...
55</switch>
56@endcode
57
58Also, see the header file (FGSwitch.h) for further details.
59
60%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61INCLUDES
62%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
63
64#include "FGSwitch.h"
65#include "models/FGFCS.h"
66#include "math/FGCondition.h"
67#include "input_output/FGLog.h"
68#include "math/FGRealValue.h"
69
70using namespace std;
71
72namespace JSBSim {
73
74/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75CLASS IMPLEMENTATION
76%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
77
78FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
79{
80 string value;
81 unique_ptr<Test> current_test;
82 auto PropertyManager = fcs->GetPropertyManager();
83
84 bind(element, PropertyManager.get()); // Bind() this component here in case it is used in its own
85 // definition for a sample-and-hold
86 Element* test_element = element->FindElement("default");
87 if (test_element) {
88 try {
89 current_test = make_unique<Test>();
90 value = test_element->GetAttributeValue("value");
91 current_test->setTestValue(value, Name, PropertyManager, test_element);
92 current_test->Default = true;
93 auto output_value = current_test->OutputValue.ptr();
94 if (delay > 0 && dynamic_cast<FGRealValue*>(output_value)) { // If there is a delay
95 double v = output_value->GetValue();
96 for (unsigned int i=0; i<delay-1; i++) { // Initialize the delay buffer to the default value
97 output_array[i] = v; // for the switch if that value is a number.
98 }
99 }
100 tests.push_back(current_test.release());
101 } catch (const BaseException& e) {
102 FGXMLLogging log(test_element, LogLevel::ERROR);
103 log << e.what() << "\n"
104 << " Default value IGNORED.\n";
105 }
106 }
107
108 test_element = element->FindElement("test");
109 while (test_element) {
110 try {
111 current_test = make_unique<Test>();
112 current_test->condition = make_unique<FGCondition>(test_element, PropertyManager);
113 value = test_element->GetAttributeValue("value");
114 current_test->setTestValue(value, Name, PropertyManager, test_element);
115 tests.push_back(current_test.release());
116 } catch (const BaseException& e) {
117 FGXMLLogging log(test_element, LogLevel::ERROR);
118 log << e.what() << "\n"
119 << " Test IGNORED.\n";
120 }
121
122 test_element = element->FindNextElement("test");
123 }
124
125 Debug(0);
126}
127
128//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129
131{
132 for (auto test: tests) delete test;
133 Debug(1);
134}
135
136//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
137
138bool FGSwitch::Run(void )
139{
140 bool pass = false;
141 double default_output=0.0;
142
143 // To detect errors early, make sure all conditions and values can be
144 // evaluated in the first time step.
145 if (!initialized) {
146 initialized = true;
147 VerifyProperties();
148 }
149
150 for (auto test: tests) {
151 if (test->Default) {
152 default_output = test->OutputValue->GetValue();
153 } else {
154 pass = test->condition->Evaluate();
155 }
156
157 if (pass) {
158 Output = test->OutputValue->GetValue();
159 break;
160 }
161 }
162
163 if (!pass) Output = default_output;
164
165 if (delay != 0) Delay();
166 Clip();
167 SetOutput();
168
169 return true;
170}
171
172//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173
174void FGSwitch::VerifyProperties(void)
175{
176 for (auto test: tests) {
177 if (!test->Default) {
178 test->condition->Evaluate();
179 }
180 test->OutputValue->GetValue();
181 }
182}
183
184//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185// The bitmasked value choices are as follows:
186// unset: In this case (the default) JSBSim would only print
187// out the normally expected messages, essentially echoing
188// the config files as they are read. If the environment
189// variable is not set, debug_lvl is set to 1 internally
190// 0: This requests JSBSim not to output any messages
191// whatsoever.
192// 1: This value explicitly requests the normal JSBSim
193// startup messages
194// 2: This value asks for a message to be printed out when
195// a class is instantiated
196// 4: When this value is set, a message is displayed when a
197// FGModel object executes its Run() method
198// 8: When this value is set, various runtime state variables
199// are printed out periodically
200// 16: When set various parameters are sanity checked and
201// a message is printed out when they go out of bounds
202
203void FGSwitch::Debug(int from)
204{
205 if (debug_lvl <= 0) return;
206
207 if (debug_lvl & 1) { // Standard console startup message output
208 if (from == 0) { // Constructor
209 FGLogging log(LogLevel::DEBUG);
210 unsigned int i = 0;
211 for (auto test: tests) {
212 if (test->Default) {
213 log << " Switch default value is: " << test->GetOutputName();
214 } else {
215 log << " Switch takes test " << i << " value (" << test->GetOutputName() << ")\n";
216
217 test->condition->PrintCondition(" ");
218 }
219 log << "\n";
220 ++i;
221 }
222 for (auto node: OutputNodes)
223 log << " OUTPUT: " << node->getNameString() << "\n";
224 }
225 }
226 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
227 FGLogging log(LogLevel::DEBUG);
228 if (from == 0) log << "Instantiated: FGSwitch\n";
229 if (from == 1) log << "Destroyed: FGSwitch\n";
230 }
231 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
232 }
233 if (debug_lvl & 8 ) { // Runtime state variables
234 }
235 if (debug_lvl & 16) { // Sanity checking
236 }
237 if (debug_lvl & 64) {
238 if (from == 0) { // Constructor
239 }
240 }
241}
242
243} //namespace JSBSim
Element * FindElement(const std::string &el="")
Searches for a specified element.
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
Element * FindNextElement(const std::string &el="")
Searches for the next element as specified.
Base class for JSBSim Flight Control System Components.
Encapsulates the Flight Control System (FCS) functionality.
Definition FGFCS.h:189
Represents a real value.
Definition FGRealValue.h:58
FGSwitch(FGFCS *fcs, Element *element)
Constructor.
Definition FGSwitch.cpp:78
~FGSwitch()
Destructor.
Definition FGSwitch.cpp:130
bool Run(void) override
Executes the switch logic.
Definition FGSwitch.cpp:138
Main namespace for the JSBSim Flight Dynamics Model.
Definition FGFDMExec.cpp:71