]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/filtersjb/FGKinemat.cpp
Update to the latest version of JSBSim
[flightgear.git] / src / FDM / JSBSim / filtersjb / FGKinemat.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2  
3  Module:       FGKinemat.cpp
4  Author:       Tony Peden, for flight control system authored by Jon S. Berndt
5  Date started: 12/02/01
6  
7  ------------- Copyright (C) 2000 Anthony K. Peden -------------
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 "FGKinemat.h"
41
42 namespace JSBSim {
43
44 static const char *IdSrc = "$Id$";
45 static const char *IdHdr = ID_FLAPS;
46
47 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 CLASS IMPLEMENTATION
49 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
50
51 FGKinemat::FGKinemat(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
52                                                          AC_cfg(AC_cfg)
53 {
54   string token,sOutputIdx;
55   double tmpDetent;
56   double tmpTime;
57
58   Detents.clear();
59   TransitionTimes.clear();
60   
61   OutputPct=0;
62   InTransit=0;
63
64   Type = AC_cfg->GetValue("TYPE");
65   Name = AC_cfg->GetValue("NAME");
66   AC_cfg->GetNextConfigLine();
67
68   while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
69     *AC_cfg >> token;
70     if (token == "INPUT") {
71       token = AC_cfg->GetValue("INPUT");
72       if( InputNodes.size() > 0 ) {
73         cerr << "Kinemat can only accept one input" << endl;
74       } else  {
75         *AC_cfg >> token;
76         InputNodes.push_back( resolveSymbol(token) );
77       }  
78
79     } else if ( token == "DETENTS" ) {
80       *AC_cfg >> NumDetents;
81       for (int i=0;i<NumDetents;i++) {
82         *AC_cfg >> tmpDetent;
83         *AC_cfg >> tmpTime;
84         Detents.push_back(tmpDetent);
85         TransitionTimes.push_back(tmpTime);
86       }
87     } else if (token == "OUTPUT") {
88
89       IsOutput = true;
90       *AC_cfg >> sOutputIdx;
91       OutputNode = PropertyManager->GetNode(sOutputIdx);
92     }
93   }
94   FGFCSComponent::bind();
95   treenode->Tie("output-norm", this, &FGKinemat::GetOutputPct );
96
97   Debug(0);
98 }
99
100 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101
102 FGKinemat::~FGKinemat()
103 {
104   Debug(1);
105 }
106
107 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108
109 bool FGKinemat::Run(void ) {
110   double dt=fcs->GetState()->Getdt();
111   double output_transit_rate=0;
112
113   Input = InputNodes[0]->getDoubleValue();
114   InputCmd = Input*Detents[NumDetents-1];
115   OutputPos = OutputNode->getDoubleValue();
116   
117   if (InputCmd < Detents[0]) {
118     fi=0;
119     InputCmd=Detents[0];
120     lastInputCmd=InputCmd;
121     OutputPos=Detents[0];
122     Output=OutputPos;
123   } else if (InputCmd > Detents[NumDetents-1]) {
124     fi=NumDetents-1;
125     InputCmd=Detents[fi];
126     lastInputCmd=InputCmd;
127     OutputPos=Detents[fi];
128     Output=OutputPos;
129   } else {
130     //cout << "FGKinemat::Run Handle: " << InputCmd << " Position: " << OutputPos << endl;
131     if (dt <= 0)
132       OutputPos=InputCmd;
133     else {
134       if (InputCmd != lastInputCmd) {
135         InTransit=1;
136       }
137       //cout << "FGKinemat::Run, InTransit: " << InTransit << endl;
138       if (InTransit) {
139         //fprintf(stderr,"InputCmd: %g, OutputPos: %g\n",InputCmd,OutputPos);
140         fi=0;
141         while (Detents[fi] < InputCmd) {
142           fi++;
143         }
144         if (OutputPos < InputCmd) {
145           if (TransitionTimes[fi] > 0)
146             output_transit_rate=(Detents[fi] - Detents[fi-1])/TransitionTimes[fi];
147           else
148             output_transit_rate=(Detents[fi] - Detents[fi-1])/5;
149           //cout << "FGKinemat::Run, output_transit_rate: " << output_transit_rate << endl;  
150         } else {
151           if (TransitionTimes[fi+1] > 0)
152             output_transit_rate=(Detents[fi] - Detents[fi+1])/TransitionTimes[fi+1];
153           else
154             output_transit_rate=(Detents[fi] - Detents[fi+1])/5;
155         }
156         if (fabs(OutputPos - InputCmd) > fabs(dt*output_transit_rate) ) {
157           OutputPos+=output_transit_rate*dt;
158           //cout << "FGKinemat::Run, OutputPos: " << OutputPos 
159            //    << " dt: " << dt << endl;
160         } else {
161           InTransit=0;
162           OutputPos=InputCmd;
163         }
164       }
165     }
166     lastInputCmd = InputCmd;
167     Output = OutputPos;
168   }
169   
170   if ( Detents[NumDetents-1] > 0 ) {
171     OutputPct = Output / Detents[NumDetents-1];
172   }
173   
174   if (IsOutput) SetOutput();
175
176   return true;
177 }
178
179 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180 //    The bitmasked value choices are as follows:
181 //    unset: In this case (the default) JSBSim would only print
182 //       out the normally expected messages, essentially echoing
183 //       the config files as they are read. If the environment
184 //       variable is not set, debug_lvl is set to 1 internally
185 //    0: This requests JSBSim not to output any messages
186 //       whatsoever.
187 //    1: This value explicity requests the normal JSBSim
188 //       startup messages
189 //    2: This value asks for a message to be printed out when
190 //       a class is instantiated
191 //    4: When this value is set, a message is displayed when a
192 //       FGModel object executes its Run() method
193 //    8: When this value is set, various runtime state variables
194 //       are printed out periodically
195 //    16: When set various parameters are sanity checked and
196 //       a message is printed out when they go out of bounds
197
198 void FGKinemat::Debug(int from)
199 {
200   if (debug_lvl <= 0) return;
201
202   if (debug_lvl & 1) { // Standard console startup message output
203     if (from == 0) { // Constructor
204       cout << "      INPUT: " << InputNodes[0]->getName() << endl;
205       cout << "      DETENTS: " << NumDetents << endl;
206       for (int i=0;i<NumDetents;i++) {
207         cout << "        " << Detents[i] << " " << TransitionTimes[i] << endl;
208       }
209       if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
210     }
211   }
212   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
213     if (from == 0) cout << "Instantiated: FGKinemat" << endl;
214     if (from == 1) cout << "Destroyed:    FGKinemat" << endl;
215   }
216   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
217   }
218   if (debug_lvl & 8 ) { // Runtime state variables
219   }
220   if (debug_lvl & 16) { // Sanity checking
221   }
222   if (debug_lvl & 64) {
223     if (from == 0) { // Constructor
224       cout << IdSrc << endl;
225       cout << IdHdr << endl;
226     }
227   }
228 }
229 }