diff --git a/src/FDM/JSBSim/FGJSBBase.h b/src/FDM/JSBSim/FGJSBBase.h index e8b60b6d4..6ed8832f8 100644 --- a/src/FDM/JSBSim/FGJSBBase.h +++ b/src/FDM/JSBSim/FGJSBBase.h @@ -349,9 +349,9 @@ protected: static int phase = 0; double X; - V1 = V2 = S = X = 0.0; - if (phase == 0) { + V1 = V2 = S = X = 0.0; + do { double U1 = (double)rand() / RAND_MAX; double U2 = (double)rand() / RAND_MAX; diff --git a/src/FDM/JSBSim/models/FGAtmosphere.cpp b/src/FDM/JSBSim/models/FGAtmosphere.cpp index b8946ac47..b1826b716 100644 --- a/src/FDM/JSBSim/models/FGAtmosphere.cpp +++ b/src/FDM/JSBSim/models/FGAtmosphere.cpp @@ -82,8 +82,8 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex) MagnitudedAccelDt = MagnitudeAccel = Magnitude = 0.0; // SetTurbType( ttCulp ); SetTurbType( ttNone ); - TurbGain = 0.0; - TurbRate = 1.7; + TurbGain = 1.0; + TurbRate = 10.0; Rhythmicity = 0.1; spike = target_time = strength = 0.0; wind_from_clockwise = 0.0; @@ -375,9 +375,11 @@ void FGAtmosphere::SetWindPsi(double dir) void FGAtmosphere::Turbulence(void) { + double DeltaT = rate*State->Getdt(); + switch (turbType) { case ttStandard: { - TurbGain = TurbGain * TurbGain * 100.0; + // TurbGain = TurbGain * TurbGain * 100.0; // what is this!? vDirectiondAccelDt(eX) = 1 - 2.0*(double(rand())/double(RAND_MAX)); vDirectiondAccelDt(eY) = 1 - 2.0*(double(rand())/double(RAND_MAX)); @@ -388,8 +390,8 @@ void FGAtmosphere::Turbulence(void) // away from the peaks MagnitudedAccelDt = ((MagnitudedAccelDt - Magnitude) / (1 + fabs(Magnitude))); - MagnitudeAccel += MagnitudedAccelDt*rate*TurbRate*State->Getdt(); - Magnitude += MagnitudeAccel*rate*State->Getdt(); + MagnitudeAccel += MagnitudedAccelDt*TurbRate*DeltaT; + Magnitude += MagnitudeAccel*DeltaT; Magnitude = fabs(Magnitude); vDirectiondAccelDt.Normalize(); @@ -398,9 +400,9 @@ void FGAtmosphere::Turbulence(void) vDirectiondAccelDt(eX) = square_signed(vDirectiondAccelDt(eX)); vDirectiondAccelDt(eY) = square_signed(vDirectiondAccelDt(eY)); - vDirectionAccel += vDirectiondAccelDt*rate*TurbRate*State->Getdt(); + vDirectionAccel += vDirectiondAccelDt*TurbRate*DeltaT; vDirectionAccel.Normalize(); - vDirection += vDirectionAccel*rate*State->Getdt(); + vDirection += vDirectionAccel*DeltaT; vDirection.Normalize(); @@ -449,42 +451,37 @@ void FGAtmosphere::Turbulence(void) } case ttBerndt: { // This is very experimental and incomplete at the moment. - TurbGain = TurbGain * TurbGain * 100.0; - - vDirectiondAccelDt(eX) = 1 - 2.0*(double(rand())/double(RAND_MAX)); - vDirectiondAccelDt(eY) = 1 - 2.0*(double(rand())/double(RAND_MAX)); - vDirectiondAccelDt(eZ) = 1 - 2.0*(double(rand())/double(RAND_MAX)); + vDirectiondAccelDt(eX) = GaussianRandomNumber(); + vDirectiondAccelDt(eY) = GaussianRandomNumber(); + vDirectiondAccelDt(eZ) = GaussianRandomNumber(); - - MagnitudedAccelDt = 1 - 2.0*(double(rand())/double(RAND_MAX)) - Magnitude; - MagnitudeAccel += MagnitudedAccelDt*rate*State->Getdt(); - Magnitude += MagnitudeAccel*rate*State->Getdt(); + MagnitudedAccelDt = GaussianRandomNumber(); + MagnitudeAccel += MagnitudedAccelDt * DeltaT; + Magnitude += MagnitudeAccel * DeltaT; vDirectiondAccelDt.Normalize(); - vDirectionAccel += vDirectiondAccelDt*rate*State->Getdt(); + vDirectionAccel += TurbRate * vDirectiondAccelDt * DeltaT; vDirectionAccel.Normalize(); - vDirection += vDirectionAccel*rate*State->Getdt(); + vDirection += vDirectionAccel*DeltaT; - // Diminish z-vector within two wingspans - // of the ground + // Diminish z-vector within two wingspans of the ground double HOverBMAC = Auxiliary->GetHOverBMAC(); - if (HOverBMAC < 2.0) - vDirection(eZ) *= HOverBMAC / 2.0; + if (HOverBMAC < 2.0) vDirection(eZ) *= HOverBMAC / 2.0; vDirection.Normalize(); vTurbulenceNED = TurbGain*Magnitude * vDirection; vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection; - vBodyTurbGrad = Propagate->GetTl2b()*vTurbulenceGrad; - vTurbPQR(eP) = vBodyTurbGrad(eY)/Aircraft->GetWingSpan(); + vBodyTurbGrad = Propagate->GetTl2b() * vTurbulenceGrad; + vTurbPQR(eP) = vBodyTurbGrad(eY) / Aircraft->GetWingSpan(); if (Aircraft->GetHTailArm() > 0) - vTurbPQR(eQ) = vBodyTurbGrad(eZ)/Aircraft->GetHTailArm(); + vTurbPQR(eQ) = vBodyTurbGrad(eZ) / Aircraft->GetHTailArm(); else - vTurbPQR(eQ) = vBodyTurbGrad(eZ)/10.0; + vTurbPQR(eQ) = vBodyTurbGrad(eZ) / 10.0; if (Aircraft->GetVTailArm() > 0) - vTurbPQR(eR) = vBodyTurbGrad(eX)/Aircraft->GetVTailArm(); + vTurbPQR(eR) = vBodyTurbGrad(eX) / Aircraft->GetVTailArm(); else vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0; @@ -571,7 +568,9 @@ void FGAtmosphere::bind(void) { typedef double (FGAtmosphere::*PMF)(int) const; typedef double (FGAtmosphere::*PMFv)(void) const; + typedef int (FGAtmosphere::*PMFt)(void) const; typedef void (FGAtmosphere::*PMFd)(int,double); + typedef void (FGAtmosphere::*PMFi)(int); PropertyManager->Tie("atmosphere/T-R", this, (PMFv)&FGAtmosphere::GetTemperature); PropertyManager->Tie("atmosphere/rho-slugs_ft3", this, (PMFv)&FGAtmosphere::GetDensity); PropertyManager->Tie("atmosphere/P-psf", this, (PMFv)&FGAtmosphere::GetPressure); @@ -608,9 +607,17 @@ void FGAtmosphere::bind(void) PropertyManager->Tie("atmosphere/gust-down-fps", this, eDown, (PMF)&FGAtmosphere::GetGustNED, (PMFd)&FGAtmosphere::SetGustNED); + PropertyManager->Tie("atmosphere/turb-north-fps", this, eNorth, (PMF)&FGAtmosphere::GetTurbNED, + (PMFd)&FGAtmosphere::SetTurbNED); + PropertyManager->Tie("atmosphere/turb-east-fps", this, eEast, (PMF)&FGAtmosphere::GetTurbNED, + (PMFd)&FGAtmosphere::SetTurbNED); + PropertyManager->Tie("atmosphere/turb-down-fps", this, eDown, (PMF)&FGAtmosphere::GetTurbNED, + (PMFd)&FGAtmosphere::SetTurbNED); + PropertyManager->Tie("atmosphere/p-turb-rad_sec", this,1, (PMF)&FGAtmosphere::GetTurbPQR); PropertyManager->Tie("atmosphere/q-turb-rad_sec", this,2, (PMF)&FGAtmosphere::GetTurbPQR); PropertyManager->Tie("atmosphere/r-turb-rad_sec", this,3, (PMF)&FGAtmosphere::GetTurbPQR); + PropertyManager->Tie("atmosphere/turb-type", this, (PMFt)&FGAtmosphere::GetTurbType, (PMFi)&FGAtmosphere::SetTurbType); PropertyManager->Tie("atmosphere/turb-rate", this, &FGAtmosphere::GetTurbRate, &FGAtmosphere::SetTurbRate); PropertyManager->Tie("atmosphere/turb-gain", this, &FGAtmosphere::GetTurbGain, &FGAtmosphere::SetTurbGain); PropertyManager->Tie("atmosphere/turb-rhythmicity", this, &FGAtmosphere::GetRhythmicity, diff --git a/src/FDM/JSBSim/models/FGAtmosphere.h b/src/FDM/JSBSim/models/FGAtmosphere.h index fef92c7b6..bd550246e 100644 --- a/src/FDM/JSBSim/models/FGAtmosphere.h +++ b/src/FDM/JSBSim/models/FGAtmosphere.h @@ -83,7 +83,7 @@ public: @return false if no error */ bool Run(void); bool InitModel(void); - enum tType {ttStandard, ttBerndt, ttCulp, ttNone} turbType; + enum tType {ttNone, ttStandard, ttBerndt, ttCulp} turbType; /// Returns the temperature in degrees Rankine. double GetTemperature(void) const {return *temperature;} @@ -194,16 +194,22 @@ public: /// Sets a gust component in NED frame. void SetGustNED(int idx, double gust) { vGustNED(idx)=gust;} + /// Sets a turbulence component in NED frame. + void SetTurbNED(int idx, double turb) { vTurbulenceNED(idx)=turb;} + /// Sets the gust components in NED frame. void SetGustNED(double gN, double gE, double gD) { vGustNED(eNorth)=gN; vGustNED(eEast)=gE; vGustNED(eDown)=gD;} /// Retrieves a gust component in NED frame. double GetGustNED(int idx) const {return vGustNED(idx);} + /// Retrieves a turbulence component in NED frame. + double GetTurbNED(int idx) const {return vTurbulenceNED(idx);} + /// Retrieves the gust components in NED frame. FGColumnVector3& GetGustNED(void) {return vGustNED;} - /** Turbulence models available: ttStandard, ttBerndt, ttCulp, ttNone */ + /** Turbulence models available: ttNone, ttStandard, ttBerndt, ttCulp */ void SetTurbType(tType tt) {turbType = tt;} tType GetTurbType() const {return turbType;} diff --git a/src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp b/src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp new file mode 100755 index 000000000..561e0dcca --- /dev/null +++ b/src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp @@ -0,0 +1,254 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Module: FGMagnetometer.cpp + Author: Matthew Chave + Date started: August 2009 + + ------------- Copyright (C) 2009 ------------- + + 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 + 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 Lesser General Public License for more + details. + + 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 Lesser General Public License can also be found on + the world wide web at http://www.gnu.org. + +FUNCTIONAL DESCRIPTION +-------------------------------------------------------------------------------- + +HISTORY +-------------------------------------------------------------------------------- + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +COMMENTS, REFERENCES, and NOTES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +INCLUDES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#include "FGMagnetometer.h" +#include "simgear/magvar/coremag.hxx" +#include + +namespace JSBSim { + +static const char *IdSrc = "$Id$"; +static const char *IdHdr = ID_MAGNETOMETER; + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS IMPLEMENTATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + + +FGMagnetometer::FGMagnetometer(FGFCS* fcs, Element* element) : FGSensor(fcs, element),\ + counter(0), + INERTIAL_UPDATE_RATE(1000) +{ + Propagate = fcs->GetExec()->GetPropagate(); + MassBalance = fcs->GetExec()->GetMassBalance(); + Inertial = fcs->GetExec()->GetInertial(); + + Element* location_element = element->FindElement("location"); + if (location_element) vLocation = location_element->FindElementTripletConvertTo("IN"); + else {cerr << "No location given for magnetometer. " << endl; exit(-1);} + + vRadius = MassBalance->StructuralToBody(vLocation); + + Element* orient_element = element->FindElement("orientation"); + if (orient_element) vOrient = orient_element->FindElementTripletConvertTo("RAD"); + else {cerr << "No orientation given for magnetometer. " << endl;} + + Element* axis_element = element->FindElement("axis"); + if (axis_element) { + string sAxis = element->FindElementValue("axis"); + if (sAxis == "X" || sAxis == "x") { + axis = 1; + } else if (sAxis == "Y" || sAxis == "y") { + axis = 2; + } else if (sAxis == "Z" || sAxis == "z") { + axis = 3; + } else { + cerr << " Incorrect/no axis specified for magnetometer; assuming X axis" << endl; + axis = 1; + } + } + + CalculateTransformMatrix(); + + //assuming date wont significantly change over a flight to affect mag field + //would be better to get the date from the sim if its simulated... + time_t rawtime; + time( &rawtime ); + tm * ptm = gmtime ( &rawtime ); + + int year = ptm->tm_year; + if(year>100) + { + year-= 100; + } + //the months here are zero based TODO find out if the function expects 1s based + date = (yymmdd_to_julian_days(ptm->tm_year,ptm->tm_mon,ptm->tm_mday));//Julian 1950-2049 yy,mm,dd + updateInertialMag(); + + Debug(0); +} +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FGMagnetometer::~FGMagnetometer() +{ + Debug(1); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +void FGMagnetometer::updateInertialMag(void) +{ + counter++; + if(counter > INERTIAL_UPDATE_RATE)//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 + + //this should be done whenever the position changes significantly (in nTesla) + double magvar = calc_magvar( usedLat, + usedLon, + usedAlt, + date, + field ); + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +bool FGMagnetometer::Run(void ) +{ + // There is no input assumed. This is a dedicated acceleration sensor. + + vRadius = MassBalance->StructuralToBody(vLocation); + + + updateInertialMag(); + //Inertial magnetic field rotated to the body frame + vMag = Propagate->GetTl2b() * FGColumnVector3(field[3], field[4], field[5]); + + //allow for sensor orientation + vMag = mT * vMag; + + Input = vMag(axis); + + Output = Input; // perfect magnetometer + + // Degrade signal as specified + + if (fail_stuck) { + Output = PreviousOutput; + return true; + } + + if (lag != 0.0) Lag(); // models magnetometer lag + if (noise_variance != 0.0) Noise(); // models noise + if (drift_rate != 0.0) Drift(); // models drift over time + if (bias != 0.0) Bias(); // models a finite bias + if (gain != 0.0) Gain(); // models a gain + + if (fail_low) Output = -HUGE_VAL; + if (fail_high) Output = HUGE_VAL; + + if (bits != 0) Quantize(); // models quantization degradation +// if (delay != 0.0) Delay(); // models system signal transport latencies + + Clip(); // Is it right to clip an magnetometer? + return true; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGMagnetometer::CalculateTransformMatrix(void) +{ + double cp,sp,cr,sr,cy,sy; + + cp=cos(vOrient(ePitch)); sp=sin(vOrient(ePitch)); + cr=cos(vOrient(eRoll)); sr=sin(vOrient(eRoll)); + cy=cos(vOrient(eYaw)); sy=sin(vOrient(eYaw)); + + + mT(1,1) = cp*cy; + mT(1,2) = cp*sy; + mT(1,3) = -sp; + + mT(2,1) = sr*sp*cy - cr*sy; + mT(2,2) = sr*sp*sy + cr*cy; + mT(2,3) = sr*cp; + + mT(3,1) = cr*sp*cy + sr*sy; + mT(3,2) = cr*sp*sy - sr*cy; + mT(3,3) = cr*cp; + + + // This transform is different than for FGForce, where we want a native nozzle + // force in body frame. Here we calculate the body frame accel and want it in + // the transformed magnetometer frame. So, the next line is commented out. + // mT = mT.Inverse(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// The bitmasked value choices are as follows: +// unset: In this case (the default) JSBSim would only print +// out the normally expected messages, essentially echoing +// the config files as they are read. If the environment +// variable is not set, debug_lvl is set to 1 internally +// 0: This requests JSBSim not to output any messages +// whatsoever. +// 1: This value explicity requests the normal JSBSim +// startup messages +// 2: This value asks for a message to be printed out when +// a class is instantiated +// 4: When this value is set, a message is displayed when a +// FGModel object executes its Run() method +// 8: When this value is set, various runtime state variables +// are printed out periodically +// 16: When set various parameters are sanity checked and +// a message is printed out when they go out of bounds + +void FGMagnetometer::Debug(int from) +{ + string ax[4] = {"none", "X", "Y", "Z"}; + + if (debug_lvl <= 0) return; + + if (debug_lvl & 1) { // Standard console startup message output + if (from == 0) { // Constructor + cout << " Axis: " << ax[axis] << endl; + } + } + if (debug_lvl & 2 ) { // Instantiation/Destruction notification + if (from == 0) cout << "Instantiated: FGMagnetometer" << endl; + if (from == 1) cout << "Destroyed: FGMagnetometer" << endl; + } + if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects + } + if (debug_lvl & 8 ) { // Runtime state variables + } + if (debug_lvl & 16) { // Sanity checking + } + if (debug_lvl & 64) { + if (from == 0) { // Constructor + cout << IdSrc << endl; + cout << IdHdr << endl; + } + } +} +} diff --git a/src/FDM/JSBSim/models/flight_control/FGMagnetometer.h b/src/FDM/JSBSim/models/flight_control/FGMagnetometer.h new file mode 100755 index 000000000..456d14d6d --- /dev/null +++ b/src/FDM/JSBSim/models/flight_control/FGMagnetometer.h @@ -0,0 +1,152 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Header: FGMagnetometer.h + Author: Matthew Chave + Date started: August 2009 + + ------------- Copyright (C) 2009 ------------- + + 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 + 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 Lesser General Public License for more + details. + + 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 Lesser General Public License can also be found on + the world wide web at http://www.gnu.org. + +HISTORY +-------------------------------------------------------------------------------- + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +SENTRY +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#ifndef FGMAGNETOMETER_H +#define FGMAGNETOMETER_H + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +INCLUDES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#include "FGSensor.h" +#include +#include "models/FGPropagate.h" +#include "models/FGMassBalance.h" +#include "models/FGInertial.h" +#include "math/FGColumnVector3.h" +#include "math/FGMatrix33.h" + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +DEFINITIONS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#define ID_MAGNETOMETER "$Id$" + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +FORWARD DECLARATIONS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +namespace JSBSim { + +class FGFCS; + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS DOCUMENTATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +/** Encapsulates a magnetometer component for the flight control system. + +Syntax: + +@code + + property + number + number + + number + number + number + + number + number + number + +@endcode + +Example: + +@code + + aero/qbar + 0.5 + 2 + + 12 + 0 + 400 + + 0.5 + 0.5 + +@endcode + +The only required element in the magnetometer definition is the input element. In that +case, no degradation would be modeled, and the output would simply be the input. + +For noise, if the type is PERCENT, then the value supplied is understood to be a +percentage variance. That is, if the number given is 0.05, the the variance is +understood to be +/-0.05 percent maximum variance. So, the actual value for the magnetometer +will be *anywhere* from 0.95 to 1.05 of the actual "perfect" value at any time - +even varying all the way from 0.95 to 1.05 in adjacent frames - whatever the delta +time. + +@author Jon S. Berndt +@version $Revision$ +*/ + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS DECLARATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +class FGMagnetometer : public FGSensor +{ +public: + FGMagnetometer(FGFCS* fcs, Element* element); + ~FGMagnetometer(); + + bool Run (void); + +private: + FGPropagate* Propagate; + FGMassBalance* MassBalance; + FGInertial* Inertial; + FGColumnVector3 vLocation; + FGColumnVector3 vOrient; + FGColumnVector3 vRadius; + FGColumnVector3 vMag; + FGMatrix33 mT; + void CalculateTransformMatrix(void); + void updateInertialMag(void); + int axis; + double field[6]; + double usedLat; + double usedLon; + double usedAlt; + unsigned long int date; + int counter; + int INERTIAL_UPDATE_RATE; + + void Debug(int from); +}; +} +#endif diff --git a/src/FDM/JSBSim/models/flight_control/Makefile.am b/src/FDM/JSBSim/models/flight_control/Makefile.am index ca5c43ff9..ca924fdd9 100644 --- a/src/FDM/JSBSim/models/flight_control/Makefile.am +++ b/src/FDM/JSBSim/models/flight_control/Makefile.am @@ -1,12 +1,14 @@ noinst_LIBRARIES = libFlightControl.a -libFlightControl_a_SOURCES = FGPID.cpp FGDeadBand.cpp FGFCSComponent.cpp \ - FGFilter.cpp FGGain.cpp FGGradient.cpp FGKinemat.cpp \ - FGSummer.cpp FGSwitch.cpp FGFCSFunction.cpp FGSensor.cpp \ - FGActuator.cpp FGAccelerometer.cpp FGGyro.cpp +libFlightControl_a_SOURCES = \ + FGPID.cpp FGDeadBand.cpp FGFCSComponent.cpp \ + FGFilter.cpp FGGain.cpp FGGradient.cpp FGKinemat.cpp \ + FGSummer.cpp FGSwitch.cpp FGFCSFunction.cpp FGSensor.cpp \ + FGActuator.cpp FGAccelerometer.cpp FGGyro.cpp FGMagnetometer.cpp -noinst_HEADERS = FGPID.h FGDeadBand.h FGFCSComponent.h FGFilter.h \ - FGGain.h FGGradient.h FGKinemat.h FGSummer.h FGSwitch.h FGFCSFunction.h \ - FGSensor.h FGActuator.h FGAccelerometer.h FGGyro.h +noinst_HEADERS = \ + FGPID.h FGDeadBand.h FGFCSComponent.h FGFilter.h \ + FGGain.h FGGradient.h FGKinemat.h FGSummer.h FGSwitch.h FGFCSFunction.h\ + FGSensor.h FGActuator.h FGAccelerometer.h FGGyro.h FGMagnetometer.h INCLUDES = -I$(top_srcdir)/src/FDM/JSBSim diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp index 23c62efe5..19150d4bb 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp @@ -185,7 +185,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) Bore = el->FindElementValueAsNumberConvertTo("bore","IN"); if (el->FindElement("stroke")) Stroke = el->FindElementValueAsNumberConvertTo("stroke","IN"); - if (el->FindElement("stroke")) + if (el->FindElement("cylinders")) Cylinders = el->FindElementValueAsNumber("cylinders"); if (el->FindElement("numboostspeeds")) { // Turbo- and super-charging parameters BoostSpeeds = (int)el->FindElementValueAsNumber("numboostspeeds");