]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/flight_control/FGSwitch.cpp
Hide some user generated files.
[flightgear.git] / src / FDM / JSBSim / models / flight_control / 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 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 General Public License for more
17  details.
18
19  You should have received a copy of the GNU 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 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 <COMPONENT NAME="switch1" TYPE="SWITCH">
40   <TEST LOGIC="{AND|OR|DEFAULT}" OUTPUT="{property|value}">
41     {property} {conditional} {property|value}
42     <CONDITION_GROUP LOGIC="{AND|OR}">
43       {property} {conditional} {property|value}
44       ...
45     </CONDITION_GROUP>
46     ...
47   </TEST>
48   <TEST LOGIC="{AND|OR}" OUTPUT="{property|value}">
49     {property} {conditional} {property|value}
50     ...
51   </TEST>
52   ...
53 </COMPONENT>
54
55 Also, see the header file (FGSwitch.h) for further details.
56
57 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58 INCLUDES
59 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
60
61 #include "FGSwitch.h"
62
63 namespace JSBSim {
64
65 static const char *IdSrc = "$Id$";
66 static const char *IdHdr = ID_SWITCH;
67
68 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
69 CLASS IMPLEMENTATION
70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
71
72 FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
73 {
74   string value, logic;
75   struct test *current_test;
76   Element *test_element, *condition_element;
77
78   test_element = element->GetElement();
79   while (test_element) {
80     if (test_element->GetName() == "default") {
81       tests.push_back(test());
82       current_test = &tests.back();
83       current_test->Logic = eDefault;
84     } else if (test_element->GetName() == "test") { // here's a test
85       tests.push_back(test());
86       current_test = &tests.back();
87       logic = test_element->GetAttributeValue("logic");
88       if (logic == "OR") current_test->Logic = eOR;
89       else if (logic == "AND") current_test->Logic = eAND;
90       else if (logic.size() == 0) current_test->Logic = eAND; // default
91       else { // error
92         cerr << "Unrecognized LOGIC token " << logic << " in switch component: " << Name << endl;
93       }
94       for (int i=0; i<test_element->GetNumDataLines(); i++)
95         current_test->conditions.push_back(FGCondition(test_element->GetDataLine(i), PropertyManager));
96
97       condition_element = test_element->GetElement(); // retrieve condition groups
98       while (condition_element) {
99         current_test->conditions.push_back(FGCondition(condition_element, PropertyManager));
100         condition_element = test_element->GetNextElement();
101       }
102
103     }
104
105     if (test_element->GetName() != "output") { // this is not an output element
106       value = test_element->GetAttributeValue("value");
107       if (value.empty()) {
108         cerr << "No VALUE supplied for switch component: " << Name << endl;
109       } else {
110         if (value.find_first_not_of("-.0123456789eE") == string::npos) {
111           // if true (and execution falls into this block), "value" is a number.
112           current_test->OutputVal = atof(value.c_str());
113         } else {
114           // "value" must be a property if execution passes to here.
115           if (value[0] == '-') {
116             current_test->sign = -1.0;
117             value.erase(0,1);
118           } else {
119             current_test->sign = 1.0;
120           }
121           current_test->OutputProp = PropertyManager->GetNode(value);
122         }
123       }
124     }
125
126     test_element = element->GetNextElement();
127   }
128
129   FGFCSComponent::bind();
130
131   Debug(0);
132 }
133
134 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135
136 FGSwitch::~FGSwitch()
137 {
138   Debug(1);
139 }
140
141 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142
143 bool FGSwitch::Run(void )
144 {
145   vector <test>::iterator iTests = tests.begin();
146   vector <FGCondition>::iterator iConditions;
147   bool pass = false;
148
149   while (iTests < tests.end()) {
150     iConditions = iTests->conditions.begin();
151
152     if (iTests->Logic == eDefault) {
153       Output = iTests->GetValue();
154     } else if (iTests->Logic == eAND) {
155       pass = true;
156       while (iConditions < iTests->conditions.end()) {
157         if (!iConditions->Evaluate()) pass = false;
158         *iConditions++;
159       }
160     } else if (iTests->Logic == eOR) {
161       pass = false;
162       while (iConditions < iTests->conditions.end()) {
163         if (iConditions->Evaluate()) pass = true;
164         *iConditions++;
165       }
166     } else {
167       cerr << "Invalid logic test" << endl;
168     }
169
170     if (pass) {
171       Output = iTests->GetValue();
172       break;
173     }
174     *iTests++;
175   }
176
177   Clip();
178   if (IsOutput) SetOutput();
179
180   return true;
181 }
182
183 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
184 //    The bitmasked value choices are as follows:
185 //    unset: In this case (the default) JSBSim would only print
186 //       out the normally expected messages, essentially echoing
187 //       the config files as they are read. If the environment
188 //       variable is not set, debug_lvl is set to 1 internally
189 //    0: This requests JSBSim not to output any messages
190 //       whatsoever.
191 //    1: This value explicity requests the normal JSBSim
192 //       startup messages
193 //    2: This value asks for a message to be printed out when
194 //       a class is instantiated
195 //    4: When this value is set, a message is displayed when a
196 //       FGModel object executes its Run() method
197 //    8: When this value is set, various runtime state variables
198 //       are printed out periodically
199 //    16: When set various parameters are sanity checked and
200 //       a message is printed out when they go out of bounds
201
202 void FGSwitch::Debug(int from)
203 {
204   vector <test>::iterator iTests = tests.begin();
205   vector <FGCondition>::iterator iConditions;
206   string comp, scratch;
207   string indent = "        ";
208   bool first = false;
209
210   if (debug_lvl <= 0) return;
211
212   if (debug_lvl & 1) { // Standard console startup message output
213     if (from == 0) { // Constructor
214       while (iTests < tests.end()) {
215
216         scratch = " if ";
217
218         switch(iTests->Logic) {
219         case (elUndef):
220           comp = " UNSET ";
221           cerr << "Unset logic for test condition" << endl;
222           break;
223         case (eAND):
224           comp = " AND ";
225           break;
226         case (eOR):
227           comp=" OR ";
228           break;
229         case (eDefault):
230           scratch = " by default.";
231           break;
232         default:
233           comp = " UNKNOWN ";
234           cerr << "Unknown logic for test condition" << endl;
235         }
236
237         if (iTests->OutputProp != 0L)
238           if (iTests->sign < 0)
239             cout << indent << "Switch VALUE is - " << iTests->OutputProp->GetName() << scratch << endl;
240           else
241             cout << indent << "Switch VALUE is " << iTests->OutputProp->GetName() << scratch << endl;
242         else
243           cout << indent << "Switch VALUE is " << iTests->OutputVal << scratch << endl;
244
245         iConditions = iTests->conditions.begin();
246         first = true;
247         while (iConditions < iTests->conditions.end()) {
248           if (!first) cout << indent << comp << " ";
249           else cout << indent << " ";
250           first = false;
251           iConditions->PrintCondition();
252           cout << endl;
253           *iConditions++;
254         }
255         cout << endl;
256         *iTests++;
257       }
258       if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
259     }
260   }
261   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
262     if (from == 0) cout << "Instantiated: FGSwitch" << endl;
263     if (from == 1) cout << "Destroyed:    FGSwitch" << endl;
264   }
265   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
266   }
267   if (debug_lvl & 8 ) { // Runtime state variables
268   }
269   if (debug_lvl & 16) { // Sanity checking
270   }
271   if (debug_lvl & 64) {
272     if (from == 0) { // Constructor
273       cout << IdSrc << endl;
274       cout << IdHdr << endl;
275     }
276   }
277 }
278
279 } //namespace JSBSim
280