]> git.mxchange.org Git - flightgear.git/commitdiff
Sync. with JSBSim (CVS) again
authorehofman <ehofman>
Sat, 5 Sep 2009 12:22:54 +0000 (12:22 +0000)
committerTim Moore <timoore@redhat.com>
Wed, 9 Sep 2009 06:56:31 +0000 (08:56 +0200)
src/FDM/JSBSim/FGJSBBase.h
src/FDM/JSBSim/models/FGAtmosphere.cpp
src/FDM/JSBSim/models/FGAtmosphere.h
src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp [new file with mode: 0755]
src/FDM/JSBSim/models/flight_control/FGMagnetometer.h [new file with mode: 0755]
src/FDM/JSBSim/models/flight_control/Makefile.am
src/FDM/JSBSim/models/propulsion/FGPiston.cpp

index e8b60b6d493a3b3ddb7abc7589a77bccc48c1874..6ed8832f87347b54833fda6503854d60082b316c 100644 (file)
@@ -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;
index b8946ac47af84b5f86b60cdfeedef2c5bb653778..b1826b716083cf929fabffa0fe36b9c6906a547d 100644 (file)
@@ -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,
index fef92c7b6974ef0d1e0068a36ba4d5b25bd3fbd6..bd550246e378d6cff2f46dec7a617b852e4be7f6 100644 (file)
@@ -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 (executable)
index 0000000..561e0dc
--- /dev/null
@@ -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 <ctime>
+
+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 (executable)
index 0000000..456d14d
--- /dev/null
@@ -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 <input_output/FGXMLElement.h>
+#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
+<magnetometer name="name">
+  <input> property </input>
+  <lag> number </lag>
+  <noise variation="PERCENT|ABSOLUTE"> number </noise>
+  <quantization name="name">
+    <bits> number </bits>
+    <min> number </min>
+    <max> number </max>
+  </quantization>
+  <drift_rate> number </drift_rate>
+  <bias> number </bias>
+  <gain> number </gain>
+</magnetometer>
+@endcode
+
+Example:
+
+@code
+<magnetometer name="aero/magnetometer/qbar">
+  <input> aero/qbar </input>
+  <lag> 0.5 </lag>
+  <noise variation="PERCENT"> 2 </noise>
+  <quantization name="aero/magnetometer/quantized/qbar">
+    <bits> 12 </bits>
+    <min> 0 </min>
+    <max> 400 </max>
+  </quantization>
+  <bias> 0.5 </bias>
+  <gain> 0.5 </gain>
+</magnetometer>
+@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
index ca5c43ff965a75837794c984d52348aea675d511..ca924fdd9d712c7237354a36c4765c8144e22868 100644 (file)
@@ -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
index 23c62efe5005abe546ebfb0aac8f96a99aa2b1e8..19150d4bbb2b31bd250078e5917d721e3a16133d 100644 (file)
@@ -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");