JSBSim Flight Dynamics Model 1.0 (23 February 2013)
An Open Source Flight Dynamics and Control Software Library in C++

FGMassBalance Class Reference

Models weight, balance and moment of inertia information. More...

#include <FGMassBalance.h>

Inheritance diagram for FGMassBalance:
Collaboration diagram for FGMassBalance:

List of all members.

Classes

struct  Inputs
struct  PointMass
 The PointMass structure encapsulates a point mass object, moments of inertia mass, location, etc.

Public Member Functions

 FGMassBalance (FGFDMExec *)
void AddPointMass (Element *el)
const FGColumnVector3GetDeltaXYZcg (void) const
double GetDeltaXYZcg (int axis) const
double GetEmptyWeight (void) const
const FGMatrix33GetJ (void) const
const FGMatrix33GetJinv (void) const
double GetMass (void) const
void GetMassPropertiesReport (void) const
FGMatrix33 GetPointmassInertia (double mass_sl, const FGColumnVector3 &r) const
 Computes the inertia contribution of a pointmass.
const FGColumnVector3GetPointMassMoment (void)
double GetTotalPointMassWeight (void) const
double GetWeight (void) const
double GetXYZcg (int axis) const
const FGColumnVector3GetXYZcg (void) const
bool InitModel (void)
bool Load (Element *el)
 Loads this model.
bool Run (bool Holding)
 Runs the Mass Balance model; called by the Executive Can pass in a value indicating if the executive is directing the simulation to Hold.
void SetAircraftBaseInertias (const FGMatrix33 &BaseJ)
void SetBaseCG (const FGColumnVector3 &CG)
void SetEmptyWeight (double EW)
FGColumnVector3 StructuralToBody (const FGColumnVector3 &r) const
 Conversion from the structural frame to the body frame.

Public Attributes

struct
JSBSim::FGMassBalance::Inputs 
in

Detailed Description

Maintains a vector of point masses. Sums the contribution of all, and provides this to FGPropagate. Loads the <mass_balance> section of the aircraft configuration file. There can be any number of <pointmasses>. Each can also have a shape which - if present - causes an associated moment of inertia to be calculated based on the shape. Note that a cylinder is solid, a tube is hollow, a ball is solid and a sphere is hollow.

Configuration File Format:

    <mass_balance>
        <ixx unit="{SLUG*FT2 | KG*M2}"> {number} </ixx>
        <iyy unit="{SLUG*FT2 | KG*M2}"> {number} </iyy>
        <izz unit="{SLUG*FT2 | KG*M2}"> {number} </izz>
        <ixy unit="{SLUG*FT2 | KG*M2}"> {number} </ixy>
        <ixz unit="{SLUG*FT2 | KG*M2}"> {number} </ixz>
        <iyz unit="{SLUG*FT2 | KG*M2}"> {number} </iyz>
        <emptywt unit="{LBS | KG"> {number} </emptywt>
        <location name="CG" unit="{IN | FT | M}">
            <x> {number} </x>
            <y> {number} </y>
            <z> {number} </z>
        </location>
        [<pointmass name="{string}">
            <form shape="{tube | cylinder | sphere | ball}">
               <radius unit="{IN | FT | M}"> {number} </radius>
               <length unit="{IN | FT | M}"> {number} </length>
            </form> 
            <weight unit="{LBS | KG}"> {number} </weight>
            <location name="{string}" unit="{IN | FT | M}">
                <x> {number} </x>
                <y> {number} </y>
                <z> {number} </z>
            </location>
        </pointmass>
        ... other point masses ...]
    </mass_balance>

Definition at line 111 of file FGMassBalance.h.


Member Function Documentation

FGMatrix33 GetPointmassInertia ( double  mass_sl,
const FGColumnVector3 r 
) const [inline]

Computes and returns the inertia matrix of a pointmass of mass slugs at the given vector r in the structural frame. The units should be for the mass in slug and the vector in the structural frame as usual in inches.

Parameters:
mass_slthe mass of this single pointmass given in slugs
rthe location of this single pointmass in the structural frame

Definition at line 145 of file FGMassBalance.h.

References FGMassBalance::StructuralToBody().

Referenced by FGBallonet::Calculate(), FGGasCell::Calculate(), and FGMassBalance::Run().

  {
    FGColumnVector3 v = StructuralToBody( r );
    FGColumnVector3 sv = mass_sl*v;
    double xx = sv(1)*v(1);
    double yy = sv(2)*v(2);
    double zz = sv(3)*v(3);
    double xy = -sv(1)*v(2);
    double xz = -sv(1)*v(3);
    double yz = -sv(2)*v(3);
    return FGMatrix33( yy+zz, xy, xz,
                       xy, xx+zz, yz,
                       xz, yz, xx+yy );
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Load ( Element el) [virtual]
Parameters:
ela pointer to the element
Returns:
true if model is successfully loaded

Reimplemented from FGModel.

Definition at line 101 of file FGMassBalance.cpp.

References Element::FindElement(), Element::FindElementTripletConvertTo(), Element::FindElementValueAsNumberConvertTo(), Element::FindNextElement(), Element::GetAttributeValue(), FGFDMExec::GetChildFDM(), FGFDMExec::GetFDMCount(), and FGFDMExec::GetFullAircraftPath().

{
  string element_name = "";
  double bixx, biyy, bizz, bixy, bixz, biyz;
  string fname="", file="";
  string separator = "/";

  fname = elem->GetAttributeValue("file");
  if (!fname.empty()) {
    file = FDMExec->GetFullAircraftPath() + separator + fname;
    document = LoadXMLDocument(file);
    if (document == 0L) return false;
  } else {
    document = elem;
  }

  FGModel::Load(document); // Perform base class Load.

  bixx = biyy = bizz = bixy = bixz = biyz = 0.0;
  if (document->FindElement("ixx"))
    bixx = document->FindElementValueAsNumberConvertTo("ixx", "SLUG*FT2");
  if (document->FindElement("iyy"))
    biyy = document->FindElementValueAsNumberConvertTo("iyy", "SLUG*FT2");
  if (document->FindElement("izz"))
    bizz = document->FindElementValueAsNumberConvertTo("izz", "SLUG*FT2");
  if (document->FindElement("ixy"))
    bixy = document->FindElementValueAsNumberConvertTo("ixy", "SLUG*FT2");
  if (document->FindElement("ixz"))
    bixz = document->FindElementValueAsNumberConvertTo("ixz", "SLUG*FT2");
  if (document->FindElement("iyz"))
    biyz = document->FindElementValueAsNumberConvertTo("iyz", "SLUG*FT2");
  SetAircraftBaseInertias(FGMatrix33(  bixx,  -bixy,  bixz,
                                      -bixy,  biyy,  -biyz,
                                       bixz,  -biyz,  bizz ));
  if (document->FindElement("emptywt")) {
    EmptyWeight = document->FindElementValueAsNumberConvertTo("emptywt", "LBS");
  }

  Element *element = document->FindElement("location");
  while (element) {
    element_name = element->GetAttributeValue("name");
    if (element_name == "CG") vbaseXYZcg = element->FindElementTripletConvertTo("IN");
    element = document->FindNextElement("location");
  }

// Find all POINTMASS elements that descend from this METRICS branch of the
// config file.

  element = document->FindElement("pointmass");
  while (element) {
    AddPointMass(element);
    element = document->FindNextElement("pointmass");
  }

  double ChildFDMWeight = 0.0;
  for (int fdm=0; fdm<FDMExec->GetFDMCount(); fdm++) {
    if (FDMExec->GetChildFDM(fdm)->mated) ChildFDMWeight += FDMExec->GetChildFDM(fdm)->exec->GetMassBalance()->GetWeight();
  }

  Weight = EmptyWeight + in.TanksWeight + GetTotalPointMassWeight()
    + in.GasMass*slugtolb + ChildFDMWeight;

  Mass = lbtoslug*Weight;

  PostLoad(document, PropertyManager);

  Debug(2);
  return true;
}

Here is the call graph for this function:

bool Run ( bool  Holding) [virtual]
Parameters:
Holdingif true, the executive has been directed to hold the sim from advancing time. Some models may ignore this flag, such as the Input model, which may need to be active to listen on a socket for the "Resume" command to be given.
Returns:
false if no error

Reimplemented from FGModel.

Definition at line 173 of file FGMassBalance.cpp.

References FGFDMExec::GetChildFDM(), FGFDMExec::GetFDMCount(), FGMassBalance::GetPointmassInertia(), FGFDMExec::GetPropagate(), FGMatrix33::InitMatrix(), FGColumnVector3::Magnitude(), FGModel::Run(), and FGMassBalance::StructuralToBody().

{
  double denom, k1, k2, k3, k4, k5, k6;
  double Ixx, Iyy, Izz, Ixy, Ixz, Iyz;

  if (FGModel::Run(Holding)) return true;
  if (Holding) return false;

  RunPreFunctions();

  double ChildFDMWeight = 0.0;
  for (int fdm=0; fdm<FDMExec->GetFDMCount(); fdm++) {
    if (FDMExec->GetChildFDM(fdm)->mated) ChildFDMWeight += FDMExec->GetChildFDM(fdm)->exec->GetMassBalance()->GetWeight();
  }

  Weight = EmptyWeight + in.TanksWeight + GetTotalPointMassWeight()
    + in.GasMass*slugtolb + ChildFDMWeight;

  Mass = lbtoslug*Weight;

// Calculate new CG

  vXYZcg = (EmptyWeight*vbaseXYZcg
            + GetPointMassMoment()
            + in.TanksMoment
            + in.GasMoment) / Weight;

  // Track frame-by-frame delta CG, and move the EOM-tracked location
  // by this amount.
  if (vLastXYZcg.Magnitude() == 0.0) vLastXYZcg = vXYZcg;
  vDeltaXYZcg = vXYZcg - vLastXYZcg;
  vDeltaXYZcgBody = StructuralToBody(vLastXYZcg) - StructuralToBody(vXYZcg);
  vLastXYZcg = vXYZcg;
  FDMExec->GetPropagate()->NudgeBodyLocation(vDeltaXYZcgBody);

// Calculate new total moments of inertia

  // At first it is the base configuration inertia matrix ...
  mJ = baseJ;
  // ... with the additional term originating from the parallel axis theorem.
  mJ += GetPointmassInertia( lbtoslug * EmptyWeight, vbaseXYZcg );
  // Then add the contributions from the additional pointmasses.
  mJ += CalculatePMInertias();
  mJ += in.TankInertia;
  mJ += in.GasInertia;

  Ixx = mJ(1,1);
  Iyy = mJ(2,2);
  Izz = mJ(3,3);
  Ixy = -mJ(1,2);
  Ixz = -mJ(1,3);
  Iyz = -mJ(2,3);

// Calculate inertia matrix inverse (ref. Stevens and Lewis, "Flight Control & Simulation")

  k1 = (Iyy*Izz - Iyz*Iyz);
  k2 = (Iyz*Ixz + Ixy*Izz);
  k3 = (Ixy*Iyz + Iyy*Ixz);

  denom = 1.0/(Ixx*k1 - Ixy*k2 - Ixz*k3 );
  k1 = k1*denom;
  k2 = k2*denom;
  k3 = k3*denom;
  k4 = (Izz*Ixx - Ixz*Ixz)*denom;
  k5 = (Ixy*Ixz + Iyz*Ixx)*denom;
  k6 = (Ixx*Iyy - Ixy*Ixy)*denom;

  mJinv.InitMatrix( k1, k2, k3,
                    k2, k4, k5,
                    k3, k5, k6 );

  RunPostFunctions();

  Debug(0);

  return false;
}

Here is the call graph for this function:

FGColumnVector3 StructuralToBody ( const FGColumnVector3 r) const

Converts the location given in the structural frame coordinate system to the body frame. The units of the structural frame are assumed to be in inches. The unit of the result is in ft.

Parameters:
rvector coordinate in the structural reference frame (X positive aft, measurements in inches).
Returns:
vector coordinate in the body frame, in feet.

Definition at line 347 of file FGMassBalance.cpp.

Referenced by FGMassBalance::GetPointmassInertia(), and FGMassBalance::Run().

{
  // Under the assumption that in the structural frame the:
  //
  // - X-axis is directed afterwards,
  // - Y-axis is directed towards the right,
  // - Z-axis is directed upwards,
  //
  // (as documented in http://jsbsim.sourceforge.net/JSBSimCoordinates.pdf)
  // we have to subtract first the center of gravity of the plane which
  // is also defined in the structural frame:
  //
  //   FGColumnVector3 cgOff = r - vXYZcg;
  //
  // Next, we do a change of units:
  //
  //   cgOff *= inchtoft;
  //
  // And then a 180 degree rotation is done about the Y axis so that the:
  //
  // - X-axis is directed forward,
  // - Y-axis is directed towards the right,
  // - Z-axis is directed downward.
  //
  // This is needed because the structural and body frames are 180 degrees apart.

  return FGColumnVector3(inchtoft*(vXYZcg(1)-r(1)),
                         inchtoft*(r(2)-vXYZcg(2)),
                         inchtoft*(vXYZcg(3)-r(3)));
}

Here is the caller graph for this function:


The documentation for this class was generated from the following files: