JSBSim Flight Dynamics Model  1.0 (02 March 2017)
An Open Source Flight Dynamics and Control Software Library in C++
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 - 2011 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 <iostream>
40 
41 #include "FGBuoyantForces.h"
42 #include "FGMassBalance.h"
43 #include "input_output/FGPropertyManager.h"
44 #include "input_output/FGXMLElement.h"
45 
46 using namespace std;
47 
48 namespace JSBSim {
49 
50 IDENT(IdSrc,"$Id: FGBuoyantForces.cpp,v 1.30 2015/03/28 14:49:02 bcoconni Exp $");
51 IDENT(IdHdr,ID_BUOYANTFORCES);
52 
53 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54 CLASS IMPLEMENTATION
55 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
56 
57 FGBuoyantForces::FGBuoyantForces(FGFDMExec* FDMExec) : FGModel(FDMExec)
58 {
59  Name = "FGBuoyantForces";
60 
61  NoneDefined = true;
62 
63  vTotalForces.InitMatrix();
64  vTotalMoments.InitMatrix();
65 
66  gasCellJ.InitMatrix();
67 
68  Debug(0);
69 }
70 
71 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72 
74 {
75  for (unsigned int i=0; i<Cells.size(); i++) delete Cells[i];
76  Cells.clear();
77 
78  Debug(1);
79 }
80 
81 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 
83 bool FGBuoyantForces::InitModel(void)
84 {
85  if (!FGModel::InitModel()) return false;
86 
87  vTotalForces.InitMatrix();
88  vTotalMoments.InitMatrix();
89 
90  return true;
91 }
92 
93 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94 
95 bool FGBuoyantForces::Run(bool Holding)
96 {
97  if (FGModel::Run(Holding)) return true;
98  if (Holding) return false; // if paused don't execute
99  if (NoneDefined) return true;
100 
101  RunPreFunctions();
102 
103  vTotalForces.InitMatrix();
104  vTotalMoments.InitMatrix();
105 
106  for (unsigned int i=0; i<Cells.size(); i++) {
107  Cells[i]->Calculate(FDMExec->GetDeltaT());
108  vTotalForces += Cells[i]->GetBodyForces();
109  vTotalMoments += Cells[i]->GetMoments();
110  }
111 
112  RunPostFunctions();
113 
114  return false;
115 }
116 
117 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118 
120 {
121  Element *gas_cell_element;
122 
123  Debug(2);
124 
125  // Perform base class Pre-Load
126  if (!FGModel::Load(document))
127  return false;
128 
129  gas_cell_element = document->FindElement("gas_cell");
130  while (gas_cell_element) {
131  NoneDefined = false;
132  Cells.push_back(new FGGasCell(FDMExec, gas_cell_element, Cells.size(), in));
133  gas_cell_element = document->FindNextElement("gas_cell");
134  }
135 
136  PostLoad(document, PropertyManager);
137 
138  if (!NoneDefined) {
139  bind();
140  }
141 
142  return true;
143 }
144 
145 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 
147 double FGBuoyantForces::GetGasMass(void) const
148 {
149  double Gw = 0.0;
150 
151  for (unsigned int i = 0; i < Cells.size(); i++) {
152  Gw += Cells[i]->GetMass();
153  }
154 
155  return Gw;
156 }
157 
158 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
159 
161 {
162  vXYZgasCell_arm.InitMatrix();
163  for (unsigned int i = 0; i < Cells.size(); i++) {
164  vXYZgasCell_arm += Cells[i]->GetMassMoment();
165  }
166  return vXYZgasCell_arm;
167 }
168 
169 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170 
172 {
173  size_t size = Cells.size();
174 
175  if (size == 0) return gasCellJ;
176 
177  gasCellJ = FGMatrix33();
178 
179  for (unsigned int i=0; i < size; i++) {
180  gasCellJ += Cells[i]->GetInertia();
181  }
182 
183  return gasCellJ;
184 }
185 
186 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
187 
188 string FGBuoyantForces::GetBuoyancyStrings(const string& delimeter)
189 {
190  string CoeffStrings = "";
191 /*
192  bool firstime = true;
193  for (sd = 0; sd < variables.size(); sd++) {
194  if (firstime) {
195  firstime = false;
196  } else {
197  CoeffStrings += delimeter;
198  }
199  CoeffStrings += variables[sd]->GetName();
200  }
201 
202  for (axis = 0; axis < 6; axis++) {
203  for (sd = 0; sd < AeroFunctions[axis].size(); sd++) {
204  if (firstime) {
205  firstime = false;
206  } else {
207  CoeffStrings += delimeter;
208  }
209  CoeffStrings += AeroFunctions[axis][sd]->GetName();
210  }
211  }
212 */
213  return CoeffStrings;
214 }
215 
216 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
217 
218 string FGBuoyantForces::GetBuoyancyValues(const string& delimeter)
219 {
220  string SDValues = "";
221 /*
222  bool firstime = true;
223  for (sd = 0; sd < variables.size(); sd++) {
224  if (firstime) {
225  firstime = false;
226  } else {
227  SDValues += delimeter;
228  }
229  SDValues += variables[sd]->GetValueAsString();
230  }
231 
232  for (unsigned int axis = 0; axis < 6; axis++) {
233  for (unsigned int sd = 0; sd < AeroFunctions[axis].size(); sd++) {
234  if (firstime) {
235  firstime = false;
236  } else {
237  SDValues += delimeter;
238  }
239  SDValues += AeroFunctions[axis][sd]->GetValueAsString();
240  }
241  }
242 */
243  return SDValues;
244 }
245 
246 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
247 
248 void FGBuoyantForces::bind(void)
249 {
250  typedef double (FGBuoyantForces::*PGF)(int) const;
251  typedef void (FGBuoyantForces::*PSF)(int, double);
252  PropertyManager->Tie("moments/l-buoyancy-lbsft", this, eL,
253  (PGF)&FGBuoyantForces::GetMoments, (PSF)0, false);
254  PropertyManager->Tie("moments/m-buoyancy-lbsft", this, eM,
255  (PGF)&FGBuoyantForces::GetMoments, (PSF)0, false);
256  PropertyManager->Tie("moments/n-buoyancy-lbsft", this, eN,
257  (PGF)&FGBuoyantForces::GetMoments, (PSF)0, false);
258  PropertyManager->Tie("forces/fbx-buoyancy-lbs", this, eX,
259  (PGF)&FGBuoyantForces::GetForces, (PSF)0, false);
260  PropertyManager->Tie("forces/fby-buoyancy-lbs", this, eY,
261  (PGF)&FGBuoyantForces::GetForces, (PSF)0, false);
262  PropertyManager->Tie("forces/fbz-buoyancy-lbs", this, eZ,
263  (PGF)&FGBuoyantForces::GetForces, (PSF)0, false);
264 }
265 
266 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
267 // The bitmasked value choices are as follows:
268 // unset: In this case (the default) JSBSim would only print
269 // out the normally expected messages, essentially echoing
270 // the config files as they are read. If the environment
271 // variable is not set, debug_lvl is set to 1 internally
272 // 0: This requests JSBSim not to output any messages
273 // whatsoever.
274 // 1: This value explicity requests the normal JSBSim
275 // startup messages
276 // 2: This value asks for a message to be printed out when
277 // a class is instantiated
278 // 4: When this value is set, a message is displayed when a
279 // FGModel object executes its Run() method
280 // 8: When this value is set, various runtime state variables
281 // are printed out periodically
282 // 16: When set various parameters are sanity checked and
283 // a message is printed out when they go out of bounds
284 
285 void FGBuoyantForces::Debug(int from)
286 {
287  if (debug_lvl <= 0) return;
288 
289  if (debug_lvl & 1) { // Standard console startup message output
290  if (from == 2) { // Loader
291  cout << endl << " Buoyant Forces: " << endl;
292  }
293  }
294  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
295  if (from == 0) cout << "Instantiated: FGBuoyantForces" << endl;
296  if (from == 1) cout << "Destroyed: FGBuoyantForces" << endl;
297  }
298  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
299  }
300  if (debug_lvl & 8 ) { // Runtime state variables
301  }
302  if (debug_lvl & 16) { // Sanity checking
303  }
304  if (debug_lvl & 64) {
305  if (from == 0) { // Constructor
306  cout << IdSrc << endl;
307  cout << IdHdr << endl;
308  }
309  }
310 }
311 
312 } // namespace JSBSim
const FGColumnVector3 & GetGasMassMoment(void)
Gets the total moment from the gas mass.
Encapsulates the Buoyant forces calculations.
~FGBuoyantForces()
Destructor.
Models a gas cell.
Definition: FGGasCell.h:172
STL namespace.
Element * FindElement(const std::string &el="")
Searches for a specified element.
std::string GetBuoyancyValues(const std::string &delimeter)
Gets the coefficient values.
virtual bool Run(bool Holding)
Runs the model; called by the Executive.
Definition: FGModel.cpp:92
void Tie(const std::string &name, bool *pointer, bool useDefault=true)
Tie a property to an external bool variable.
const FGMatrix33 & GetGasMassInertia(void)
Gets the total moments of inertia for the gas mass in the body frame.
bool Run(bool Holding)
Runs the Buoyant forces model; called by the Executive Can pass in a value indicating if the executiv...
const FGColumnVector3 & GetMoments(void) const
Gets the total Buoyancy moment vector.
double GetGasMass(void) const
Gets the total gas mass.
Base class for all scheduled JSBSim models.
Definition: FGModel.h:74
std::string GetBuoyancyStrings(const std::string &delimeter)
Gets the strings for the current set of gas cells.
const FGColumnVector3 & GetForces(void) const
Gets the total Buoyant force vector.
This class implements a 3 element column vector.
bool Load(Element *element)
Loads the Buoyant forces model.
Element * FindNextElement(const std::string &el="")
Searches for the next element as specified.
Handles matrix math operations.
Definition: FGMatrix33.h:92
void InitMatrix(void)
Initialize the matrix.
Definition: FGMatrix33.cpp:257
double GetDeltaT(void) const
Returns the simulation delta T.
Definition: FGFDMExec.h:536
Encapsulates the JSBSim simulation executive.
Definition: FGFDMExec.h:189
virtual bool Load(Element *el)
Loads this model.
Definition: FGModel.cpp:113