From 01dd0a987d48a4c749e449ab5a757f93501198da Mon Sep 17 00:00:00 2001 From: Bertrand Coconnier Date: Fri, 30 Apr 2021 12:15:59 +0200 Subject: [PATCH] Sync'ed with JSBSim v1.1.5 - Lower the allowable minimum propeller inertia from 1e-3 to 1e-6 - Account for the vehicle angular rates in the computation of propellers local velocities. - Apply the engine torque to the vehicle (The aerodynamic torque was applied until now but it is the engine generated torque that the aircraft is actually submitted to) - Prevent FGPiston from sending negative powers to thrusters - Fixed FGMagnetometer : no need to update the magnetic field every time step. - FGMassBalance: remove a direct reference to FGGroundReactions --- src/FDM/JSBSim/FGFDMExec.cpp | 1 + src/FDM/JSBSim/models/FGMassBalance.cpp | 6 ++---- src/FDM/JSBSim/models/FGMassBalance.h | 2 +- .../models/atmosphere/FGStandardAtmosphere.h | 2 +- .../models/flight_control/FGMagnetometer.cpp | 11 ++++++++-- .../models/flight_control/FGMagnetometer.h | 1 + src/FDM/JSBSim/models/propulsion/FGForce.cpp | 7 +++---- src/FDM/JSBSim/models/propulsion/FGForce.h | 2 ++ src/FDM/JSBSim/models/propulsion/FGPiston.cpp | 5 ++++- .../JSBSim/models/propulsion/FGPropeller.cpp | 20 ++++++++++--------- 10 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp index 3402d417f..7470d4ad7 100644 --- a/src/FDM/JSBSim/FGFDMExec.cpp +++ b/src/FDM/JSBSim/FGFDMExec.cpp @@ -483,6 +483,7 @@ void FGFDMExec::LoadInputs(unsigned int idx) MassBalance->in.TanksWeight = Propulsion->GetTanksWeight(); MassBalance->in.TanksMoment = Propulsion->GetTanksMoment(); MassBalance->in.TankInertia = Propulsion->CalculateTankInertias(); + MassBalance->in.WOW = GroundReactions->GetWOW(); break; case eAircraft: Aircraft->in.AeroForce = Aerodynamics->GetForces(); diff --git a/src/FDM/JSBSim/models/FGMassBalance.cpp b/src/FDM/JSBSim/models/FGMassBalance.cpp index 48075e687..bc0c7d33b 100644 --- a/src/FDM/JSBSim/models/FGMassBalance.cpp +++ b/src/FDM/JSBSim/models/FGMassBalance.cpp @@ -42,7 +42,6 @@ INCLUDES #include "FGMassBalance.h" #include "FGFDMExec.h" -#include "FGGroundReactions.h" #include "input_output/FGXMLElement.h" using namespace std; @@ -55,7 +54,7 @@ CLASS IMPLEMENTATION FGMassBalance::FGMassBalance(FGFDMExec* fdmex) - : FGModel(fdmex), GroundReactions(nullptr) + : FGModel(fdmex) { Name = "FGMassBalance"; Weight = EmptyWeight = Mass = 0.0; @@ -90,7 +89,6 @@ bool FGMassBalance::InitModel(void) { if (!FGModel::InitModel()) return false; - GroundReactions = FDMExec->GetGroundReactions(); vLastXYZcg.InitMatrix(); vDeltaXYZcg.InitMatrix(); @@ -211,7 +209,7 @@ bool FGMassBalance::Run(bool Holding) // Compensate displacements of the structural frame when the mass distribution // is modified while the aircraft is in contact with the ground. - if (FDMExec->GetHoldDown() || GroundReactions->GetWOW()) + if (FDMExec->GetHoldDown() || in.WOW) Propagate->NudgeBodyLocation(vDeltaXYZcgBody); // Calculate new total moments of inertia diff --git a/src/FDM/JSBSim/models/FGMassBalance.h b/src/FDM/JSBSim/models/FGMassBalance.h index abb07ea53..2723c9325 100644 --- a/src/FDM/JSBSim/models/FGMassBalance.h +++ b/src/FDM/JSBSim/models/FGMassBalance.h @@ -188,11 +188,11 @@ public: FGMatrix33 GasInertia; FGColumnVector3 TanksMoment; FGMatrix33 TankInertia; + bool WOW; } in; private: FGPropagate* Propagate; - FGGroundReactions* GroundReactions; double Weight; double EmptyWeight; double Mass; diff --git a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h index 0edfd0cb6..0fb7b4d2e 100644 --- a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h +++ b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h @@ -101,7 +101,7 @@ public: FGStandardAtmosphere(FGFDMExec*); /// Destructor - ~FGStandardAtmosphere() override; + virtual ~FGStandardAtmosphere(); bool InitModel(void) override; diff --git a/src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp b/src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp index c2a6d892b..bee2e7b6e 100644 --- a/src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp @@ -100,12 +100,19 @@ FGMagnetometer::~FGMagnetometer() } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGMagnetometer::ResetPastStates(void) +{ + FGSensor::ResetPastStates(); + counter = 0; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + void FGMagnetometer::updateInertialMag(void) { if (counter++ % INERTIAL_UPDATE_RATE == 0)//dont need to update every iteration { - counter = 0; - usedLat = (Propagate->GetGeodLatitudeRad());//radians, N and E lat and long are positive, S and W negative usedLon = (Propagate->GetLongitude());//radians usedAlt = (Propagate->GetGeodeticAltitude()*fttom*0.001);//km diff --git a/src/FDM/JSBSim/models/flight_control/FGMagnetometer.h b/src/FDM/JSBSim/models/flight_control/FGMagnetometer.h index 2183ea7af..56f1cc30f 100644 --- a/src/FDM/JSBSim/models/flight_control/FGMagnetometer.h +++ b/src/FDM/JSBSim/models/flight_control/FGMagnetometer.h @@ -123,6 +123,7 @@ public: ~FGMagnetometer(); bool Run (void) override; + void ResetPastStates(void) override; private: FGPropagate* Propagate; diff --git a/src/FDM/JSBSim/models/propulsion/FGForce.cpp b/src/FDM/JSBSim/models/propulsion/FGForce.cpp index b26354345..9dba77b32 100644 --- a/src/FDM/JSBSim/models/propulsion/FGForce.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGForce.cpp @@ -50,9 +50,8 @@ namespace JSBSim { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -FGForce::FGForce(FGFDMExec *FDMExec) : - fdmex(FDMExec), - ttype(tNone) +FGForce::FGForce(FGFDMExec *FDMExec) + : fdmex(FDMExec), MassBalance(fdmex->GetMassBalance()), ttype(tNone) { vFn.InitMatrix(); vMn.InitMatrix(); @@ -87,7 +86,7 @@ const FGColumnVector3& FGForce::GetBodyForces(void) // needs to be done like this to convert from structural to body coords. // CG and RP values are in inches - FGColumnVector3 vDXYZ = fdmex->GetMassBalance()->StructuralToBody(vActingXYZn); + FGColumnVector3 vDXYZ = MassBalance->StructuralToBody(vActingXYZn); vM = vMn + vDXYZ*vFb; diff --git a/src/FDM/JSBSim/models/propulsion/FGForce.h b/src/FDM/JSBSim/models/propulsion/FGForce.h index 8ac10cc25..dd13bed5a 100644 --- a/src/FDM/JSBSim/models/propulsion/FGForce.h +++ b/src/FDM/JSBSim/models/propulsion/FGForce.h @@ -67,6 +67,7 @@ FORWARD DECLARATIONS namespace JSBSim { class FGFDMExec; +class FGMassBalance; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASS DOCUMENTATION @@ -305,6 +306,7 @@ public: protected: FGFDMExec *fdmex; + FGMassBalance* MassBalance; FGColumnVector3 vFn; FGColumnVector3 vMn; FGColumnVector3 vOrient; diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp index a7885ecc3..0a28c6d6f 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp @@ -518,7 +518,10 @@ void FGPiston::Calculate(void) } LoadThrusterInputs(); - Thruster->Calculate(HP * hptoftlbssec); + // Filters out negative powers. + // TODO: static_friction_HP should not be taken into account while the engine + // is not started. + Thruster->Calculate(max(HP * hptoftlbssec, 0.)); RunPostFunctions(); } diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp index ce2444e7e..08bdbf70e 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp @@ -41,6 +41,7 @@ INCLUDES #include "FGFDMExec.h" #include "FGPropeller.h" #include "input_output/FGXMLElement.h" +#include "models/FGMassBalance.h" using namespace std; @@ -50,11 +51,6 @@ namespace JSBSim { CLASS IMPLEMENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -// This class currently makes certain assumptions when calculating torque and -// p-factor. That is, that the axis of rotation is the X axis of the aircraft - -// not just the X-axis of the engine/propeller. This may or may not work for a -// helicopter. - FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num) : FGThruster(exec, prop_element, num) { @@ -75,7 +71,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num) Vinduced = 0.0; if (prop_element->FindElement("ixx")) - Ixx = max(prop_element->FindElementValueAsNumberConvertTo("ixx", "SLUG*FT2"), 0.001); + Ixx = max(prop_element->FindElementValueAsNumberConvertTo("ixx", "SLUG*FT2"), 1e-06); Sense_multiplier = 1.0; if (prop_element->HasAttribute("version") @@ -205,7 +201,13 @@ void FGPropeller::ResetToIC(void) double FGPropeller::Calculate(double EnginePower) { - FGColumnVector3 localAeroVel = Transform().Transposed() * in.AeroUVW; + FGColumnVector3 vDXYZ = MassBalance->StructuralToBody(vActingXYZn); + const FGMatrix33& mT = Transform(); + // Local air velocity is obtained from Stevens & Lewis' "Aircraft Control and + // Simualtion (3rd edition)" eqn 8.2-1 + // Variables in.AeroUVW and in.AeroPQR include the wind and turbulence effects + // as computed by FGAuxiliary. + FGColumnVector3 localAeroVel = mT.Transposed() * (in.AeroUVW + in.AeroPQR*vDXYZ); double omega, PowerAvailable; double Vel = localAeroVel(eU); @@ -268,6 +270,7 @@ double FGPropeller::Calculate(double EnginePower) omega = RPS*2.0*M_PI; vFn(eX) = Thrust; + vTorque(eX) = -Sense*EnginePower / max(0.01, omega); // The Ixx value and rotation speed given below are for rotation about the // natural axis of the engine. The transform takes place in the base class @@ -284,7 +287,7 @@ double FGPropeller::Calculate(double EnginePower) // Transform Torque and momentum first, as PQR is used in this // equation and cannot be transformed itself. - vMn = in.PQRi*(Transform()*vH) + Transform()*vTorque; + vMn = in.PQRi*(mT*vH) + mT*vTorque; return Thrust; // return thrust in pounds } @@ -354,7 +357,6 @@ double FGPropeller::GetPowerRequired(void) double local_RPS = RPS < 0.01 ? 0.01 : RPS; PowerRequired = cPReq*local_RPS*local_RPS*local_RPS*D5*in.Density; - vTorque(eX) = -Sense*PowerRequired / (local_RPS*2.0*M_PI); return PowerRequired; }