JSBSim Flight Dynamics Model  1.0 (02 March 2017)
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 Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  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 with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA 02111-1307, USA.
22 
23  Further information about the GNU Lesser General Public License can also be found on
24  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 <iostream>
65 
66 #include "FGSwitch.h"
67 #include "input_output/FGXMLElement.h"
68 
69 using namespace std;
70 
71 namespace JSBSim {
72 
73 IDENT(IdSrc,"$Id: FGSwitch.cpp,v 1.29 2014/01/13 10:46:10 ehofman Exp $");
74 IDENT(IdHdr,ID_SWITCH);
75 
76 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77 CLASS IMPLEMENTATION
78 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
79 
80 FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
81 {
82  string value;
83  struct test *current_test;
84  Element *test_element;
85 
86  FGFCSComponent::bind(); // Bind() this component here in case it is used
87  // in its own definition for a sample-and-hold
88 
89  int num = element->GetNumElements("test");
90  if (element->FindElement("default")) num++;
91  tests.reserve(num);
92 
93  test_element = element->FindElement("default");
94  if (test_element) {
95  current_test = new struct test;
96  current_test->condition = 0;
97  value = test_element->GetAttributeValue("value");
98  current_test->setTestValue(value, Name, PropertyManager);
99  current_test->Default = true;
100  if (delay > 0 && is_number(value)) { // If there is a delay, initialize the
101  for (unsigned int i=0; i<delay-1; i++) { // delay buffer to the default value
102  output_array[i] = atof(value.c_str()); // for the switch if that value is a number.
103  }
104  }
105  tests.push_back(current_test);
106  }
107 
108  test_element = element->FindElement("test");
109  while (test_element) {
110  current_test = new struct test;
111  current_test->condition = new FGCondition(test_element, PropertyManager);
112  value = test_element->GetAttributeValue("value");
113  current_test->setTestValue(value, Name, PropertyManager);
114  tests.push_back(current_test);
115  test_element = element->FindNextElement("test");
116  }
117 
118  Debug(0);
119 }
120 
121 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122 
124 {
125  for (unsigned int i=0; i<tests.size(); i++) {
126  delete tests[i]->condition;
127  delete tests[i]->OutputProp;
128  delete tests[i];
129  }
130 
131  Debug(1);
132 }
133 
134 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 
136 bool FGSwitch::Run(void )
137 {
138  bool pass = false;
139  double default_output=0.0;
140 
141  for (unsigned int i=0; i<tests.size(); i++) {
142  if (tests[i]->Default) {
143  default_output = tests[i]->GetValue();
144  } else {
145  pass = tests[i]->condition->Evaluate();
146  }
147 
148  if (pass) {
149  Output = tests[i]->GetValue();
150  break;
151  }
152  }
153 
154  if (!pass) Output = default_output;
155 
156  if (delay != 0) Delay();
157  Clip();
158  if (IsOutput) SetOutput();
159 
160  return true;
161 }
162 
163 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164 // The bitmasked value choices are as follows:
165 // unset: In this case (the default) JSBSim would only print
166 // out the normally expected messages, essentially echoing
167 // the config files as they are read. If the environment
168 // variable is not set, debug_lvl is set to 1 internally
169 // 0: This requests JSBSim not to output any messages
170 // whatsoever.
171 // 1: This value explicity requests the normal JSBSim
172 // startup messages
173 // 2: This value asks for a message to be printed out when
174 // a class is instantiated
175 // 4: When this value is set, a message is displayed when a
176 // FGModel object executes its Run() method
177 // 8: When this value is set, various runtime state variables
178 // are printed out periodically
179 // 16: When set various parameters are sanity checked and
180 // a message is printed out when they go out of bounds
181 
182 void FGSwitch::Debug(int from)
183 {
184  string comp, scratch;
185  string indent = " ";
186  //bool first = false;
187 
188  if (debug_lvl <= 0) return;
189 
190  if (debug_lvl & 1) { // Standard console startup message output
191  if (from == 0) { // Constructor
192  for (unsigned int i=0; i<tests.size(); i++) {
193  if (tests[i]->Default) {
194  if (tests[i]->OutputProp == 0) {
195  cout << " Switch default value is: " << tests[i]->OutputVal;
196  } else {
197  cout << " Switch default value is: " << tests[i]->OutputProp->GetName();
198  }
199  } else {
200  if (tests[i]->OutputProp == 0) {
201  cout << " Switch takes test " << i << " value (" << tests[i]->OutputVal << ")" << endl;
202  } else {
203  cout << " Switch takes test " << i << " value (" << tests[i]->OutputProp->GetName() << ")" << endl;
204  }
205  tests[i]->condition->PrintCondition(" ");
206  }
207  cout << endl;
208  }
209  if (IsOutput) {
210  for (unsigned int i=0; i<OutputNodes.size(); i++)
211  cout << " OUTPUT: " << OutputNodes[i]->getName() << endl;
212  }
213  }
214  }
215  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
216  if (from == 0) cout << "Instantiated: FGSwitch" << endl;
217  if (from == 1) cout << "Destroyed: FGSwitch" << endl;
218  }
219  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
220  }
221  if (debug_lvl & 8 ) { // Runtime state variables
222  }
223  if (debug_lvl & 16) { // Sanity checking
224  }
225  if (debug_lvl & 64) {
226  if (from == 0) { // Constructor
227  cout << IdSrc << endl;
228  cout << IdHdr << endl;
229  }
230  }
231 }
232 
233 } //namespace JSBSim
234 
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
~FGSwitch()
Destructor.
Definition: FGSwitch.cpp:123
STL namespace.
Element * FindElement(const std::string &el="")
Searches for a specified element.
bool Run(void)
Executes the switch logic.
Definition: FGSwitch.cpp:136
unsigned int GetNumElements(void)
Returns the number of child elements for this element.
Definition: FGXMLElement.h:198
Encapsulates the Flight Control System (FCS) functionality.
Definition: FGFCS.h:193
Element * FindNextElement(const std::string &el="")
Searches for the next element as specified.
Base class for JSBSim Flight Control System Components.
Encapsulates a condition, which is used in parts of JSBSim including switches.
Definition: FGCondition.h:70