JSBSim Flight Dynamics Model  1.1.11 (13 Feb 2022)
An Open Source Flight Dynamics and Control Software Library in C++
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 
26 FUNCTIONAL DESCRIPTION
27 --------------------------------------------------------------------------------
28 
29 HISTORY
30 --------------------------------------------------------------------------------
31 
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 COMMENTS, REFERENCES, and NOTES
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 
36 The switch component is defined as follows (see the API documentation for more
37 information):
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 
58 Also, see the header file (FGSwitch.h) for further details.
59 
60 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61 INCLUDES
62 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
63 
64 #include "FGSwitch.h"
65 #include "math/FGCondition.h"
66 
67 using namespace std;
68 
69 namespace JSBSim {
70 
71 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72 CLASS IMPLEMENTATION
73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
74 
75 FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
76 {
77  string value;
78  Test *current_test;
79 
80  bind(element); // Bind() this component here in case it is used in its own
81  // definition for a sample-and-hold
82  Element* test_element = element->FindElement("default");
83  if (test_element) {
84  current_test = new Test;
85  value = test_element->GetAttributeValue("value");
86  current_test->setTestValue(value, Name, PropertyManager);
87  current_test->Default = true;
88  if (delay > 0 && is_number(value)) { // If there is a delay, initialize the
89  for (unsigned int i=0; i<delay-1; i++) { // delay buffer to the default value
90  output_array[i] = atof(value.c_str()); // for the switch if that value is a number.
91  }
92  }
93  tests.push_back(current_test);
94  }
95 
96  test_element = element->FindElement("test");
97  while (test_element) {
98  current_test = new Test;
99  current_test->condition = new FGCondition(test_element, PropertyManager);
100  value = test_element->GetAttributeValue("value");
101  current_test->setTestValue(value, Name, PropertyManager);
102  tests.push_back(current_test);
103  test_element = element->FindNextElement("test");
104  }
105 
106  Debug(0);
107 }
108 
109 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110 
112 {
113  for (auto test: tests) {
114  delete test->condition;
115  delete test;
116  }
117 
118  Debug(1);
119 }
120 
121 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122 
123 bool FGSwitch::Run(void )
124 {
125  bool pass = false;
126  double default_output=0.0;
127 
128  // To detect errors early, make sure all conditions and values can be
129  // evaluated in the first time step.
130  if (!initialized) {
131  initialized = true;
132  VerifyProperties();
133  }
134 
135  for (auto test: tests) {
136  if (test->Default) {
137  default_output = test->OutputValue->GetValue();
138  } else {
139  pass = test->condition->Evaluate();
140  }
141 
142  if (pass) {
143  Output = test->OutputValue->GetValue();
144  break;
145  }
146  }
147 
148  if (!pass) Output = default_output;
149 
150  if (delay != 0) Delay();
151  Clip();
152  SetOutput();
153 
154  return true;
155 }
156 
157 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158 
159 void FGSwitch::VerifyProperties(void)
160 {
161  for (auto test: tests) {
162  if (!test->Default) {
163  test->condition->Evaluate();
164  }
165  test->OutputValue->GetValue();
166  }
167 }
168 
169 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170 // The bitmasked value choices are as follows:
171 // unset: In this case (the default) JSBSim would only print
172 // out the normally expected messages, essentially echoing
173 // the config files as they are read. If the environment
174 // variable is not set, debug_lvl is set to 1 internally
175 // 0: This requests JSBSim not to output any messages
176 // whatsoever.
177 // 1: This value explicity requests the normal JSBSim
178 // startup messages
179 // 2: This value asks for a message to be printed out when
180 // a class is instantiated
181 // 4: When this value is set, a message is displayed when a
182 // FGModel object executes its Run() method
183 // 8: When this value is set, various runtime state variables
184 // are printed out periodically
185 // 16: When set various parameters are sanity checked and
186 // a message is printed out when they go out of bounds
187 
188 void FGSwitch::Debug(int from)
189 {
190  if (debug_lvl <= 0) return;
191 
192  if (debug_lvl & 1) { // Standard console startup message output
193  if (from == 0) { // Constructor
194  unsigned int i = 0;
195  for (auto test: tests) {
196  if (test->Default) {
197  cout << " Switch default value is: " << test->GetOutputName();
198  } else {
199  cout << " Switch takes test " << i << " value (" << test->GetOutputName() << ")" << endl;
200 
201  test->condition->PrintCondition(" ");
202  }
203  cout << endl;
204  ++i;
205  }
206  for (auto node: OutputNodes)
207  cout << " OUTPUT: " << node->getNameString() << endl;
208  }
209  }
210  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
211  if (from == 0) cout << "Instantiated: FGSwitch" << endl;
212  if (from == 1) cout << "Destroyed: FGSwitch" << endl;
213  }
214  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
215  }
216  if (debug_lvl & 8 ) { // Runtime state variables
217  }
218  if (debug_lvl & 16) { // Sanity checking
219  }
220  if (debug_lvl & 64) {
221  if (from == 0) { // Constructor
222  }
223  }
224 }
225 
226 } //namespace JSBSim
227 
JSBSim::Element::GetAttributeValue
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
Definition: FGXMLElement.cpp:260
JSBSim::FGSwitch::Run
bool Run(void) override
Executes the switch logic.
Definition: FGSwitch.cpp:123
JSBSim::Element::FindElement
Element * FindElement(const std::string &el="")
Searches for a specified element.
Definition: FGXMLElement.cpp:389
JSBSim::FGFCSComponent
Base class for JSBSim Flight Control System Components.
Definition: FGFCSComponent.h:84
JSBSim::FGSwitch::~FGSwitch
~FGSwitch()
Destructor.
Definition: FGSwitch.cpp:111
JSBSim::FGFCS
Encapsulates the Flight Control System (FCS) functionality.
Definition: FGFCS.h:187
JSBSim::Element::FindNextElement
Element * FindNextElement(const std::string &el="")
Searches for the next element as specified.
Definition: FGXMLElement.cpp:407
JSBSim::FGCondition
Encapsulates a condition, which is used in parts of JSBSim including switches.
Definition: FGCondition.h:66
JSBSim::Element
Definition: FGXMLElement.h:143