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