LCOV - code coverage report
Current view: top level - models - FGMassBalance.cpp (source / functions) Hit Total Coverage
Test: JSBSim-Coverage-Statistics Lines: 195 229 85.2 %
Date: 2010-08-24 Functions: 17 19 89.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 59 120 49.2 %

           Branch data     Line data    Source code
       1                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       2                 :            : 
       3                 :            :  Module:       FGMassBalance.cpp
       4                 :            :  Author:       Jon S. Berndt
       5                 :            :  Date started: 09/12/2000
       6                 :            :  Purpose:      This module models weight and balance
       7                 :            : 
       8                 :            :  ------------- Copyright (C) 2000  Jon S. Berndt (jon@jsbsim.org) --------------
       9                 :            : 
      10                 :            :  This program is free software; you can redistribute it and/or modify it under
      11                 :            :  the terms of the GNU Lesser General Public License as published by the Free Software
      12                 :            :  Foundation; either version 2 of the License, or (at your option) any later
      13                 :            :  version.
      14                 :            : 
      15                 :            :  This program is distributed in the hope that it will be useful, but WITHOUT
      16                 :            :  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      17                 :            :  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      18                 :            :  details.
      19                 :            : 
      20                 :            :  You should have received a copy of the GNU Lesser General Public License along with
      21                 :            :  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
      22                 :            :  Place - Suite 330, Boston, MA  02111-1307, USA.
      23                 :            : 
      24                 :            :  Further information about the GNU Lesser General Public License can also be found on
      25                 :            :  the world wide web at http://www.gnu.org.
      26                 :            : 
      27                 :            : FUNCTIONAL DESCRIPTION
      28                 :            : --------------------------------------------------------------------------------
      29                 :            : 
      30                 :            : This class models the change in weight and balance of the aircraft due to fuel
      31                 :            : burnoff, etc.
      32                 :            : 
      33                 :            : HISTORY
      34                 :            : --------------------------------------------------------------------------------
      35                 :            : 09/12/2000  JSB  Created
      36                 :            : 
      37                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      38                 :            : INCLUDES
      39                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      40                 :            : 
      41                 :            : #include "FGMassBalance.h"
      42                 :            : #include "FGPropulsion.h"
      43                 :            : #include "propulsion/FGTank.h"
      44                 :            : #include "FGBuoyantForces.h"
      45                 :            : #include "input_output/FGPropertyManager.h"
      46                 :            : #include <iostream>
      47                 :            : #include <iomanip>
      48                 :            : #include <cstdlib>
      49                 :            : 
      50                 :            : using namespace std;
      51                 :            : 
      52                 :            : namespace JSBSim {
      53                 :            : 
      54                 :            : static const char *IdSrc = "$Id: FGMassBalance.cpp,v 1.32 2010/08/12 04:07:11 jberndt Exp $";
      55                 :            : static const char *IdHdr = ID_MASSBALANCE;
      56                 :            : 
      57                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      58                 :            : CLASS IMPLEMENTATION
      59                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      60                 :            : 
      61                 :            : 
      62                 :          1 : FGMassBalance::FGMassBalance(FGFDMExec* fdmex) : FGModel(fdmex)
      63                 :            : {
      64                 :          1 :   Name = "FGMassBalance";
      65                 :          1 :   Weight = EmptyWeight = Mass = 0.0;
      66                 :            : 
      67                 :          1 :   vbaseXYZcg.InitMatrix(0.0);
      68                 :          1 :   vXYZcg.InitMatrix(0.0);
      69                 :          1 :   vLastXYZcg.InitMatrix(0.0);
      70                 :          1 :   vDeltaXYZcg.InitMatrix(0.0);
      71                 :          1 :   baseJ.InitMatrix();
      72                 :          1 :   mJ.InitMatrix();
      73                 :          1 :   mJinv.InitMatrix();
      74                 :          1 :   pmJ.InitMatrix();
      75                 :            : 
      76                 :          1 :   bind();
      77                 :            : 
      78                 :          1 :   Debug(0);
      79                 :          1 : }
      80                 :            : 
      81                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      82                 :            : 
      83                 :          1 : FGMassBalance::~FGMassBalance()
      84                 :            : {
      85 [ +  - ][ +  + ]:         20 :   for (unsigned int i=0; i<PointMasses.size(); i++) delete PointMasses[i];
         [ #  # ][ #  # ]
      86                 :          1 :   PointMasses.clear();
      87                 :            : 
      88                 :          1 :   Debug(1);
      89                 :          1 : }
      90                 :            : 
      91                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      92                 :            : 
      93                 :          1 : bool FGMassBalance::InitModel(void)
      94                 :            : {
      95         [ -  + ]:          1 :   if (!FGModel::InitModel()) return false;
      96                 :            : 
      97                 :          1 :   vLastXYZcg.InitMatrix(0.0);
      98                 :          1 :   vDeltaXYZcg.InitMatrix(0.0);
      99                 :            : 
     100                 :          1 :   return true;
     101                 :            : }
     102                 :            : 
     103                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     104                 :            : 
     105                 :          1 : bool FGMassBalance::Load(Element* el)
     106                 :            : {
     107                 :            :   Element *element;
     108                 :          1 :   string element_name = "";
     109                 :            :   double bixx, biyy, bizz, bixy, bixz, biyz;
     110                 :            : 
     111                 :          1 :   FGModel::Load(el); // Perform base class Load.
     112                 :            : 
     113                 :          1 :   bixx = biyy = bizz = bixy = bixz = biyz = 0.0;
     114         [ -  + ]:          1 :   if (el->FindElement("ixx"))
     115                 :          0 :     bixx = el->FindElementValueAsNumberConvertTo("ixx", "SLUG*FT2");
     116         [ -  + ]:          1 :   if (el->FindElement("iyy"))
     117                 :          0 :     biyy = el->FindElementValueAsNumberConvertTo("iyy", "SLUG*FT2");
     118         [ -  + ]:          1 :   if (el->FindElement("izz"))
     119                 :          0 :     bizz = el->FindElementValueAsNumberConvertTo("izz", "SLUG*FT2");
     120         [ -  + ]:          1 :   if (el->FindElement("ixy"))
     121                 :          0 :     bixy = el->FindElementValueAsNumberConvertTo("ixy", "SLUG*FT2");
     122         [ -  + ]:          1 :   if (el->FindElement("ixz"))
     123                 :          0 :     bixz = el->FindElementValueAsNumberConvertTo("ixz", "SLUG*FT2");
     124         [ -  + ]:          1 :   if (el->FindElement("iyz"))
     125                 :          0 :     biyz = el->FindElementValueAsNumberConvertTo("iyz", "SLUG*FT2");
     126                 :            :   SetAircraftBaseInertias(FGMatrix33(  bixx,  -bixy,  bixz,
     127                 :            :                                       -bixy,  biyy,  -biyz,
     128                 :          1 :                                        bixz,  -biyz,  bizz ));
     129         [ -  + ]:          1 :   if (el->FindElement("emptywt")) {
     130                 :          0 :     EmptyWeight = el->FindElementValueAsNumberConvertTo("emptywt", "LBS");
     131                 :            :   }
     132                 :            : 
     133                 :          1 :   element = el->FindElement("location");
     134         [ -  + ]:          1 :   while (element) {
     135                 :          0 :     element_name = element->GetAttributeValue("name");
     136         [ #  # ]:          0 :     if (element_name == "CG") vbaseXYZcg = element->FindElementTripletConvertTo("IN");
     137                 :          0 :     element = el->FindNextElement("location");
     138                 :            :   }
     139                 :            : 
     140                 :            : // Find all POINTMASS elements that descend from this METRICS branch of the
     141                 :            : // config file.
     142                 :            : 
     143                 :          1 :   element = el->FindElement("pointmass");
     144         [ +  + ]:         20 :   while (element) {
     145                 :         19 :     AddPointMass(element);
     146                 :         19 :     element = el->FindNextElement("pointmass");
     147                 :            :   }
     148                 :            : 
     149                 :          1 :   double ChildFDMWeight = 0.0;
     150         [ -  + ]:          1 :   for (int fdm=0; fdm<FDMExec->GetFDMCount(); fdm++) {
     151         [ #  # ]:          0 :     if (FDMExec->GetChildFDM(fdm)->mated) ChildFDMWeight += FDMExec->GetChildFDM(fdm)->exec->GetMassBalance()->GetWeight();
     152                 :            :   }
     153                 :            : 
     154                 :            :   Weight = EmptyWeight + Propulsion->GetTanksWeight() + GetTotalPointMassWeight()
     155                 :          1 :     + BuoyantForces->GetGasMass()*slugtolb + ChildFDMWeight;
     156                 :            : 
     157                 :          1 :   Mass = lbtoslug*Weight;
     158                 :            : 
     159                 :          1 :   PostLoad(el, PropertyManager);
     160                 :            : 
     161                 :          1 :   Debug(2);
     162                 :          1 :   return true;
     163                 :            : }
     164                 :            : 
     165                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     166                 :            : 
     167                 :      54006 : bool FGMassBalance::Run(void)
     168                 :            : {
     169                 :            :   double denom, k1, k2, k3, k4, k5, k6;
     170                 :            :   double Ixx, Iyy, Izz, Ixy, Ixz, Iyz;
     171                 :            : 
     172         [ -  + ]:      54006 :   if (FGModel::Run()) return true;
     173         [ -  + ]:      54006 :   if (FDMExec->Holding()) return false;
     174                 :            : 
     175                 :      54006 :   RunPreFunctions();
     176                 :            : 
     177                 :      54006 :   double ChildFDMWeight = 0.0;
     178         [ -  + ]:      54006 :   for (int fdm=0; fdm<FDMExec->GetFDMCount(); fdm++) {
     179         [ #  # ]:          0 :     if (FDMExec->GetChildFDM(fdm)->mated) ChildFDMWeight += FDMExec->GetChildFDM(fdm)->exec->GetMassBalance()->GetWeight();
     180                 :            :   }
     181                 :            : 
     182                 :            :   Weight = EmptyWeight + Propulsion->GetTanksWeight() + GetTotalPointMassWeight()
     183                 :      54006 :     + BuoyantForces->GetGasMass()*slugtolb + ChildFDMWeight;
     184                 :            : 
     185                 :      54006 :   Mass = lbtoslug*Weight;
     186                 :            : 
     187                 :            : // Calculate new CG
     188                 :            : 
     189                 :            :   vXYZcg = (Propulsion->GetTanksMoment() + EmptyWeight*vbaseXYZcg
     190                 :            :             + GetPointMassMoment()
     191                 :      54006 :             + BuoyantForces->GetGasMassMoment()) / Weight;
     192                 :            : 
     193                 :            :   // Track frame-by-frame delta CG, and move the EOM-tracked location
     194                 :            :   // by this amount.
     195         [ +  + ]:      54006 :   if (vLastXYZcg.Magnitude() == 0.0) vLastXYZcg = vXYZcg;
     196                 :     108012 :   vDeltaXYZcg = vXYZcg - vLastXYZcg;
     197                 :      54006 :   vDeltaXYZcgBody = StructuralToBody(vLastXYZcg) - StructuralToBody(vXYZcg);
     198                 :      54006 :   vLastXYZcg = vXYZcg;
     199                 :     108012 :   Propagate->NudgeBodyLocation(vDeltaXYZcgBody);
     200                 :            : 
     201                 :            : // Calculate new total moments of inertia
     202                 :            : 
     203                 :            :   // At first it is the base configuration inertia matrix ...
     204                 :      54006 :   mJ = baseJ;
     205                 :            :   // ... with the additional term originating from the parallel axis theorem.
     206                 :      54006 :   mJ += GetPointmassInertia( lbtoslug * EmptyWeight, vbaseXYZcg );
     207                 :            :   // Then add the contributions from the additional pointmasses.
     208                 :      54006 :   mJ += CalculatePMInertias();
     209                 :      54006 :   mJ += Propulsion->CalculateTankInertias();
     210                 :      54006 :   mJ += BuoyantForces->GetGasMassInertia();
     211                 :            : 
     212                 :     108012 :   Ixx = mJ(1,1);
     213                 :     108012 :   Iyy = mJ(2,2);
     214                 :     108012 :   Izz = mJ(3,3);
     215                 :     108012 :   Ixy = -mJ(1,2);
     216                 :     108012 :   Ixz = -mJ(1,3);
     217                 :     108012 :   Iyz = -mJ(2,3);
     218                 :            : 
     219                 :            : // Calculate inertia matrix inverse (ref. Stevens and Lewis, "Flight Control & Simulation")
     220                 :            : 
     221                 :      54006 :   k1 = (Iyy*Izz - Iyz*Iyz);
     222                 :      54006 :   k2 = (Iyz*Ixz + Ixy*Izz);
     223                 :      54006 :   k3 = (Ixy*Iyz + Iyy*Ixz);
     224                 :            : 
     225                 :      54006 :   denom = 1.0/(Ixx*k1 - Ixy*k2 - Ixz*k3 );
     226                 :      54006 :   k1 = k1*denom;
     227                 :      54006 :   k2 = k2*denom;
     228                 :      54006 :   k3 = k3*denom;
     229                 :      54006 :   k4 = (Izz*Ixx - Ixz*Ixz)*denom;
     230                 :      54006 :   k5 = (Ixy*Ixz + Iyz*Ixx)*denom;
     231                 :      54006 :   k6 = (Ixx*Iyy - Ixy*Ixy)*denom;
     232                 :            : 
     233                 :            :   mJinv.InitMatrix( k1, k2, k3,
     234                 :            :                     k2, k4, k5,
     235                 :      54006 :                     k3, k5, k6 );
     236                 :            : 
     237                 :      54006 :   RunPostFunctions();
     238                 :            : 
     239                 :      54006 :   Debug(0);
     240                 :            : 
     241                 :      54006 :   return false;
     242                 :            : }
     243                 :            : 
     244                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     245                 :            : 
     246                 :         19 : void FGMassBalance::AddPointMass(Element* el)
     247                 :            : {
     248                 :         19 :   double radius=0, length=0;
     249                 :         19 :   Element* loc_element = el->FindElement("location");
     250                 :         19 :   string pointmass_name = el->GetAttributeValue("name");
     251         [ -  + ]:         19 :   if (!loc_element) {
     252                 :          0 :     cerr << "Pointmass " << pointmass_name << " has no location." << endl;
     253                 :          0 :     exit(-1);
     254                 :            :   }
     255                 :            : 
     256                 :         19 :   double w = el->FindElementValueAsNumberConvertTo("weight", "LBS");
     257                 :         19 :   FGColumnVector3 vXYZ = loc_element->FindElementTripletConvertTo("IN");
     258                 :            : 
     259                 :         19 :   PointMass *pm = new PointMass(w, vXYZ);
     260                 :         38 :   pm->SetName(pointmass_name);
     261                 :            : 
     262                 :         19 :   Element* form_element = el->FindElement("form");
     263         [ +  - ]:         19 :   if (form_element) {
     264                 :         19 :     string shape = form_element->GetAttributeValue("shape");
     265                 :         19 :     Element* radius_element = form_element->FindElement("radius");
     266                 :         19 :     Element* length_element = form_element->FindElement("length");
     267         [ +  - ]:         19 :     if (radius_element) radius = form_element->FindElementValueAsNumberConvertTo("radius", "FT");
     268         [ +  - ]:         19 :     if (length_element) length = form_element->FindElementValueAsNumberConvertTo("length", "FT");
     269         [ +  + ]:         19 :     if (shape == "tube") {
     270                 :          6 :       pm->SetPointMassShapeType(PointMass::esTube);
     271                 :          6 :       pm->SetRadius(radius);
     272                 :          6 :       pm->SetLength(length);
     273                 :          6 :       pm->CalculateShapeInertia();
     274         [ +  - ]:         13 :     } else if (shape == "cylinder") {
     275                 :         13 :       pm->SetPointMassShapeType(PointMass::esCylinder);
     276                 :         13 :       pm->SetRadius(radius);
     277                 :         13 :       pm->SetLength(length);
     278                 :         13 :       pm->CalculateShapeInertia();
     279         [ #  # ]:          0 :     } else if (shape == "sphere") {
     280                 :          0 :       pm->SetPointMassShapeType(PointMass::esSphere);
     281                 :          0 :       pm->SetRadius(radius);
     282                 :          0 :       pm->CalculateShapeInertia();
     283         [ #  # ]:          0 :     } else if (shape == "ball") {
     284                 :          0 :       pm->SetPointMassShapeType(PointMass::esBall);
     285                 :          0 :       pm->SetRadius(radius);
     286                 :          0 :       pm->CalculateShapeInertia();
     287                 :            :     } else {
     288                 :         19 :     }
     289                 :            :   }
     290                 :            : 
     291                 :         19 :   pm->bind(PropertyManager, PointMasses.size());
     292                 :         19 :   PointMasses.push_back(pm);
     293                 :         19 : }
     294                 :            : 
     295                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     296                 :            : 
     297                 :      54007 : double FGMassBalance::GetTotalPointMassWeight(void)
     298                 :            : {
     299                 :      54007 :   double PM_total_weight = 0.0;
     300                 :            : 
     301         [ +  + ]:    1080140 :   for (unsigned int i=0; i<PointMasses.size(); i++) {
     302                 :    2052266 :     PM_total_weight += PointMasses[i]->Weight;
     303                 :            :   }
     304                 :      54007 :   return PM_total_weight;
     305                 :            : }
     306                 :            : 
     307                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     308                 :            : 
     309                 :      54006 : FGColumnVector3& FGMassBalance::GetPointMassMoment(void)
     310                 :            : {
     311                 :      54006 :   PointMassCG.InitMatrix();
     312                 :            : 
     313         [ +  + ]:    1080120 :   for (unsigned int i=0; i<PointMasses.size(); i++) {
     314                 :    4104456 :     PointMassCG += PointMasses[i]->Weight*PointMasses[i]->Location;
     315                 :            :   }
     316                 :      54006 :   return PointMassCG;
     317                 :            : }
     318                 :            : 
     319                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     320                 :            : 
     321                 :      54006 : FGMatrix33& FGMassBalance::CalculatePMInertias(void)
     322                 :            : {
     323                 :            :   unsigned int size;
     324                 :            : 
     325                 :     108012 :   size = PointMasses.size();
     326         [ -  + ]:      54006 :   if (size == 0) return pmJ;
     327                 :            : 
     328                 :      54006 :   pmJ = FGMatrix33();
     329                 :            : 
     330         [ +  + ]:    1080120 :   for (unsigned int i=0; i<size; i++) {
     331                 :    1026114 :     pmJ += GetPointmassInertia( lbtoslug * PointMasses[i]->Weight, PointMasses[i]->Location );
     332                 :    1026114 :     pmJ += PointMasses[i]->GetPointMassInertia();
     333                 :            :   }
     334                 :            : 
     335                 :      54006 :   return pmJ;
     336                 :            : }
     337                 :            : 
     338                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     339                 :            : 
     340                 :    2375352 : FGColumnVector3 FGMassBalance::StructuralToBody(const FGColumnVector3& r) const
     341                 :            : {
     342                 :            :   // Under the assumption that in the structural frame the:
     343                 :            :   //
     344                 :            :   // - X-axis is directed afterwards,
     345                 :            :   // - Y-axis is directed towards the right,
     346                 :            :   // - Z-axis is directed upwards,
     347                 :            :   //
     348                 :            :   // (as documented in http://jsbsim.sourceforge.net/JSBSimCoordinates.pdf)
     349                 :            :   // we have to subtract first the center of gravity of the plane which
     350                 :            :   // is also defined in the structural frame:
     351                 :            :   //
     352                 :            :   //   FGColumnVector3 cgOff = r - vXYZcg;
     353                 :            :   //
     354                 :            :   // Next, we do a change of units:
     355                 :            :   //
     356                 :            :   //   cgOff *= inchtoft;
     357                 :            :   //
     358                 :            :   // And then a 180 degree rotation is done about the Y axis so that the:
     359                 :            :   //
     360                 :            :   // - X-axis is directed forward,
     361                 :            :   // - Y-axis is directed towards the right,
     362                 :            :   // - Z-axis is directed downward.
     363                 :            :   //
     364                 :            :   // This is needed because the structural and body frames are 180 degrees apart.
     365                 :            : 
     366                 :            :   return FGColumnVector3(inchtoft*(vXYZcg(1)-r(1)),
     367                 :            :                          inchtoft*(r(2)-vXYZcg(2)),
     368                 :   11876760 :                          inchtoft*(vXYZcg(3)-r(3)));
     369                 :            : }
     370                 :            : 
     371                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     372                 :            : 
     373                 :          1 : void FGMassBalance::bind(void)
     374                 :            : {
     375                 :            :   typedef double (FGMassBalance::*PMF)(int) const;
     376                 :            :   PropertyManager->Tie("inertia/mass-slugs", this,
     377                 :          1 :                        &FGMassBalance::GetMass);
     378                 :            :   PropertyManager->Tie("inertia/weight-lbs", this,
     379                 :          1 :                        &FGMassBalance::GetWeight);
     380                 :            :   PropertyManager->Tie("inertia/empty-weight-lbs", this,
     381                 :          1 :                        &FGMassBalance::GetEmptyWeight);
     382                 :            :   PropertyManager->Tie("inertia/cg-x-in", this,1,
     383                 :          1 :                        (PMF)&FGMassBalance::GetXYZcg);
     384                 :            :   PropertyManager->Tie("inertia/cg-y-in", this,2,
     385                 :          1 :                        (PMF)&FGMassBalance::GetXYZcg);
     386                 :            :   PropertyManager->Tie("inertia/cg-z-in", this,3,
     387                 :          1 :                        (PMF)&FGMassBalance::GetXYZcg);
     388                 :          1 : }
     389                 :            : 
     390                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     391                 :            : //
     392                 :            : // This function binds properties for each pointmass object created.
     393                 :            : //
     394                 :         19 : void FGMassBalance::PointMass::bind(FGPropertyManager* PropertyManager, int num) {
     395                 :         19 :   string tmp = CreateIndexedPropertyName("inertia/pointmass-weight-lbs", num);
     396                 :            :   PropertyManager->Tie( tmp.c_str(), this, &PointMass::GetPointMassWeight,
     397                 :         38 :                                        &PointMass::SetPointMassWeight);
     398                 :            : 
     399                 :         38 :   tmp = CreateIndexedPropertyName("inertia/pointmass-location-X-inches", num);
     400                 :            :   PropertyManager->Tie( tmp.c_str(), this, eX, &PointMass::GetPointMassLocation,
     401                 :         19 :                                            &PointMass::SetPointMassLocation);
     402                 :         38 :   tmp = CreateIndexedPropertyName("inertia/pointmass-location-Y-inches", num);
     403                 :            :   PropertyManager->Tie( tmp.c_str(), this, eY, &PointMass::GetPointMassLocation,
     404                 :         19 :                                            &PointMass::SetPointMassLocation);
     405                 :         38 :   tmp = CreateIndexedPropertyName("inertia/pointmass-location-Z-inches", num);
     406                 :            :   PropertyManager->Tie( tmp.c_str(), this, eZ, &PointMass::GetPointMassLocation,
     407                 :         19 :                                            &PointMass::SetPointMassLocation);
     408                 :         19 : }
     409                 :            : 
     410                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     411                 :            : 
     412                 :          1 : void FGMassBalance::GetMassPropertiesReport(void) const
     413                 :            : {
     414                 :            :   cout << endl << fgblue << highint 
     415                 :            :        << "  Mass Properties Report (English units: lbf, in, slug-ft^2)"
     416                 :          1 :        << reset << endl;
     417                 :            :   cout << "                                  " << underon << "    Weight    CG-X    CG-Y"
     418                 :          1 :        << "    CG-Z         Ixx         Iyy         Izz" << underoff << endl;
     419                 :            :   cout.precision(1);
     420                 :            :   cout << highint << setw(34) << left << "    Base Vehicle " << normint
     421                 :            :        << right << setw(10) << EmptyWeight << setw(8) << vbaseXYZcg(eX) << setw(8)
     422                 :            :        << vbaseXYZcg(eY) << setw(8) << vbaseXYZcg(eZ) << setw(12) << baseJ(1,1)
     423                 :          1 :        << setw(12) << baseJ(2,2) << setw(12) << baseJ(3,3) << endl;
     424                 :            : 
     425         [ +  + ]:         20 :   for (unsigned int i=0;i<PointMasses.size();i++) {
     426                 :         38 :     PointMass* pm = PointMasses[i];
     427                 :         19 :     double pmweight = pm->GetPointMassWeight();
     428                 :            :     cout << highint << left << setw(4) << i << setw(30) << pm->GetName() << normint
     429                 :            :          << right << setw(10) << pmweight << setw(8) << pm->GetLocation()(eX)
     430                 :            :          << setw(8) << pm->GetLocation()(eY) << setw(8) << pm->GetLocation()(eZ)
     431                 :            :          << setw(12) << pm->GetPointMassMoI(1,1) << setw(12) << pm->GetPointMassMoI(2,2)
     432                 :         57 :          << setw(12) << pm->GetPointMassMoI(3,3) << endl;
     433                 :            :   }
     434                 :            : 
     435         [ +  + ]:          7 :   for (unsigned int i=0;i<Propulsion->GetNumTanks() ;i++) {
     436                 :         12 :     FGTank* tank = Propulsion->GetTank(i);
     437                 :          6 :     string tankname="";
     438 [ +  + ][ +  + ]:          6 :     if (tank->GetType() == FGTank::ttFUEL && tank->GetGrainType() != FGTank::gtUNKNOWN) {
                 [ +  + ]
     439                 :            :       tankname = "Solid Fuel";
     440         [ +  + ]:          4 :     } else if (tank->GetType() == FGTank::ttFUEL) {
     441                 :            :       tankname = "Fuel";
     442         [ +  - ]:          2 :     } else if (tank->GetType() == FGTank::ttOXIDIZER) {
     443                 :            :       tankname = "Oxidizer";
     444                 :            :     } else {
     445                 :            :       tankname = "(Unknown tank type)";
     446                 :            :     }
     447                 :            :     cout << highint << left << setw(4) << i << setw(30) << tankname << normint
     448                 :            :       << right << setw(10) << tank->GetContents() << setw(8) << tank->GetXYZ(eX)
     449                 :            :          << setw(8) << tank->GetXYZ(eY) << setw(8) << tank->GetXYZ(eZ)
     450                 :            :          << setw(12) << "*" << setw(12) << "*"
     451                 :         18 :          << setw(12) << "*" << endl;
     452                 :            :   }
     453                 :            : 
     454                 :          1 :   cout << underon << setw(104) << " " << underoff << endl;
     455                 :            :   cout << highint << left << setw(30) << "    Total: " << right << setw(14) << Weight 
     456                 :            :        << setw(8) << vXYZcg(eX)
     457                 :            :        << setw(8) << vXYZcg(eY)
     458                 :            :        << setw(8) << vXYZcg(eZ)
     459                 :            :        << setw(12) << mJ(1,1)
     460                 :            :        << setw(12) << mJ(2,2)
     461                 :            :        << setw(12) << mJ(3,3)
     462                 :          2 :        << normint << endl;
     463                 :            : 
     464                 :            :   cout.setf(ios_base::fixed);
     465                 :          1 : }
     466                 :            : 
     467                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     468                 :            : //    The bitmasked value choices are as follows:
     469                 :            : //    unset: In this case (the default) JSBSim would only print
     470                 :            : //       out the normally expected messages, essentially echoing
     471                 :            : //       the config files as they are read. If the environment
     472                 :            : //       variable is not set, debug_lvl is set to 1 internally
     473                 :            : //    0: This requests JSBSim not to output any messages
     474                 :            : //       whatsoever.
     475                 :            : //    1: This value explicity requests the normal JSBSim
     476                 :            : //       startup messages
     477                 :            : //    2: This value asks for a message to be printed out when
     478                 :            : //       a class is instantiated
     479                 :            : //    4: When this value is set, a message is displayed when a
     480                 :            : //       FGModel object executes its Run() method
     481                 :            : //    8: When this value is set, various runtime state variables
     482                 :            : //       are printed out periodically
     483                 :            : //    16: When set various parameters are sanity checked and
     484                 :            : //       a message is printed out when they go out of bounds
     485                 :            : 
     486                 :      54009 : void FGMassBalance::Debug(int from)
     487                 :            : {
     488         [ +  - ]:      54009 :   if (debug_lvl <= 0) return;
     489                 :            : 
     490         [ +  - ]:      54009 :   if (debug_lvl & 1) { // Standard console startup message output
     491         [ +  + ]:      54009 :     if (from == 2) { // Loading
     492                 :          1 :       cout << endl << "  Mass and Balance:" << endl;
     493                 :          2 :       cout << "    baseIxx: " << baseJ(1,1) << " slug-ft2" << endl;
     494                 :          2 :       cout << "    baseIyy: " << baseJ(2,2) << " slug-ft2" << endl;
     495                 :          2 :       cout << "    baseIzz: " << baseJ(3,3) << " slug-ft2" << endl;
     496                 :          2 :       cout << "    baseIxy: " << baseJ(1,2) << " slug-ft2" << endl;
     497                 :          2 :       cout << "    baseIxz: " << baseJ(1,3) << " slug-ft2" << endl;
     498                 :          2 :       cout << "    baseIyz: " << baseJ(2,3) << " slug-ft2" << endl;
     499                 :          2 :       cout << "    Empty Weight: " << EmptyWeight << " lbm" << endl;
     500                 :          1 :       cout << "    CG (x, y, z): " << vbaseXYZcg << endl;
     501                 :            :       // ToDo: Need to add point mass outputs here
     502         [ +  + ]:         20 :       for (unsigned int i=0; i<PointMasses.size(); i++) {
     503                 :            :         cout << "    Point Mass Object: " << PointMasses[i]->Weight << " lbs. at "
     504                 :            :                    << "X, Y, Z (in.): " << PointMasses[i]->Location(eX) << "  "
     505                 :            :                    << PointMasses[i]->Location(eY) << "  "
     506                 :         76 :                    << PointMasses[i]->Location(eZ) << endl;
     507                 :            :       }
     508                 :            :     }
     509                 :            :   }
     510         [ -  + ]:      54009 :   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
     511         [ #  # ]:          0 :     if (from == 0) cout << "Instantiated: FGMassBalance" << endl;
     512         [ #  # ]:          0 :     if (from == 1) cout << "Destroyed:    FGMassBalance" << endl;
     513                 :            :   }
     514                 :      54009 :   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
     515                 :            :   }
     516                 :      54009 :   if (debug_lvl & 8 ) { // Runtime state variables
     517                 :            :   }
     518         [ -  + ]:      54009 :   if (debug_lvl & 16) { // Sanity checking
     519         [ #  # ]:          0 :     if (from == 2) {
     520 [ #  # ][ #  # ]:          0 :       if (EmptyWeight <= 0.0 || EmptyWeight > 1e9)
     521                 :          0 :         cout << "MassBalance::EmptyWeight out of bounds: " << EmptyWeight << endl;
     522 [ #  # ][ #  # ]:          0 :       if (Weight <= 0.0 || Weight > 1e9)
     523                 :          0 :         cout << "MassBalance::Weight out of bounds: " << Weight << endl;
     524 [ #  # ][ #  # ]:          0 :       if (Mass <= 0.0 || Mass > 1e9)
     525                 :          0 :         cout << "MassBalance::Mass out of bounds: " << Mass << endl;
     526                 :            :     }
     527                 :            :   }
     528         [ -  + ]:      54009 :   if (debug_lvl & 64) {
     529         [ #  # ]:          0 :     if (from == 0) { // Constructor
     530                 :          0 :       cout << IdSrc << endl;
     531                 :          0 :       cout << IdHdr << endl;
     532                 :            :     }
     533                 :            :   }
     534                 :            : }
     535 [ +  + ][ +  - ]:         12 : }

Generated by: LCOV version 1.9