]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp
Sync. w. JSBSim CVS.
[flightgear.git] / src / FDM / JSBSim / models / flight_control / FGFCSComponent.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGFCSComponent.cpp
4  Author:       Jon S. Berndt
5  Date started: 11/1999
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 "FGFCSComponent.h"
41
42 namespace JSBSim {
43
44 static const char *IdSrc = "$Id$";
45 static const char *IdHdr = ID_FCSCOMPONENT;
46
47 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 CLASS IMPLEMENTATION
49 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
50
51 FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
52 {
53   Element *input_element, *clip_el;
54   Input = Output = clipmin = clipmax = 0.0;
55   OutputNode = treenode = 0;
56   ClipMinPropertyNode = ClipMaxPropertyNode = 0;
57   clipMinSign = clipMaxSign = 1.0;
58   IsOutput   = clip = false;
59   string input, clip_string;
60
61   PropertyManager = fcs->GetPropertyManager();
62   Type = element->GetAttributeValue("type"); // Old, deprecated format
63   if (Type.empty()) {
64     if        (element->GetName() == string("lag_filter")) {
65       Type = "LAG_FILTER";
66     } else if (element->GetName() == string("lead_lag_filter")) {
67       Type = "LEAD_LAG_FILTER";
68     } else if (element->GetName() == string("washout_filter")) {
69       Type = "WASHOUT_FILTER";
70     } else if (element->GetName() == string("second_order_filter")) {
71       Type = "SECOND_ORDER_FILTER";
72     } else if (element->GetName() == string("integrator")) {
73       Type = "INTEGRATOR";
74     } else if (element->GetName() == string("summer")) {
75       Type = "SUMMER";
76     } else if (element->GetName() == string("pure_gain")) {
77       Type = "PURE_GAIN";
78     } else if (element->GetName() == string("scheduled_gain")) {
79       Type = "SCHEDULED_GAIN";
80     } else if (element->GetName() == string("aerosurface_scale")) {
81       Type = "AEROSURFACE_SCALE";
82     } else if (element->GetName() == string("switch")) {
83       Type = "SWITCH";
84     } else if (element->GetName() == string("kinematic")) {
85       Type = "KINEMATIC";
86     } else if (element->GetName() == string("deadband")) {
87       Type = "DEADBAND";
88     } else if (element->GetName() == string("fcs_function")) {
89       Type = "FCS_FUNCTION";
90     } else if (element->GetName() == string("sensor")) {
91       Type = "SENSOR";
92     } else { // illegal component in this channel
93       Type = "UNKNOWN";
94     }
95   }
96
97   Name = element->GetAttributeValue("name");
98
99   input_element = element->FindElement("input");
100   while (input_element) {
101     input = input_element->GetDataLine();
102     if (input[0] == '-') {
103       InputSigns.push_back(-1.0);
104       input.erase(0,1);
105     } else {
106       InputSigns.push_back( 1.0);
107     }
108     InputNodes.push_back( resolveSymbol(input) );
109     input_element = element->FindNextElement("input");
110   }
111
112   if (element->FindElement("output")) {
113     IsOutput = true;
114     OutputNode = PropertyManager->GetNode( element->FindElementValue("output") );
115     if (!OutputNode) {
116       cerr << endl << "  Unable to process property: " << element->FindElementValue("output") << endl;
117       throw(string("Invalid output property name in flight control definition"));
118     }
119   }
120
121   clip_el = element->FindElement("clipto");
122   if (clip_el) {
123     clip_string = clip_el->FindElementValue("min");
124     if (clip_string.find_first_not_of("+-.0123456789") != string::npos) { // it's a property
125       if (clip_string[0] == '-') clipMinSign = -1.0;
126       ClipMinPropertyNode = PropertyManager->GetNode( clip_string );
127     } else {
128       clipmin = clip_el->FindElementValueAsNumber("min");
129     }
130     clip_string = clip_el->FindElementValue("max");
131     if (clip_string.find_first_not_of("+-.0123456789") != string::npos) { // it's a property
132       if (clip_string[0] == '-') clipMaxSign = -1.0;
133       ClipMaxPropertyNode = PropertyManager->GetNode( clip_string );
134     } else {
135       clipmax = clip_el->FindElementValueAsNumber("max");
136     }
137     clip = true;
138   }
139
140   Debug(0);
141 }
142
143 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
144
145 FGFCSComponent::~FGFCSComponent()
146 {
147 //  string tmp = "fcs/" + PropertyManager->mkPropertyName(Name, true);
148 //  PropertyManager->Untie( tmp);
149
150   Debug(1);
151 }
152
153 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154
155 void FGFCSComponent::SetOutput(void)
156 {
157   OutputNode->setDoubleValue(Output);
158 }
159
160 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161
162 bool FGFCSComponent::Run(void)
163 {
164   return true;
165 }
166
167 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
168
169 void FGFCSComponent::Clip(void)
170 {
171   if (clip) {
172     if (ClipMinPropertyNode != 0) clipmin = clipMinSign*ClipMinPropertyNode->getDoubleValue();
173     if (ClipMaxPropertyNode != 0) clipmax = clipMaxSign*ClipMaxPropertyNode->getDoubleValue();
174     if (Output > clipmax)      Output = clipmax;
175     else if (Output < clipmin) Output = clipmin;
176   }
177 }
178
179 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180
181 FGPropertyManager* FGFCSComponent::resolveSymbol(string token)
182 {
183   string prop;
184   FGPropertyManager* tmp = PropertyManager->GetNode(token,false);
185   if (!tmp) {
186     if (token.find("/") == token.npos) prop = "model/" + token;
187     cerr << "Creating new property " << prop << endl;
188     tmp = PropertyManager->GetNode(token,true);
189   }
190   return tmp;
191 }
192
193
194 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195
196 void FGFCSComponent::bind(void)
197 {
198   string tmp = "fcs/" + PropertyManager->mkPropertyName(Name, true);
199   PropertyManager->Tie( tmp, this, &FGFCSComponent::GetOutput);
200 }
201
202 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 //    The bitmasked value choices are as follows:
204 //    unset: In this case (the default) JSBSim would only print
205 //       out the normally expected messages, essentially echoing
206 //       the config files as they are read. If the environment
207 //       variable is not set, debug_lvl is set to 1 internally
208 //    0: This requests JSBSim not to output any messages
209 //       whatsoever.
210 //    1: This value explicity requests the normal JSBSim
211 //       startup messages
212 //    2: This value asks for a message to be printed out when
213 //       a class is instantiated
214 //    4: When this value is set, a message is displayed when a
215 //       FGModel object executes its Run() method
216 //    8: When this value is set, various runtime state variables
217 //       are printed out periodically
218 //    16: When set various parameters are sanity checked and
219 //       a message is printed out when they go out of bounds
220
221 void FGFCSComponent::Debug(int from)
222 {
223   if (debug_lvl <= 0) return;
224
225   if (debug_lvl & 1) { // Standard console startup message output
226     if (from == 0) {
227       cout << endl << "    Loading Component \"" << Name
228                    << "\" of type: " << Type << endl;
229     }
230   }
231   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
232     if (from == 0) cout << "Instantiated: FGFCSComponent" << endl;
233     if (from == 1) cout << "Destroyed:    FGFCSComponent" << endl;
234   }
235   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
236   }
237   if (debug_lvl & 8 ) { // Runtime state variables
238   }
239   if (debug_lvl & 16) { // Sanity checking
240   }
241   if (debug_lvl & 64) {
242     if (from == 0) { // Constructor
243       cout << IdSrc << endl;
244       cout << IdHdr << endl;
245     }
246   }
247 }
248 }