![]() |
JSBSim Flight Dynamics Model 1.0 (23 February 2013)
An Open Source Flight Dynamics and Control Software Library in C++
|
Models weight, balance and moment of inertia information. More...
#include <FGMassBalance.h>
Inheritance diagram for FGMassBalance:
Collaboration diagram for FGMassBalance: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 FGColumnVector3 & | GetDeltaXYZcg (void) const |
| double | GetDeltaXYZcg (int axis) const |
| double | GetEmptyWeight (void) const |
| const FGMatrix33 & | GetJ (void) const |
| const FGMatrix33 & | GetJinv (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 FGColumnVector3 & | GetPointMassMoment (void) |
| double | GetTotalPointMassWeight (void) const |
| double | GetWeight (void) const |
| double | GetXYZcg (int axis) const |
| const FGColumnVector3 & | GetXYZcg (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 |
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.
<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.
| 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.
| mass_sl | the mass of this single pointmass given in slugs |
| r | the 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] |
| el | a pointer to the element |
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] |
| Holding | if 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. |
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.
| r | vector coordinate in the structural reference frame (X positive aft, measurements in inches). |
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: