JSBSim Flight Dynamics Model 1.0 (23 February 2013)
An Open Source Flight Dynamics and Control Software Library in C++

FGSwitch.cpp

00001 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00002 
00003  Module:       FGSwitch.cpp
00004  Author:       Jon S. Berndt
00005  Date started: 4/2000
00006 
00007  ------------- Copyright (C) 2000 -------------
00008 
00009  This program is free software; you can redistribute it and/or modify it under
00010  the terms of the GNU Lesser General Public License as published by the Free Software
00011  Foundation; either version 2 of the License, or (at your option) any later
00012  version.
00013 
00014  This program is distributed in the hope that it will be useful, but WITHOUT
00015  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00016  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00017  details.
00018 
00019  You should have received a copy of the GNU Lesser General Public License along with
00020  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021  Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00023  Further information about the GNU Lesser General Public License can also be found on
00024  the world wide web at http://www.gnu.org.
00025 
00026 FUNCTIONAL DESCRIPTION
00027 --------------------------------------------------------------------------------
00028 
00029 HISTORY
00030 --------------------------------------------------------------------------------
00031 
00032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00033 COMMENTS, REFERENCES,  and NOTES
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 
00036 The switch component is defined as follows (see the API documentation for more
00037 information):
00038 
00039 @code
00040 <switch name="switch1">
00041   <default value="{property|value}"/>
00042   <test logic="{AND|OR}" value="{property|value}">
00043     {property} {conditional} {property|value}
00044     <test logic="{AND|OR}">
00045       {property} {conditional} {property|value}
00046       ...
00047     </test>
00048     ...
00049   </test>
00050   <test logic="{AND|OR}" value="{property|value}">
00051     {property} {conditional} {property|value}
00052     ...
00053   </test>
00054   ...
00055 </switch>
00056 @endcode
00057 
00058 Also, see the header file (FGSwitch.h) for further details.
00059 
00060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00061 INCLUDES
00062 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
00063 
00064 #include "FGSwitch.h"
00065 #include <iostream>
00066 
00067 using namespace std;
00068 
00069 namespace JSBSim {
00070 
00071 static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.25 2012/12/02 12:59:19 bcoconni Exp $";
00072 static const char *IdHdr = ID_SWITCH;
00073 
00074 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00075 CLASS IMPLEMENTATION
00076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
00077 
00078 FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
00079 {
00080   string value;
00081   struct test *current_test;
00082   Element *test_element;
00083 
00084   FGFCSComponent::bind(); // Bind() this component here in case it is used
00085                           // in its own definition for a sample-and-hold
00086 
00087   int num = element->GetNumElements("test");
00088   if (element->FindElement("default")) num++;
00089   tests.reserve(num);
00090 
00091   test_element = element->FindElement("default");
00092   if (test_element) {
00093     current_test = new struct test;
00094     current_test->condition = 0;
00095     value = test_element->GetAttributeValue("value");
00096     current_test->setTestValue(value, Name, PropertyManager);
00097     current_test->Default = true;
00098     tests.push_back(current_test);
00099   }
00100 
00101   test_element = element->FindElement("test");
00102   while (test_element) {
00103     current_test = new struct test;
00104     current_test->condition = new FGCondition(test_element, PropertyManager);
00105     value = test_element->GetAttributeValue("value");
00106     current_test->setTestValue(value, Name, PropertyManager);
00107     tests.push_back(current_test);
00108     test_element = element->FindNextElement("test");
00109   }
00110 
00111   Debug(0);
00112 }
00113 
00114 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00115 
00116 FGSwitch::~FGSwitch()
00117 {
00118   for (unsigned int i=0; i<tests.size(); i++) {
00119     delete tests[i]->condition;
00120     delete tests[i]->OutputProp;
00121     delete tests[i];
00122   }
00123 
00124   Debug(1);
00125 }
00126 
00127 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00128 
00129 bool FGSwitch::Run(void )
00130 {
00131   bool pass = false;
00132   double default_output=0.0;
00133 
00134   for (unsigned int i=0; i<tests.size(); i++) {
00135     if (tests[i]->Default) {
00136       default_output = tests[i]->GetValue();
00137     } else {
00138       pass = tests[i]->condition->Evaluate();
00139     }
00140 
00141     if (pass) {
00142       Output = tests[i]->GetValue();
00143       break;
00144     }
00145   }
00146   
00147   if (!pass) Output = default_output;
00148 
00149   if (delay != 0) Delay();
00150   Clip();
00151   if (IsOutput) SetOutput();
00152 
00153   return true;
00154 }
00155 
00156 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00157 //    The bitmasked value choices are as follows:
00158 //    unset: In this case (the default) JSBSim would only print
00159 //       out the normally expected messages, essentially echoing
00160 //       the config files as they are read. If the environment
00161 //       variable is not set, debug_lvl is set to 1 internally
00162 //    0: This requests JSBSim not to output any messages
00163 //       whatsoever.
00164 //    1: This value explicity requests the normal JSBSim
00165 //       startup messages
00166 //    2: This value asks for a message to be printed out when
00167 //       a class is instantiated
00168 //    4: When this value is set, a message is displayed when a
00169 //       FGModel object executes its Run() method
00170 //    8: When this value is set, various runtime state variables
00171 //       are printed out periodically
00172 //    16: When set various parameters are sanity checked and
00173 //       a message is printed out when they go out of bounds
00174 
00175 void FGSwitch::Debug(int from)
00176 {
00177   string comp, scratch;
00178   string indent = "        ";
00179   //bool first = false;
00180 
00181   if (debug_lvl <= 0) return;
00182 
00183   if (debug_lvl & 1) { // Standard console startup message output
00184     if (from == 0) { // Constructor
00185       for (unsigned int i=0; i<tests.size(); i++) {
00186         if (tests[i]->Default) {
00187           if (tests[i]->OutputProp == 0) {
00188             cout << "      Switch default value is: " << tests[i]->OutputVal;
00189           } else {
00190             cout << "      Switch default value is: " << tests[i]->OutputProp->GetName();
00191           }
00192         } else {
00193           if (tests[i]->OutputProp == 0) {
00194             cout << "      Switch takes test " << i << " value (" << tests[i]->OutputVal << ")" << endl;
00195           } else {
00196             cout << "      Switch takes test " << i << " value (" << tests[i]->OutputProp->GetName() << ")" << endl;
00197           }
00198           tests[i]->condition->PrintCondition("      ");
00199         }
00200         cout << endl;
00201       }
00202       if (IsOutput) {
00203         for (unsigned int i=0; i<OutputNodes.size(); i++)
00204           cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
00205       }
00206     }
00207   }
00208   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
00209     if (from == 0) cout << "Instantiated: FGSwitch" << endl;
00210     if (from == 1) cout << "Destroyed:    FGSwitch" << endl;
00211   }
00212   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
00213   }
00214   if (debug_lvl & 8 ) { // Runtime state variables
00215   }
00216   if (debug_lvl & 16) { // Sanity checking
00217   }
00218   if (debug_lvl & 64) {
00219     if (from == 0) { // Constructor
00220       cout << IdSrc << endl;
00221       cout << IdHdr << endl;
00222     }
00223   }
00224 }
00225 
00226 } //namespace JSBSim
00227