]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/FGBuoyantForces.cpp
Andreas Gaeb: fix #222 (JSBSIm reset problems)
[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 - 2010  Anders Gidenstam        -------------
9  ------------- Copyright (C) 2008  Jon S. Berndt (jon@jsbsim.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"
42 #include <iostream>
43
44 using namespace std;
45
46 namespace JSBSim {
47
48 static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.14 2010/11/18 12:38:06 jberndt Exp $";
49 static const char *IdHdr = ID_BUOYANTFORCES;
50
51 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 CLASS IMPLEMENTATION
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
54
55 FGBuoyantForces::FGBuoyantForces(FGFDMExec* FDMExec) : FGModel(FDMExec)
56 {
57   Name = "FGBuoyantForces";
58
59   NoneDefined = true;
60
61   vTotalForces.InitMatrix();
62   vTotalMoments.InitMatrix();
63
64   gasCellJ.InitMatrix();
65
66   Debug(0);
67 }
68
69 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70
71 FGBuoyantForces::~FGBuoyantForces()
72 {
73   for (unsigned int i=0; i<Cells.size(); i++) delete Cells[i];
74   Cells.clear();
75
76   Debug(1);
77 }
78
79 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80
81 bool FGBuoyantForces::InitModel(void)
82 {
83   if (!FGModel::InitModel()) return false;
84
85   return true;
86 }
87
88 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89
90 bool FGBuoyantForces::Run(void)
91 {
92   if (FGModel::Run()) return true;
93   if (FDMExec->Holding()) return false; // if paused don't execute
94   if (NoneDefined) return true;
95
96   RunPreFunctions();
97
98   vTotalForces.InitMatrix();
99   vTotalMoments.InitMatrix();
100
101   for (unsigned int i=0; i<Cells.size(); i++) {
102     Cells[i]->Calculate(FDMExec->GetDeltaT());
103     vTotalForces  += Cells[i]->GetBodyForces();
104     vTotalMoments += Cells[i]->GetMoments();
105   }
106
107   RunPostFunctions();
108
109   return false;
110 }
111
112 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113
114 bool FGBuoyantForces::Load(Element *element)
115 {
116   string fname="", file="";
117   Element *gas_cell_element;
118
119   Debug(2);
120
121   string separator = "/";
122
123   fname = element->GetAttributeValue("file");
124   if (!fname.empty()) {
125     file = FDMExec->GetFullAircraftPath() + separator + fname;
126     document = LoadXMLDocument(file);
127   } else {
128     document = element;
129   }
130
131   FGModel::Load(element); // Perform base class Load
132
133   gas_cell_element = document->FindElement("gas_cell");
134   while (gas_cell_element) {
135     NoneDefined = false;
136     Cells.push_back(new FGGasCell(FDMExec, gas_cell_element, Cells.size()));
137     gas_cell_element = document->FindNextElement("gas_cell");
138   }
139   
140   PostLoad(element, PropertyManager);
141
142   if (!NoneDefined) {
143     bind();
144   }
145
146   return true;
147 }
148
149 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150
151 double FGBuoyantForces::GetGasMass(void)
152 {
153   double Gw = 0.0;
154
155   for (unsigned int i = 0; i < Cells.size(); i++) {
156     Gw += Cells[i]->GetMass();
157   }
158
159   return Gw;
160 }
161
162 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163
164 const FGColumnVector3& FGBuoyantForces::GetGasMassMoment(void)
165 {
166   vXYZgasCell_arm.InitMatrix();
167   for (unsigned int i = 0; i < Cells.size(); i++) {
168     vXYZgasCell_arm += Cells[i]->GetMassMoment();
169   }
170   return vXYZgasCell_arm;
171 }
172
173 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
174
175 const FGMatrix33& FGBuoyantForces::GetGasMassInertia(void)
176 {
177   const unsigned int size = Cells.size();
178   
179   if (size == 0) return gasCellJ;
180
181   gasCellJ = FGMatrix33();
182
183   for (unsigned int i=0; i < size; i++) {
184     FGColumnVector3 v = FDMExec->GetMassBalance()->StructuralToBody( Cells[i]->GetXYZ() );
185     // Body basis is in FT. 
186     const double mass = Cells[i]->GetMass();
187     
188     // FIXME: Verify that this is the correct way to change between the
189     //        coordinate frames.
190     gasCellJ += Cells[i]->GetInertia() + 
191       FGMatrix33( 0,                - mass*v(1)*v(2), - mass*v(1)*v(3),
192                   - mass*v(2)*v(1), 0,                - mass*v(2)*v(3),
193                   - mass*v(3)*v(1), - mass*v(3)*v(2), 0 );
194   }
195   
196   return gasCellJ;
197 }
198
199 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200
201 string FGBuoyantForces::GetBuoyancyStrings(string delimeter)
202 {
203   string CoeffStrings = "";
204 /*
205   bool firstime = true;
206   for (sd = 0; sd < variables.size(); sd++) {
207     if (firstime) {
208       firstime = false;
209     } else {
210       CoeffStrings += delimeter;
211     }
212     CoeffStrings += variables[sd]->GetName();
213   }
214
215   for (axis = 0; axis < 6; axis++) {
216     for (sd = 0; sd < Coeff[axis].size(); sd++) {
217       if (firstime) {
218         firstime = false;
219       } else {
220         CoeffStrings += delimeter;
221       }
222       CoeffStrings += Coeff[axis][sd]->GetName();
223     }
224   }
225 */
226   return CoeffStrings;
227 }
228
229 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230
231 string FGBuoyantForces::GetBuoyancyValues(string delimeter)
232 {
233   string SDValues = "";
234 /*
235   bool firstime = true;
236   for (sd = 0; sd < variables.size(); sd++) {
237     if (firstime) {
238       firstime = false;
239     } else {
240       SDValues += delimeter;
241     }
242     SDValues += variables[sd]->GetValueAsString();
243   }
244
245   for (unsigned int axis = 0; axis < 6; axis++) {
246     for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) {
247       if (firstime) {
248         firstime = false;
249       } else {
250         SDValues += delimeter;
251       }
252       SDValues += Coeff[axis][sd]->GetValueAsString();
253     }
254   }
255 */
256   return SDValues;
257 }
258
259 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260
261 void FGBuoyantForces::bind(void)
262 {
263   typedef double (FGBuoyantForces::*PMF)(int) const;
264   PropertyManager->Tie("moments/l-buoyancy-lbsft", this, eL,
265                        (PMF)&FGBuoyantForces::GetMoments);
266   PropertyManager->Tie("moments/m-buoyancy-lbsft", this, eM,
267                        (PMF)&FGBuoyantForces::GetMoments);
268   PropertyManager->Tie("moments/n-buoyancy-lbsft", this, eN,
269                        (PMF)&FGBuoyantForces::GetMoments);
270   PropertyManager->Tie("forces/fbx-buoyancy-lbs", this, eX,
271                        (PMF)&FGBuoyantForces::GetForces);
272   PropertyManager->Tie("forces/fby-buoyancy-lbs", this, eY,
273                        (PMF)&FGBuoyantForces::GetForces);
274   PropertyManager->Tie("forces/fbz-buoyancy-lbs", this, eZ,
275                        (PMF)&FGBuoyantForces::GetForces);
276 }
277
278 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279 //    The bitmasked value choices are as follows:
280 //    unset: In this case (the default) JSBSim would only print
281 //       out the normally expected messages, essentially echoing
282 //       the config files as they are read. If the environment
283 //       variable is not set, debug_lvl is set to 1 internally
284 //    0: This requests JSBSim not to output any messages
285 //       whatsoever.
286 //    1: This value explicity requests the normal JSBSim
287 //       startup messages
288 //    2: This value asks for a message to be printed out when
289 //       a class is instantiated
290 //    4: When this value is set, a message is displayed when a
291 //       FGModel object executes its Run() method
292 //    8: When this value is set, various runtime state variables
293 //       are printed out periodically
294 //    16: When set various parameters are sanity checked and
295 //       a message is printed out when they go out of bounds
296
297 void FGBuoyantForces::Debug(int from)
298 {
299   if (debug_lvl <= 0) return;
300
301   if (debug_lvl & 1) { // Standard console startup message output
302     if (from == 2) { // Loader
303       cout << endl << "  Buoyant Forces: " << endl;
304     }
305   }
306   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
307     if (from == 0) cout << "Instantiated: FGBuoyantForces" << endl;
308     if (from == 1) cout << "Destroyed:    FGBuoyantForces" << endl;
309   }
310   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
311   }
312   if (debug_lvl & 8 ) { // Runtime state variables
313   }
314   if (debug_lvl & 16) { // Sanity checking
315   }
316   if (debug_lvl & 64) {
317     if (from == 0) { // Constructor
318       cout << IdSrc << endl;
319       cout << IdHdr << endl;
320     }
321   }
322 }
323
324 } // namespace JSBSim