From 69905cc45b0e52d47886736cbfba095f54cecb4b Mon Sep 17 00:00:00 2001 From: Anders Gidenstam Date: Sun, 3 Jul 2011 22:05:57 +0200 Subject: [PATCH] Fixed faulty frame transformation of moment of inertia. Thanks to Jon for finding the problem. --- src/FDM/JSBSim/models/FGBuoyantForces.cpp | 15 ++------ src/FDM/JSBSim/models/FGBuoyantForces.h | 29 +++++++------- src/FDM/JSBSim/models/FGGasCell.cpp | 24 +++++------- src/FDM/JSBSim/models/FGGasCell.h | 47 ++++++++++++----------- 4 files changed, 52 insertions(+), 63 deletions(-) diff --git a/src/FDM/JSBSim/models/FGBuoyantForces.cpp b/src/FDM/JSBSim/models/FGBuoyantForces.cpp index 96fd81d67..a1824e7a0 100644 --- a/src/FDM/JSBSim/models/FGBuoyantForces.cpp +++ b/src/FDM/JSBSim/models/FGBuoyantForces.cpp @@ -5,7 +5,7 @@ Date started: 01/21/08 Purpose: Encapsulates the buoyant forces - ------------- Copyright (C) 2008 - 2010 Anders Gidenstam ------------- + ------------- Copyright (C) 2008 - 2011 Anders Gidenstam ------------- ------------- Copyright (C) 2008 Jon S. Berndt (jon@jsbsim.org) ------------- This program is free software; you can redistribute it and/or modify it under @@ -45,7 +45,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.17 2011/05/20 03:18:36 jberndt Exp $"; +static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.19 2011/07/01 21:22:25 andgi Exp $"; static const char *IdHdr = ID_BUOYANTFORCES; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -179,16 +179,7 @@ const FGMatrix33& FGBuoyantForces::GetGasMassInertia(void) gasCellJ = FGMatrix33(); for (unsigned int i=0; i < size; i++) { - FGColumnVector3 v = FDMExec->GetMassBalance()->StructuralToBody( Cells[i]->GetXYZ() ); - // Body basis is in FT. - const double mass = Cells[i]->GetMass(); - - // FIXME: Verify that this is the correct way to change between the - // coordinate frames. - gasCellJ += Cells[i]->GetInertia() + - FGMatrix33( 0, - mass*v(1)*v(2), - mass*v(1)*v(3), - - mass*v(2)*v(1), 0, - mass*v(2)*v(3), - - mass*v(3)*v(1), - mass*v(3)*v(2), 0 ); + gasCellJ += Cells[i]->GetInertia(); } return gasCellJ; diff --git a/src/FDM/JSBSim/models/FGBuoyantForces.h b/src/FDM/JSBSim/models/FGBuoyantForces.h index e3baab137..ac712e242 100644 --- a/src/FDM/JSBSim/models/FGBuoyantForces.h +++ b/src/FDM/JSBSim/models/FGBuoyantForces.h @@ -4,7 +4,7 @@ Author: Anders Gidenstam, Jon S. Berndt Date started: 01/21/08 - ------------- Copyright (C) 2008 - 2010 Anders Gidenstam ------------- + ------------- Copyright (C) 2008 - 2011 Anders Gidenstam ------------- ------------- Copyright (C) 2008 Jon S. Berndt (jon@jsbsim.org) ------------- This program is free software; you can redistribute it and/or modify it under @@ -51,7 +51,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_BUOYANTFORCES "$Id: FGBuoyantForces.h,v 1.12 2011/05/20 03:18:36 jberndt Exp $" +#define ID_BUOYANTFORCES "$Id: FGBuoyantForces.h,v 1.13 2011/07/01 21:22:25 andgi Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -96,7 +96,7 @@ CLASS DOCUMENTATION See FGGasCell for the full configuration file format for gas cells. @author Anders Gidenstam, Jon S. Berndt - @version $Id: FGBuoyantForces.h,v 1.12 2011/05/20 03:18:36 jberndt Exp $ + @version $Id: FGBuoyantForces.h,v 1.13 2011/07/01 21:22:25 andgi Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -132,19 +132,19 @@ public: bool Load(Element* element); /** Gets the total Buoyant force vector. - @return a force vector. */ + @return a force vector in lbs. */ const FGColumnVector3& GetForces(void) const {return vTotalForces;} /** Gets a component of the total Buoyant force vector. - @return a component of the force vector. */ + @return a component of the force vector in lbs. */ double GetForces(int idx) const {return vTotalForces(idx);} /** Gets the total Buoyancy moment vector. - @return a moment vector. */ + @return a moment vector in the body frame in lbs ft. */ const FGColumnVector3& GetMoments(void) const {return vTotalMoments;} /** Gets a component of the total Buoyancy moment vector. - @return a component of the moment vector. */ + @return a component of the moment vector in the body frame in lbs ft. */ double GetMoments(int idx) const {return vTotalMoments(idx);} /** Gets the total gas mass. The gas mass is part of the aircraft's @@ -153,11 +153,12 @@ public: double GetGasMass(void); /** Gets the total moment from the gas mass. - @return a moment vector. */ + @return a moment vector in the structural frame in lbs in. */ const FGColumnVector3& GetGasMassMoment(void); - /** Gets the total moments of inertia for the gas mass. - @return . */ + /** Gets the total moments of inertia for the gas mass in the body frame. + @return moments of inertia matrix in the body frame + in slug ft2. */ const FGMatrix33& GetGasMassInertia(void); /** Gets the strings for the current set of gas cells. @@ -174,13 +175,13 @@ public: private: vector Cells; // Buoyant forces and moments. Excluding the gas weight. - FGColumnVector3 vTotalForces; - FGColumnVector3 vTotalMoments; + FGColumnVector3 vTotalForces; // [lbs] + FGColumnVector3 vTotalMoments; // [lbs ft] // Gas mass related masses, inertias and moments. - FGMatrix33 gasCellJ; + FGMatrix33 gasCellJ; // [slug ft^2] FGColumnVector3 vGasCellXYZ; - FGColumnVector3 vXYZgasCell_arm; + FGColumnVector3 vXYZgasCell_arm; // [lbs in] bool NoneDefined; diff --git a/src/FDM/JSBSim/models/FGGasCell.cpp b/src/FDM/JSBSim/models/FGGasCell.cpp index bdab72172..742288cd6 100644 --- a/src/FDM/JSBSim/models/FGGasCell.cpp +++ b/src/FDM/JSBSim/models/FGGasCell.cpp @@ -4,7 +4,7 @@ Author: Anders Gidenstam Date started: 01/21/2006 - ----- Copyright (C) 2006 - 2008 Anders Gidenstam (anders(at)gidenstam.org) -- + ----- Copyright (C) 2006 - 2011 Anders Gidenstam (anders(at)gidenstam.org) -- This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -53,7 +53,7 @@ using std::max; namespace JSBSim { -static const char *IdSrc = "$Id: FGGasCell.cpp,v 1.13 2010/12/29 22:39:25 andgi Exp $"; +static const char *IdSrc = "$Id: FGGasCell.cpp,v 1.14 2011/07/01 21:22:25 andgi Exp $"; static const char *IdHdr = ID_GASCELL; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -405,6 +405,9 @@ void FGGasCell::Calculate(double dt) gasCellJ(2,2) = Iyy; gasCellJ(3,3) = Izz; Mass = mass; + // Transform the moments of inertia to the body frame. + gasCellJ += MassBalance->GetPointmassInertia(Mass, GetXYZ()); + gasCellM.InitMatrix(); gasCellM(eX) += GetXYZ(eX) * Mass*slugtolb; @@ -415,12 +418,10 @@ void FGGasCell::Calculate(double dt) if (no_ballonets > 0) { // Add the mass, moment and inertia of any ballonets. - const FGColumnVector3 p = MassBalance->StructuralToBody( GetXYZ() ); - for (i = 0; i < no_ballonets; i++) { Mass += Ballonet[i]->GetMass(); - // Add ballonet moments. + // Add ballonet moments due to mass (in the structural frame). gasCellM(eX) += Ballonet[i]->GetXYZ(eX) * Ballonet[i]->GetMass()*slugtolb; gasCellM(eY) += @@ -428,15 +429,7 @@ void FGGasCell::Calculate(double dt) gasCellM(eZ) += Ballonet[i]->GetXYZ(eZ) * Ballonet[i]->GetMass()*slugtolb; - // Moments of inertia must be converted to the gas cell frame here. - FGColumnVector3 v = - MassBalance->StructuralToBody( Ballonet[i]->GetXYZ() ) - p; - // Body basis is in FT. - const double mass = Ballonet[i]->GetMass(); - gasCellJ += Ballonet[i]->GetInertia() + - FGMatrix33( 0, - mass*v(1)*v(2), - mass*v(1)*v(3), - - mass*v(2)*v(1), 0, - mass*v(2)*v(3), - - mass*v(3)*v(1), - mass*v(3)*v(2), 0 ); + gasCellJ += Ballonet[i]->GetInertia(); } } } @@ -525,6 +518,7 @@ FGBallonet::FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent) Atmosphere = exec->GetAtmosphere(); PropertyManager = exec->GetPropertyManager(); Inertial = exec->GetInertial(); + MassBalance = exec->GetMassBalance(); ballonetJ = FGMatrix33(); @@ -791,6 +785,8 @@ void FGBallonet::Calculate(double dt) ballonetJ(1,1) = Ixx; ballonetJ(2,2) = Iyy; ballonetJ(3,3) = Izz; + // Transform the moments of inertia to the body frame. + ballonetJ += MassBalance->GetPointmassInertia(GetMass(), GetXYZ()); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/FGGasCell.h b/src/FDM/JSBSim/models/FGGasCell.h index de34fb670..abe73ac5b 100644 --- a/src/FDM/JSBSim/models/FGGasCell.h +++ b/src/FDM/JSBSim/models/FGGasCell.h @@ -4,7 +4,7 @@ Author: Anders Gidenstam Date started: 01/21/2006 - ----- Copyright (C) 2006 - 2008 Anders Gidenstam (anders(at)gidenstam.org) -- + ----- Copyright (C) 2006 - 2011 Anders Gidenstam (anders(at)gidenstam.org) -- This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -50,7 +50,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_GASCELL "$Id: FGGasCell.h,v 1.10 2009/10/24 22:59:30 jberndt Exp $" +#define ID_GASCELL "$Id: FGGasCell.h,v 1.11 2011/07/01 21:22:25 andgi Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -189,12 +189,12 @@ public: /** Get the center of gravity location of the gas cell (including any ballonets) - @return CoG location in the structural frame. */ + @return CoG location in the structural frame in inches. */ const FGColumnVector3& GetXYZ(void) const {return vXYZ;} /** Get the center of gravity location of the gas cell (including any ballonets) - @return CoG location in the structural frame. */ + @return CoG location in the structural frame in inches. */ double GetXYZ(int idx) const {return vXYZ(idx);} /** Get the current mass of the gas cell (including any ballonets) @@ -202,7 +202,7 @@ public: double GetMass(void) const {return Mass;} /** Get the moments of inertia of the gas cell (including any ballonets) - @return moments of inertia matrix relative the gas cell location + @return moments of inertia matrix in the body frame in slug ft2. */ const FGMatrix33& GetInertia(void) const {return gasCellJ;} @@ -210,7 +210,7 @@ public: Note that the buoyancy of the gas cell is handled separately by the FGForce part and not included here. - @return moment vector in lbs ft. */ + @return moment vector in the structural frame in lbs in. */ const FGColumnVector3& GetMassMoment(void) const {return gasCellM;} /** Get the current gas temperature inside the gas cell @@ -229,8 +229,8 @@ private: std::string type; int CellNum; // Structural constants - double MaxVolume; // [ft�] - double MaxOverpressure; // [lbs/ft�] + double MaxVolume; // [ft^2] + double MaxOverpressure; // [lbs/ft^2] FGColumnVector3 vXYZ; // [in] double Xradius, Yradius, Zradius; // [ft] double Xwidth, Ywidth, Zwidth; // [ft] @@ -240,17 +240,17 @@ private: typedef vector BallonetArray; BallonetArray Ballonet; // Variables - double Pressure; // [lbs/ft�] + double Pressure; // [lbs/ft^2] double Contents; // [mol] - double Volume; // [ft�] - double dVolumeIdeal; // [ft�] + double Volume; // [ft^2] + double dVolumeIdeal; // [ft^2] double Temperature; // [Rankine] double Buoyancy; // [lbs] Note: Gross lift. // Does not include the weight of the gas itself. double ValveOpen; // 0 <= ValveOpen <= 1 (or higher). double Mass; // [slug] - FGMatrix33 gasCellJ; // [slug foot�] - FGColumnVector3 gasCellM; // [lbs ft] + FGMatrix33 gasCellJ; // [slug foot^2] + FGColumnVector3 gasCellM; // [lbs in] FGAuxiliary* Auxiliary; FGAtmosphere* Atmosphere; @@ -295,7 +295,6 @@ private: //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /** Models a ballonet inside a gas cell. - Models a ballonet inside a gas cell. Not intended to be used outside FGGasCell. See FGGasCell for the configuration file format. @author Anders Gidenstam @@ -312,10 +311,10 @@ public: /** Get the center of gravity location of the ballonet - @return CoG location in the structural frame. */ + @return CoG location in the structural frame in inches. */ const FGColumnVector3& GetXYZ(void) const {return vXYZ;} /** Get the center of gravity location of the ballonet - @return CoG location in the structural frame. */ + @return CoG location in the structural frame in inches. */ double GetXYZ(int idx) const {return vXYZ(idx);} /** Get the current mass of the ballonets @@ -323,7 +322,8 @@ public: double GetMass(void) const {return Contents * M_air;} /** Get the moments of inertia of the ballonet - @return moments of inertia matrix in slug ft2. */ + @return moments of inertia matrix in the body frame in + slug ft2. */ const FGMatrix33& GetInertia(void) const {return ballonetJ;} /** Get the current volume of the ballonet @@ -336,8 +336,8 @@ public: private: int CellNum; // Structural constants - double MaxVolume; // [ft�] - double MaxOverpressure; // [lbs/ft�] + double MaxVolume; // [ft^2] + double MaxOverpressure; // [lbs/ft^2] FGColumnVector3 vXYZ; // [in] double Xradius, Yradius, Zradius; // [ft] double Xwidth, Ywidth, Zwidth; // [ft] @@ -347,19 +347,20 @@ private: FGFunction* BlowerInput; // [ft^3 / sec] FGGasCell* Parent; // Variables - double Pressure; // [lbs/ft�] + double Pressure; // [lbs/ft^2] double Contents; // [mol] - double Volume; // [ft�] - double dVolumeIdeal; // [ft�] + double Volume; // [ft^2] + double dVolumeIdeal; // [ft^2] double dU; // [lbs ft / sec] double Temperature; // [Rankine] double ValveOpen; // 0 <= ValveOpen <= 1 (or higher). - FGMatrix33 ballonetJ; // [slug foot�] + FGMatrix33 ballonetJ; // [slug foot^2] FGAuxiliary* Auxiliary; FGAtmosphere* Atmosphere; FGPropertyManager* PropertyManager; FGInertial* Inertial; + FGMassBalance* MassBalance; void Debug(int from); /* Constants. */