]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/filtersjb/FGFilter.cpp
Make yasim accept the launchbar and hook properties. They are not tied to anything...
[flightgear.git] / src / FDM / JSBSim / filtersjb / FGFilter.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGFilter.cpp
4  Author:       Jon S. Berndt
5  Date started: 11/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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37 INCLUDES
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
39
40 #include "FGFilter.h"
41
42 namespace JSBSim {
43
44 static const char *IdSrc = "$Id$";
45 static const char *IdHdr = ID_FILTER;
46
47 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 CLASS IMPLEMENTATION
49 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
50
51 FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
52                                                        AC_cfg(AC_cfg)
53 {
54   string token;
55   double denom;
56   string sOutputIdx;
57
58   Type = AC_cfg->GetValue("TYPE");
59   Name = AC_cfg->GetValue("NAME");
60   AC_cfg->GetNextConfigLine();
61   dt = fcs->GetState()->Getdt();
62   Trigger = 0;
63
64   C1 = C2 = C3 = C4 = C5 = C6 = 0.0;
65
66   if      (Type == "LAG_FILTER")          FilterType = eLag        ;
67   else if (Type == "LEAD_LAG_FILTER")     FilterType = eLeadLag    ;
68   else if (Type == "SECOND_ORDER_FILTER") FilterType = eOrder2     ;
69   else if (Type == "WASHOUT_FILTER")      FilterType = eWashout    ;
70   else if (Type == "INTEGRATOR")          FilterType = eIntegrator ;
71   else                                    FilterType = eUnknown    ;
72
73   while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
74     *AC_cfg >> token;
75     if (token == "C1")           *AC_cfg >> C1;
76     else if (token == "C2")      *AC_cfg >> C2;
77     else if (token == "C3")      *AC_cfg >> C3;
78     else if (token == "C4")      *AC_cfg >> C4;
79     else if (token == "C5")      *AC_cfg >> C5;
80     else if (token == "C6")      *AC_cfg >> C6;
81     else if (token == "TRIGGER")
82     {
83       token = AC_cfg->GetValue("TRIGGER");
84       *AC_cfg >> token;
85       Trigger =  resolveSymbol(token);
86     }
87     else if (token == "INPUT")
88     {
89       token = AC_cfg->GetValue("INPUT");
90       if( InputNodes.size() > 0 ) {
91         cerr << "Filters can only accept one input" << endl;
92       } else  {
93         *AC_cfg >> token;
94         InputNodes.push_back( resolveSymbol(token) );
95       }
96     }
97     else if (token == "OUTPUT")
98     {
99       IsOutput = true;
100       *AC_cfg >> sOutputIdx;
101       OutputNode = PropertyManager->GetNode( sOutputIdx );
102     }
103     else cerr << "Unknown filter type: " << token << endl;
104   }
105
106   Initialize = true;
107
108   switch (FilterType) {
109     case eLag:
110       denom = 2.00 + dt*C1;
111       ca = dt*C1 / denom;
112       cb = (2.00 - dt*C1) / denom;
113       break;
114     case eLeadLag:
115       denom = 2.00*C3 + dt*C4;
116       ca = (2.00*C1 + dt*C2) / denom;
117       cb = (dt*C2 - 2.00*C1) / denom;
118       cc = (2.00*C3 - dt*C4) / denom;
119       break;
120     case eOrder2:
121       denom = 4.0*C4 + 2.0*C5*dt + C6*dt*dt;
122       ca = (4.0*C1 + 2.0*C2*dt + C3*dt*dt) / denom;
123       cb = (2.0*C3*dt*dt - 8.0*C1) / denom;
124       cc = (4.0*C1 - 2.0*C2*dt + C3*dt*dt) / denom;
125       cd = (2.0*C6*dt*dt - 8.0*C4) / denom;
126       ce = (4.0*C4 - 2.0*C5*dt + C6*dt*dt) / denom;
127       break;
128     case eWashout:
129       denom = 2.00 + dt*C1;
130       ca = 2.00 / denom;
131       cb = (2.00 - dt*C1) / denom;
132       break;
133     case eIntegrator:
134       ca = dt*C1 / 2.00;
135       break;
136     case eUnknown:
137       cerr << "Unknown filter type" << endl;
138     break;
139   }
140   FGFCSComponent::bind();
141
142   Debug(0);
143 }
144
145 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146
147 FGFilter::~FGFilter()
148 {
149   Debug(1);
150 }
151
152 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
153
154 bool FGFilter::Run(void)
155 {
156   int test = 0;
157
158   FGFCSComponent::Run(); // call the base class for initialization of Input
159
160   if (Initialize) {
161
162     PreviousOutput1 = PreviousInput1 = Output = Input;
163     Initialize = false;
164
165   } else if (Trigger != 0) {
166     test = Trigger->getIntValue();
167     if (test < 0) {
168       Input  = PreviousInput1 = PreviousInput2 = 0.0;
169     } else {
170       Output = PreviousOutput1 = PreviousOutput2 = 0.0;
171     }
172
173   } else {
174     Input = InputNodes[0]->getDoubleValue();
175     switch (FilterType) {
176       case eLag:
177         Output = Input * ca + PreviousInput1 * ca + PreviousOutput1 * cb;
178         break;
179       case eLeadLag:
180         Output = Input * ca + PreviousInput1 * cb + PreviousOutput1 * cc;
181         break;
182       case eOrder2:
183         Output = Input * ca + PreviousInput1 * cb + PreviousInput2 * cc
184                             - PreviousOutput1 * cd - PreviousOutput2 * ce;
185         break;
186       case eWashout:
187         Output = Input * ca - PreviousInput1 * ca + PreviousOutput1 * cb;
188         break;
189       case eIntegrator:
190         Output = Input * ca + PreviousInput1 * ca + PreviousOutput1;
191         break;
192       case eUnknown:
193         break;
194     }
195
196   }
197
198   PreviousOutput2 = PreviousOutput1;
199   PreviousOutput1 = Output;
200   PreviousInput2  = PreviousInput1;
201   PreviousInput1  = Input;
202
203   if (IsOutput) SetOutput();
204
205   return true;
206 }
207
208 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209 //    The bitmasked value choices are as follows:
210 //    unset: In this case (the default) JSBSim would only print
211 //       out the normally expected messages, essentially echoing
212 //       the config files as they are read. If the environment
213 //       variable is not set, debug_lvl is set to 1 internally
214 //    0: This requests JSBSim not to output any messages
215 //       whatsoever.
216 //    1: This value explicity requests the normal JSBSim
217 //       startup messages
218 //    2: This value asks for a message to be printed out when
219 //       a class is instantiated
220 //    4: When this value is set, a message is displayed when a
221 //       FGModel object executes its Run() method
222 //    8: When this value is set, various runtime state variables
223 //       are printed out periodically
224 //    16: When set various parameters are sanity checked and
225 //       a message is printed out when they go out of bounds
226
227 void FGFilter::Debug(int from)
228 {
229   if (debug_lvl <= 0) return;
230
231   if (debug_lvl & 1) { // Standard console startup message output
232     if (from == 0) { // Constructor
233       cout << "      INPUT: " << InputNodes[0]->getName() << endl;
234       cout << "      C1: " << C1 << endl;
235       cout << "      C2: " << C2 << endl;
236       cout << "      C3: " << C3 << endl;
237       cout << "      C4: " << C4 << endl;
238       cout << "      C5: " << C5 << endl;
239       cout << "      C6: " << C6 << endl;
240       if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
241     }
242   }
243   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
244     if (from == 0) cout << "Instantiated: FGFilter" << endl;
245     if (from == 1) cout << "Destroyed:    FGFilter" << endl;
246   }
247   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
248   }
249   if (debug_lvl & 8 ) { // Runtime state variables
250   }
251   if (debug_lvl & 16) { // Sanity checking
252   }
253   if (debug_lvl & 64) {
254     if (from == 0) { // Constructor
255       cout << IdSrc << endl;
256       cout << IdHdr << endl;
257     }
258   }
259 }
260 }