X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FFDM%2FJSBSim%2Fmodels%2FFGMassBalance.cpp;h=dbd8ab3a64565c40fa7b0ac28d4bab5bcd69a30c;hb=1575fad886a0b18825363d41d53a287e8d36b9c8;hp=73892ba614325f8d5ec4c233701d254e4dd78d6c;hpb=932b38a87e2870d23f9be9461b551f1e1fe556ba;p=flightgear.git diff --git a/src/FDM/JSBSim/models/FGMassBalance.cpp b/src/FDM/JSBSim/models/FGMassBalance.cpp index 73892ba61..dbd8ab3a6 100644 --- a/src/FDM/JSBSim/models/FGMassBalance.cpp +++ b/src/FDM/JSBSim/models/FGMassBalance.cpp @@ -5,23 +5,23 @@ Date started: 09/12/2000 Purpose: This module models weight and balance - ------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------- + ------------- Copyright (C) 2000 Jon S. Berndt (jon@jsbsim.org) -------------- This program is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free Software + the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU General Public License along with + You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Further information about the GNU General Public License can also be found on + Further information about the GNU Lesser General Public License can also be found on the world wide web at http://www.gnu.org. FUNCTIONAL DESCRIPTION @@ -38,13 +38,18 @@ HISTORY INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#include +#include +#include #include "FGMassBalance.h" -#include "FGPropulsion.h" -#include +#include "FGFDMExec.h" +#include "input_output/FGPropertyManager.h" + +using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id$"; +static const char *IdSrc = "$Id: FGMassBalance.cpp,v 1.39 2011/11/09 21:58:26 bcoconni Exp $"; static const char *IdHdr = ID_MASSBALANCE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -58,6 +63,9 @@ FGMassBalance::FGMassBalance(FGFDMExec* fdmex) : FGModel(fdmex) Weight = EmptyWeight = Mass = 0.0; vbaseXYZcg.InitMatrix(0.0); + vXYZcg.InitMatrix(0.0); + vLastXYZcg.InitMatrix(0.0); + vDeltaXYZcg.InitMatrix(0.0); baseJ.InitMatrix(); mJ.InitMatrix(); mJinv.InitMatrix(); @@ -72,19 +80,32 @@ FGMassBalance::FGMassBalance(FGFDMExec* fdmex) : FGModel(fdmex) FGMassBalance::~FGMassBalance() { - unbind(); + for (unsigned int i=0; iFindElement("ixx")) bixx = el->FindElementValueAsNumberConvertTo("ixx", "SLUG*FT2"); @@ -98,17 +119,19 @@ bool FGMassBalance::Load(Element* el) bixz = el->FindElementValueAsNumberConvertTo("ixz", "SLUG*FT2"); if (el->FindElement("iyz")) biyz = el->FindElementValueAsNumberConvertTo("iyz", "SLUG*FT2"); - SetAircraftBaseInertias(FGMatrix33( bixx, -bixy, -bixz, + SetAircraftBaseInertias(FGMatrix33( bixx, -bixy, bixz, -bixy, biyy, -biyz, - -bixz, -biyz, bizz )); - EmptyWeight = el->FindElementValueAsNumberConvertTo("emptywt", "LBS"); + bixz, -biyz, bizz )); + if (el->FindElement("emptywt")) { + EmptyWeight = el->FindElementValueAsNumberConvertTo("emptywt", "LBS"); + } element = el->FindElement("location"); - while (element) { - element_name = element->GetAttributeValue("name"); - if (element_name == "CG") vbaseXYZcg = element->FindElementTripletConvertTo("IN"); - element = el->FindNextElement("location"); - } + while (element) { + element_name = element->GetAttributeValue("name"); + if (element_name == "CG") vbaseXYZcg = element->FindElementTripletConvertTo("IN"); + element = el->FindNextElement("location"); + } // Find all POINTMASS elements that descend from this METRICS branch of the // config file. @@ -119,29 +142,58 @@ bool FGMassBalance::Load(Element* el) element = el->FindNextElement("pointmass"); } + double ChildFDMWeight = 0.0; + for (int fdm=0; fdmGetFDMCount(); 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(el, PropertyManager); + Debug(2); return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGMassBalance::Run(void) +bool FGMassBalance::Run(bool Holding) { double denom, k1, k2, k3, k4, k5, k6; double Ixx, Iyy, Izz, Ixy, Ixz, Iyz; - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; + + RunPreFunctions(); + + double ChildFDMWeight = 0.0; + for (int fdm=0; fdmGetFDMCount(); fdm++) { + if (FDMExec->GetChildFDM(fdm)->mated) ChildFDMWeight += FDMExec->GetChildFDM(fdm)->exec->GetMassBalance()->GetWeight(); + } - Weight = EmptyWeight + Propulsion->GetTanksWeight() + GetPointMassWeight(); + Weight = EmptyWeight + in.TanksWeight + GetTotalPointMassWeight() + + in.GasMass*slugtolb + ChildFDMWeight; Mass = lbtoslug*Weight; // Calculate new CG -// printf("%s:%i\n", __FILE__, __LINE__); - vXYZcg = (Propulsion->GetTanksMoment() + EmptyWeight*vbaseXYZcg - + GetPointMassMoment() ) / Weight; + 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 @@ -151,7 +203,8 @@ bool FGMassBalance::Run(void) mJ += GetPointmassInertia( lbtoslug * EmptyWeight, vbaseXYZcg ); // Then add the contributions from the additional pointmasses. mJ += CalculatePMInertias(); - mJ += Propulsion->CalculateTankInertias(); + mJ += in.TankInertia; + mJ += in.GasInertia; Ixx = mJ(1,1); Iyy = mJ(2,2); @@ -178,6 +231,8 @@ bool FGMassBalance::Run(void) k2, k4, k5, k3, k5, k6 ); + RunPostFunctions(); + Debug(0); return false; @@ -187,50 +242,80 @@ bool FGMassBalance::Run(void) void FGMassBalance::AddPointMass(Element* el) { + double radius=0, length=0; Element* loc_element = el->FindElement("location"); string pointmass_name = el->GetAttributeValue("name"); - if (!el) { - cerr << "Pointmass " << pointmass_name << "has no location." << endl; + if (!loc_element) { + cerr << "Pointmass " << pointmass_name << " has no location." << endl; exit(-1); } - string loc_unit = loc_element->GetAttributeValue("unit"); - double w, x, y, z; - w = el->FindElementValueAsNumberConvertTo("weight", "LBS"); - x = loc_element->FindElementValueAsNumberConvertTo("x", loc_unit); - y = loc_element->FindElementValueAsNumberConvertTo("y", loc_unit); - z = loc_element->FindElementValueAsNumberConvertTo("z", loc_unit); + double w = el->FindElementValueAsNumberConvertTo("weight", "LBS"); + FGColumnVector3 vXYZ = loc_element->FindElementTripletConvertTo("IN"); + + PointMass *pm = new PointMass(w, vXYZ); + pm->SetName(pointmass_name); + + Element* form_element = el->FindElement("form"); + if (form_element) { + string shape = form_element->GetAttributeValue("shape"); + Element* radius_element = form_element->FindElement("radius"); + Element* length_element = form_element->FindElement("length"); + if (radius_element) radius = form_element->FindElementValueAsNumberConvertTo("radius", "FT"); + if (length_element) length = form_element->FindElementValueAsNumberConvertTo("length", "FT"); + if (shape == "tube") { + pm->SetPointMassShapeType(PointMass::esTube); + pm->SetRadius(radius); + pm->SetLength(length); + pm->CalculateShapeInertia(); + } else if (shape == "cylinder") { + pm->SetPointMassShapeType(PointMass::esCylinder); + pm->SetRadius(radius); + pm->SetLength(length); + pm->CalculateShapeInertia(); + } else if (shape == "sphere") { + pm->SetPointMassShapeType(PointMass::esSphere); + pm->SetRadius(radius); + pm->CalculateShapeInertia(); + } else if (shape == "ball") { + pm->SetPointMassShapeType(PointMass::esBall); + pm->SetRadius(radius); + pm->CalculateShapeInertia(); + } else { + } + } - PointMasses.push_back(PointMass(w, x, y, z)); + pm->bind(PropertyManager, PointMasses.size()); + PointMasses.push_back(pm); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -double FGMassBalance::GetPointMassWeight(void) +double FGMassBalance::GetTotalPointMassWeight(void) const { double PM_total_weight = 0.0; for (unsigned int i=0; iWeight; } return PM_total_weight; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -FGColumnVector3& FGMassBalance::GetPointMassMoment(void) +const FGColumnVector3& FGMassBalance::GetPointMassMoment(void) { PointMassCG.InitMatrix(); for (unsigned int i=0; iWeight*PointMasses[i]->Location; } return PointMassCG; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -FGMatrix33& FGMassBalance::CalculatePMInertias(void) +const FGMatrix33& FGMassBalance::CalculatePMInertias(void) { unsigned int size; @@ -239,8 +324,10 @@ FGMatrix33& FGMassBalance::CalculatePMInertias(void) pmJ = FGMatrix33(); - for (unsigned int i=0; iWeight, PointMasses[i]->Location ); + pmJ += PointMasses[i]->GetPointMassInertia(); + } return pmJ; } @@ -287,23 +374,74 @@ void FGMassBalance::bind(void) &FGMassBalance::GetMass); PropertyManager->Tie("inertia/weight-lbs", this, &FGMassBalance::GetWeight); - PropertyManager->Tie("inertia/cg-x-ft", this,1, + PropertyManager->Tie("inertia/empty-weight-lbs", this, + &FGMassBalance::GetEmptyWeight); + PropertyManager->Tie("inertia/cg-x-in", this,1, (PMF)&FGMassBalance::GetXYZcg); - PropertyManager->Tie("inertia/cg-y-ft", this,2, + PropertyManager->Tie("inertia/cg-y-in", this,2, (PMF)&FGMassBalance::GetXYZcg); - PropertyManager->Tie("inertia/cg-z-ft", this,3, + PropertyManager->Tie("inertia/cg-z-in", this,3, (PMF)&FGMassBalance::GetXYZcg); } +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// +// This function binds properties for each pointmass object created. +// +void FGMassBalance::PointMass::bind(FGPropertyManager* PropertyManager, int num) { + string tmp = CreateIndexedPropertyName("inertia/pointmass-weight-lbs", num); + PropertyManager->Tie( tmp.c_str(), this, &PointMass::GetPointMassWeight, + &PointMass::SetPointMassWeight); + + tmp = CreateIndexedPropertyName("inertia/pointmass-location-X-inches", num); + PropertyManager->Tie( tmp.c_str(), this, eX, &PointMass::GetPointMassLocation, + &PointMass::SetPointMassLocation); + tmp = CreateIndexedPropertyName("inertia/pointmass-location-Y-inches", num); + PropertyManager->Tie( tmp.c_str(), this, eY, &PointMass::GetPointMassLocation, + &PointMass::SetPointMassLocation); + tmp = CreateIndexedPropertyName("inertia/pointmass-location-Z-inches", num); + PropertyManager->Tie( tmp.c_str(), this, eZ, &PointMass::GetPointMassLocation, + &PointMass::SetPointMassLocation); +} + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void FGMassBalance::unbind(void) +void FGMassBalance::GetMassPropertiesReport(void) const { - PropertyManager->Untie("inertia/mass-slugs"); - PropertyManager->Untie("inertia/weight-lbs"); - PropertyManager->Untie("inertia/cg-x-ft"); - PropertyManager->Untie("inertia/cg-y-ft"); - PropertyManager->Untie("inertia/cg-z-ft"); + cout << endl << fgblue << highint + << " Mass Properties Report (English units: lbf, in, slug-ft^2)" + << reset << endl; + cout << " " << underon << " Weight CG-X CG-Y" + << " CG-Z Ixx Iyy Izz" << underoff << endl; + cout.precision(1); + cout << highint << setw(34) << left << " Base Vehicle " << normint + << right << setw(10) << EmptyWeight << setw(8) << vbaseXYZcg(eX) << setw(8) + << vbaseXYZcg(eY) << setw(8) << vbaseXYZcg(eZ) << setw(12) << baseJ(1,1) + << setw(12) << baseJ(2,2) << setw(12) << baseJ(3,3) << endl; + + for (unsigned int i=0;iGetPointMassWeight(); + cout << highint << left << setw(4) << i << setw(30) << pm->GetName() << normint + << right << setw(10) << pmweight << setw(8) << pm->GetLocation()(eX) + << setw(8) << pm->GetLocation()(eY) << setw(8) << pm->GetLocation()(eZ) + << setw(12) << pm->GetPointMassMoI(1,1) << setw(12) << pm->GetPointMassMoI(2,2) + << setw(12) << pm->GetPointMassMoI(3,3) << endl; + } + + cout << FDMExec->GetPropulsionTankReport(); + + cout << underon << setw(104) << " " << underoff << endl; + cout << highint << left << setw(30) << " Total: " << right << setw(14) << Weight + << setw(8) << vXYZcg(eX) + << setw(8) << vXYZcg(eY) + << setw(8) << vXYZcg(eZ) + << setw(12) << mJ(1,1) + << setw(12) << mJ(2,2) + << setw(12) << mJ(3,3) + << normint << endl; + + cout.setf(ios_base::fixed); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -338,14 +476,14 @@ void FGMassBalance::Debug(int from) cout << " baseIxy: " << baseJ(1,2) << " slug-ft2" << endl; cout << " baseIxz: " << baseJ(1,3) << " slug-ft2" << endl; cout << " baseIyz: " << baseJ(2,3) << " slug-ft2" << endl; - cout << " EmptyWeight: " << EmptyWeight << " lbm" << endl; + cout << " Empty Weight: " << EmptyWeight << " lbm" << endl; cout << " CG (x, y, z): " << vbaseXYZcg << endl; // ToDo: Need to add point mass outputs here - for (int i=0; iWeight << " lbs. at " + << "X, Y, Z (in.): " << PointMasses[i]->Location(eX) << " " + << PointMasses[i]->Location(eY) << " " + << PointMasses[i]->Location(eZ) << endl; } } }