]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/FGBuoyantForces.cpp
Merge branch 'maint' into next
[flightgear.git] / src / FDM / JSBSim / models / FGBuoyantForces.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGBuoyantForces.cpp
4  Authors:      Anders Gidenstam, Jon S. Berndt
5  Date started: 01/21/08
6  Purpose:      Encapsulates the buoyant forces
7
8  ------------- Copyright (C) 2008 - 2009  Anders Gidenstam        -------------
9  ------------- Copyright (C) 2008  Jon S. Berndt (jsb@hal-pc.org) -------------
10
11  This program is free software; you can redistribute it and/or modify it under
12  the terms of the GNU Lesser General Public License as published by the Free Software
13  Foundation; either version 2 of the License, or (at your option) any later
14  version.
15
16  This program is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
19  details.
20
21  You should have received a copy of the GNU Lesser General Public License along with
22  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23  Place - Suite 330, Boston, MA  02111-1307, USA.
24
25  Further information about the GNU Lesser General Public License can also be found on
26  the world wide web at http://www.gnu.org.
27
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30
31 HISTORY
32 --------------------------------------------------------------------------------
33 01/21/08   JSB   Created
34
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 INCLUDES
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
38
39 #include "FGBuoyantForces.h"
40 #include "FGMassBalance.h"
41 #include <input_output/FGPropertyManager.h>  // Need?
42
43 namespace JSBSim {
44
45 static const char *IdSrc = "$Id$";
46 static const char *IdHdr = ID_BUOYANTFORCES;
47
48 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49 CLASS IMPLEMENTATION
50 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
51
52 FGBuoyantForces::FGBuoyantForces(FGFDMExec* FDMExec) : FGModel(FDMExec)
53 {
54   Name = "FGBuoyantForces";
55
56   NoneDefined = true;
57
58   vTotalForces.InitMatrix();
59   vTotalMoments.InitMatrix();
60
61   gasCellJ.InitMatrix();
62
63   bind();
64
65   Debug(0);
66 }
67
68 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
69
70 FGBuoyantForces::~FGBuoyantForces()
71 {
72   for (unsigned int i=0; i<Cells.size(); i++) delete Cells[i];
73   Cells.clear();
74
75   for (unsigned int i=0; i<interface_properties.size(); i++)
76     delete interface_properties[i];
77   interface_properties.clear();
78
79   Debug(1);
80 }
81
82 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83
84 bool FGBuoyantForces::InitModel(void)
85 {
86   if (!FGModel::InitModel()) return false;
87
88   return true;
89 }
90
91 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92
93 bool FGBuoyantForces::Run(void)
94 {
95   if (FGModel::Run()) return true;
96   if (FDMExec->Holding()) return false; // if paused don't execute
97   if (NoneDefined) return true;
98
99   vTotalForces.InitMatrix();
100   vTotalMoments.InitMatrix();
101
102   for (unsigned int i=0; i<Cells.size(); i++) {
103     Cells[i]->Calculate(FDMExec->GetDeltaT());
104     vTotalForces  += Cells[i]->GetBodyForces();
105     vTotalMoments += Cells[i]->GetMoments();
106   }
107
108   return false;
109 }
110
111 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112
113 bool FGBuoyantForces::Load(Element *element)
114 {
115   string fname="", file="";
116   Element *gas_cell_element;
117
118   Debug(2);
119
120   string separator = "/";
121
122   fname = element->GetAttributeValue("file");
123   if (!fname.empty()) {
124     file = FDMExec->GetFullAircraftPath() + separator + fname;
125     document = LoadXMLDocument(file);
126   } else {
127     document = element;
128   }
129
130   Element *property_element = document->FindElement("property");
131   if (property_element)
132     cout << endl << "    Declared properties" << endl << endl;
133   while (property_element) {
134     string interface_property_string = property_element->GetDataLine();
135
136     if (PropertyManager->HasNode(interface_property_string)) {
137       cout << "      Property " << interface_property_string <<
138         " is already defined." << endl;
139     } else {
140       double value=0.0;
141       if ( ! property_element->GetAttributeValue("value").empty())
142         value = property_element->GetAttributeValueAsNumber("value");
143       interface_properties.push_back(new double(value));
144       interface_property_string = property_element->GetDataLine();
145       PropertyManager->Tie(interface_property_string,
146                            interface_properties.back());
147       cout << "      " << interface_property_string <<
148         " (initial value: " << value << ")" << endl;
149     }
150     property_element = document->FindNextElement("property");
151   }
152
153   gas_cell_element = document->FindElement("gas_cell");
154   while (gas_cell_element) {
155     NoneDefined = false;
156     Cells.push_back(new FGGasCell(FDMExec, gas_cell_element, Cells.size()));
157     gas_cell_element = document->FindNextElement("gas_cell");
158   }
159   
160   return true;
161 }
162
163 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164
165 double FGBuoyantForces::GetGasMass(void)
166 {
167   double Gw = 0.0;
168
169   for (unsigned int i = 0; i < Cells.size(); i++) {
170     Gw += Cells[i]->GetMass();
171   }
172
173   return Gw;
174 }
175
176 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177
178 const FGColumnVector3& FGBuoyantForces::GetGasMassMoment(void)
179 {
180   vXYZgasCell_arm.InitMatrix();
181   for (unsigned int i = 0; i < Cells.size(); i++) {
182     vXYZgasCell_arm += Cells[i]->GetMassMoment();
183   }
184   return vXYZgasCell_arm;
185 }
186
187 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
188
189 const FGMatrix33& FGBuoyantForces::GetGasMassInertia(void)
190 {
191   const unsigned int size = Cells.size();
192   
193   if (size == 0) return gasCellJ;
194
195   gasCellJ = FGMatrix33();
196
197   for (unsigned int i=0; i < size; i++) {
198     FGColumnVector3 v = MassBalance->StructuralToBody( Cells[i]->GetXYZ() );
199     // Body basis is in FT. 
200     const double mass = Cells[i]->GetMass();
201     
202     // FIXME: Verify that this is the correct way to change between the
203     //        coordinate frames.
204     gasCellJ += Cells[i]->GetInertia() + 
205       FGMatrix33( 0,                - mass*v(1)*v(2), - mass*v(1)*v(3),
206                   - mass*v(2)*v(1), 0,                - mass*v(2)*v(3),
207                   - mass*v(3)*v(1), - mass*v(3)*v(2), 0 );
208   }
209   
210   return gasCellJ;
211 }
212
213 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
214
215 string FGBuoyantForces::GetBuoyancyStrings(string delimeter)
216 {
217   string CoeffStrings = "";
218 /*
219   bool firstime = true;
220   for (sd = 0; sd < variables.size(); sd++) {
221     if (firstime) {
222       firstime = false;
223     } else {
224       CoeffStrings += delimeter;
225     }
226     CoeffStrings += variables[sd]->GetName();
227   }
228
229   for (axis = 0; axis < 6; axis++) {
230     for (sd = 0; sd < Coeff[axis].size(); sd++) {
231       if (firstime) {
232         firstime = false;
233       } else {
234         CoeffStrings += delimeter;
235       }
236       CoeffStrings += Coeff[axis][sd]->GetName();
237     }
238   }
239 */
240   return CoeffStrings;
241 }
242
243 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244
245 string FGBuoyantForces::GetBuoyancyValues(string delimeter)
246 {
247   string SDValues = "";
248 /*
249   bool firstime = true;
250   for (sd = 0; sd < variables.size(); sd++) {
251     if (firstime) {
252       firstime = false;
253     } else {
254       SDValues += delimeter;
255     }
256     SDValues += variables[sd]->GetValueAsString();
257   }
258
259   for (unsigned int axis = 0; axis < 6; axis++) {
260     for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) {
261       if (firstime) {
262         firstime = false;
263       } else {
264         SDValues += delimeter;
265       }
266       SDValues += Coeff[axis][sd]->GetValueAsString();
267     }
268   }
269 */
270   return SDValues;
271 }
272
273 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274
275 void FGBuoyantForces::bind(void)
276 {
277 }
278
279 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280 //    The bitmasked value choices are as follows:
281 //    unset: In this case (the default) JSBSim would only print
282 //       out the normally expected messages, essentially echoing
283 //       the config files as they are read. If the environment
284 //       variable is not set, debug_lvl is set to 1 internally
285 //    0: This requests JSBSim not to output any messages
286 //       whatsoever.
287 //    1: This value explicity requests the normal JSBSim
288 //       startup messages
289 //    2: This value asks for a message to be printed out when
290 //       a class is instantiated
291 //    4: When this value is set, a message is displayed when a
292 //       FGModel object executes its Run() method
293 //    8: When this value is set, various runtime state variables
294 //       are printed out periodically
295 //    16: When set various parameters are sanity checked and
296 //       a message is printed out when they go out of bounds
297
298 void FGBuoyantForces::Debug(int from)
299 {
300   if (debug_lvl <= 0) return;
301
302   if (debug_lvl & 1) { // Standard console startup message output
303     if (from == 2) { // Loader
304       cout << endl << "  Buoyant Forces: " << endl;
305     }
306   }
307   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
308     if (from == 0) cout << "Instantiated: FGBuoyantForces" << endl;
309     if (from == 1) cout << "Destroyed:    FGBuoyantForces" << endl;
310   }
311   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
312   }
313   if (debug_lvl & 8 ) { // Runtime state variables
314   }
315   if (debug_lvl & 16) { // Sanity checking
316   }
317   if (debug_lvl & 64) {
318     if (from == 0) { // Constructor
319       cout << IdSrc << endl;
320       cout << IdHdr << endl;
321     }
322   }
323 }
324
325 } // namespace JSBSim