]> git.mxchange.org Git - flightgear.git/commitdiff
sync. with JSBSim CVS again
authorehofman <ehofman>
Mon, 12 Oct 2009 07:24:41 +0000 (07:24 +0000)
committerTim Moore <timoore@redhat.com>
Tue, 13 Oct 2009 22:40:44 +0000 (00:40 +0200)
108 files changed:
src/FDM/JSBSim/FGFDMExec.cpp
src/FDM/JSBSim/FGFDMExec.h
src/FDM/JSBSim/FGState.h
src/FDM/JSBSim/initialization/FGInitialCondition.cpp
src/FDM/JSBSim/initialization/FGInitialCondition.h
src/FDM/JSBSim/initialization/FGTrim.cpp
src/FDM/JSBSim/initialization/FGTrimAxis.cpp
src/FDM/JSBSim/input_output/FGGroundCallback.cpp
src/FDM/JSBSim/input_output/FGGroundCallback.h
src/FDM/JSBSim/input_output/FGPropertyManager.h
src/FDM/JSBSim/input_output/FGScript.cpp
src/FDM/JSBSim/input_output/FGScript.h
src/FDM/JSBSim/input_output/FGXMLElement.cpp
src/FDM/JSBSim/input_output/FGXMLElement.h
src/FDM/JSBSim/input_output/FGXMLFileRead.h
src/FDM/JSBSim/math/FGCondition.h
src/FDM/JSBSim/math/FGFunction.cpp
src/FDM/JSBSim/math/FGFunction.h
src/FDM/JSBSim/math/FGLocation.cpp
src/FDM/JSBSim/math/FGLocation.h
src/FDM/JSBSim/math/FGPropertyValue.h
src/FDM/JSBSim/math/FGQuaternion.h
src/FDM/JSBSim/math/FGTable.cpp
src/FDM/JSBSim/math/FGTable.h
src/FDM/JSBSim/models/FGAerodynamics.cpp
src/FDM/JSBSim/models/FGAerodynamics.h
src/FDM/JSBSim/models/FGAircraft.cpp
src/FDM/JSBSim/models/FGAircraft.h
src/FDM/JSBSim/models/FGAtmosphere.cpp
src/FDM/JSBSim/models/FGAtmosphere.h
src/FDM/JSBSim/models/FGAuxiliary.cpp
src/FDM/JSBSim/models/FGAuxiliary.h
src/FDM/JSBSim/models/FGBuoyantForces.cpp
src/FDM/JSBSim/models/FGBuoyantForces.h
src/FDM/JSBSim/models/FGExternalForce.h
src/FDM/JSBSim/models/FGExternalReactions.h
src/FDM/JSBSim/models/FGFCS.cpp
src/FDM/JSBSim/models/FGFCS.h
src/FDM/JSBSim/models/FGGasCell.cpp
src/FDM/JSBSim/models/FGGasCell.h
src/FDM/JSBSim/models/FGGroundReactions.cpp
src/FDM/JSBSim/models/FGGroundReactions.h
src/FDM/JSBSim/models/FGInertial.cpp
src/FDM/JSBSim/models/FGInertial.h
src/FDM/JSBSim/models/FGInput.cpp
src/FDM/JSBSim/models/FGInput.h
src/FDM/JSBSim/models/FGLGear.cpp
src/FDM/JSBSim/models/FGLGear.h
src/FDM/JSBSim/models/FGMassBalance.cpp
src/FDM/JSBSim/models/FGMassBalance.h
src/FDM/JSBSim/models/FGModel.h
src/FDM/JSBSim/models/FGOutput.cpp
src/FDM/JSBSim/models/FGPropagate.cpp
src/FDM/JSBSim/models/FGPropagate.h
src/FDM/JSBSim/models/FGPropulsion.cpp
src/FDM/JSBSim/models/FGPropulsion.h
src/FDM/JSBSim/models/atmosphere/FGMSIS.h
src/FDM/JSBSim/models/atmosphere/FGMars.h
src/FDM/JSBSim/models/flight_control/FGAccelerometer.cpp
src/FDM/JSBSim/models/flight_control/FGAccelerometer.h
src/FDM/JSBSim/models/flight_control/FGActuator.cpp
src/FDM/JSBSim/models/flight_control/FGActuator.h
src/FDM/JSBSim/models/flight_control/FGDeadBand.cpp
src/FDM/JSBSim/models/flight_control/FGDeadBand.h
src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp
src/FDM/JSBSim/models/flight_control/FGFCSComponent.h
src/FDM/JSBSim/models/flight_control/FGFCSFunction.cpp
src/FDM/JSBSim/models/flight_control/FGFCSFunction.h
src/FDM/JSBSim/models/flight_control/FGFilter.cpp
src/FDM/JSBSim/models/flight_control/FGFilter.h
src/FDM/JSBSim/models/flight_control/FGGain.cpp
src/FDM/JSBSim/models/flight_control/FGGain.h
src/FDM/JSBSim/models/flight_control/FGGradient.h
src/FDM/JSBSim/models/flight_control/FGGyro.cpp
src/FDM/JSBSim/models/flight_control/FGGyro.h
src/FDM/JSBSim/models/flight_control/FGKinemat.cpp
src/FDM/JSBSim/models/flight_control/FGKinemat.h
src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp
src/FDM/JSBSim/models/flight_control/FGMagnetometer.h
src/FDM/JSBSim/models/flight_control/FGPID.cpp
src/FDM/JSBSim/models/flight_control/FGPID.h
src/FDM/JSBSim/models/flight_control/FGSensor.cpp
src/FDM/JSBSim/models/flight_control/FGSensor.h
src/FDM/JSBSim/models/flight_control/FGSensorOrientation.h [new file with mode: 0755]
src/FDM/JSBSim/models/flight_control/FGSummer.cpp
src/FDM/JSBSim/models/flight_control/FGSummer.h
src/FDM/JSBSim/models/flight_control/FGSwitch.cpp
src/FDM/JSBSim/models/flight_control/FGSwitch.h
src/FDM/JSBSim/models/flight_control/Makefile.am
src/FDM/JSBSim/models/propulsion/FGElectric.cpp
src/FDM/JSBSim/models/propulsion/FGElectric.h
src/FDM/JSBSim/models/propulsion/FGEngine.cpp
src/FDM/JSBSim/models/propulsion/FGEngine.h
src/FDM/JSBSim/models/propulsion/FGForce.cpp
src/FDM/JSBSim/models/propulsion/FGForce.h
src/FDM/JSBSim/models/propulsion/FGNozzle.cpp
src/FDM/JSBSim/models/propulsion/FGPiston.cpp
src/FDM/JSBSim/models/propulsion/FGPiston.h
src/FDM/JSBSim/models/propulsion/FGPropeller.cpp
src/FDM/JSBSim/models/propulsion/FGPropeller.h
src/FDM/JSBSim/models/propulsion/FGRocket.cpp
src/FDM/JSBSim/models/propulsion/FGRocket.h
src/FDM/JSBSim/models/propulsion/FGTank.cpp
src/FDM/JSBSim/models/propulsion/FGTank.h
src/FDM/JSBSim/models/propulsion/FGThruster.h
src/FDM/JSBSim/models/propulsion/FGTurbine.cpp
src/FDM/JSBSim/models/propulsion/FGTurbine.h
src/FDM/JSBSim/models/propulsion/FGTurboProp.h

index c6740b4b6ab1e5485e64b0804d6096a615c90e50..c62dafa6a4cd428f114bb4b1388c20a3054b5db3 100644 (file)
@@ -43,26 +43,26 @@ INCLUDES
 
 #include "FGFDMExec.h"
 #include "FGState.h"
-#include <models/FGAtmosphere.h>
-#include <models/atmosphere/FGMSIS.h>
-#include <models/atmosphere/FGMars.h>
-#include <models/FGFCS.h>
-#include <models/FGPropulsion.h>
-#include <models/FGMassBalance.h>
-#include <models/FGGroundReactions.h>
-#include <models/FGExternalReactions.h>
-#include <models/FGBuoyantForces.h>
-#include <models/FGAerodynamics.h>
-#include <models/FGInertial.h>
-#include <models/FGAircraft.h>
-#include <models/FGPropagate.h>
-#include <models/FGAuxiliary.h>
-#include <models/FGInput.h>
-#include <models/FGOutput.h>
-#include <initialization/FGInitialCondition.h>
-//#include <initialization/FGTrimAnalysis.h> // Remove until later
-#include <input_output/FGPropertyManager.h>
-#include <input_output/FGScript.h>
+#include "models/FGAtmosphere.h"
+#include "models/atmosphere/FGMSIS.h"
+#include "models/atmosphere/FGMars.h"
+#include "models/FGFCS.h"
+#include "models/FGPropulsion.h"
+#include "models/FGMassBalance.h"
+#include "models/FGGroundReactions.h"
+#include "models/FGExternalReactions.h"
+#include "models/FGBuoyantForces.h"
+#include "models/FGAerodynamics.h"
+#include "models/FGInertial.h"
+#include "models/FGAircraft.h"
+#include "models/FGPropagate.h"
+#include "models/FGAuxiliary.h"
+#include "models/FGInput.h"
+#include "models/FGOutput.h"
+#include "initialization/FGInitialCondition.h"
+//#include "initialization/FGTrimAnalysis.h" // Remove until later
+#include "input_output/FGPropertyManager.h"
+#include "input_output/FGScript.h"
 
 #include <iostream>
 #include <iterator>
@@ -715,7 +715,7 @@ void FGFDMExec::BuildPropertyCatalog(struct PropertyCatalogStructure* pcs)
   int node_idx = 0;
   char int_buf[10];
 
-  for (unsigned int i=0; i<pcs->node->nChildren(); i++) {
+  for (int i=0; i<pcs->node->nChildren(); i++) {
     pcsNew->base_string = pcs->base_string + "/" + pcs->node->getChild(i)->getName();
     node_idx = pcs->node->getChild(i)->getIndex();
     sprintf(int_buf, "[%d]", node_idx);
index 50bffeaf52f0cafc5685964d6871db5e35e504ad..5e1ee07193a5c30f40a7301ea6541943267c407a 100644 (file)
@@ -41,17 +41,17 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <models/FGModel.h>
-#include <models/FGOutput.h>
-#include <models/FGInput.h>
-#include <initialization/FGTrim.h>
-#include <initialization/FGInitialCondition.h>
-#include <FGJSBBase.h>
-#include <input_output/FGPropertyManager.h>
-#include <input_output/FGGroundCallback.h>
-#include <input_output/FGXMLFileRead.h>
-#include <models/FGPropagate.h>
-#include <math/FGColumnVector3.h>
+#include "models/FGModel.h"
+#include "models/FGOutput.h"
+#include "models/FGInput.h"
+#include "initialization/FGTrim.h"
+#include "initialization/FGInitialCondition.h"
+#include "FGJSBBase.h"
+#include "input_output/FGPropertyManager.h"
+#include "input_output/FGGroundCallback.h"
+#include "input_output/FGXMLFileRead.h"
+#include "models/FGPropagate.h"
+#include "math/FGColumnVector3.h"
 
 #include <vector>
 #include <string>
index c1b6f72813816db14ca96db273033f6b12bc65bb..9fd627ebae40eb43382247bbf3937639e75f3fc0 100644 (file)
@@ -45,18 +45,18 @@ INCLUDES
 #include <string>
 #include <map>
 #include "FGJSBBase.h"
-#include <initialization/FGInitialCondition.h>
-#include <math/FGColumnVector3.h>
-#include <math/FGQuaternion.h>
+#include "initialization/FGInitialCondition.h"
+#include "math/FGColumnVector3.h"
+#include "math/FGQuaternion.h"
 #include "FGFDMExec.h"
-#include <models/FGAtmosphere.h>
-#include <models/FGFCS.h>
-#include <models/FGPropagate.h>
-#include <models/FGAuxiliary.h>
-#include <models/FGAerodynamics.h>
-#include <models/FGAircraft.h>
-#include <models/FGGroundReactions.h>
-#include <models/FGPropulsion.h>
+#include "models/FGAtmosphere.h"
+#include "models/FGFCS.h"
+#include "models/FGPropagate.h"
+#include "models/FGAuxiliary.h"
+#include "models/FGAerodynamics.h"
+#include "models/FGAircraft.h"
+#include "models/FGGroundReactions.h"
+#include "models/FGPropulsion.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 10b4b7a3e3fe429bb03bf0babed4495f2490eacd..295033d50d3808915713a7a181f9941c16ec56af 100644 (file)
@@ -43,15 +43,15 @@ INCLUDES
 *******************************************************************************/
 
 #include "FGInitialCondition.h"
-#include <FGFDMExec.h>
-#include <models/FGInertial.h>
-#include <models/FGAtmosphere.h>
-#include <models/FGAerodynamics.h>
-#include <models/FGPropagate.h>
-#include <input_output/FGPropertyManager.h>
-#include <models/FGPropulsion.h>
-#include <input_output/FGXMLParse.h>
-#include <math/FGQuaternion.h>
+#include "FGFDMExec.h"
+#include "models/FGInertial.h"
+#include "models/FGAtmosphere.h"
+#include "models/FGAerodynamics.h"
+#include "models/FGPropagate.h"
+#include "input_output/FGPropertyManager.h"
+#include "models/FGPropulsion.h"
+#include "input_output/FGXMLParse.h"
+#include "math/FGQuaternion.h"
 #include <fstream>
 
 namespace JSBSim {
index 86de126a00448a6e7045e1bc88486ab1d9149125..898acc3fdf90aef649112ad590523f1c0dadfad6 100644 (file)
@@ -47,10 +47,10 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <FGFDMExec.h>
-#include <FGJSBBase.h>
-#include <math/FGColumnVector3.h>
-#include <input_output/FGXMLFileRead.h>
+#include "FGFDMExec.h"
+#include "FGJSBBase.h"
+#include "math/FGColumnVector3.h"
+#include "input_output/FGXMLFileRead.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index ed69050cdea5f0ab9915238f1e297f7ad421263d..4257e90d3d6ec5df100a41e78880a0f8766500cd 100644 (file)
@@ -44,14 +44,14 @@ INCLUDES
 #include <cstdlib>
 #include <iomanip>
 #include "FGTrim.h"
-#include <models/FGAtmosphere.h>
+#include "models/FGAtmosphere.h"
 #include "FGInitialCondition.h"
-#include <models/FGAircraft.h>
-#include <models/FGMassBalance.h>
-#include <models/FGGroundReactions.h>
-#include <models/FGInertial.h>
-#include <models/FGAerodynamics.h>
-#include <math/FGColumnVector3.h>
+#include "models/FGAircraft.h"
+#include "models/FGMassBalance.h"
+#include "models/FGGroundReactions.h"
+#include "models/FGInertial.h"
+#include "models/FGAerodynamics.h"
+#include "math/FGColumnVector3.h"
 
 #if _MSC_VER
 #pragma warning (disable : 4786 4788)
index 5124c31bbd62cc4202514ce27b85f704b3f2cd04..d9da4669b5daf2c265fafa9769e929260aa2f093 100644 (file)
@@ -38,13 +38,13 @@ INCLUDES
 
 #include <string>
 #include <cstdlib>
-#include <FGFDMExec.h>
-#include <models/FGAtmosphere.h>
+#include "FGFDMExec.h"
+#include "models/FGAtmosphere.h"
 #include "FGInitialCondition.h"
 #include "FGTrimAxis.h"
-#include <models/FGAircraft.h>
-#include <models/FGPropulsion.h>
-#include <models/FGAerodynamics.h>
+#include "models/FGAircraft.h"
+#include "models/FGPropulsion.h"
+#include "models/FGAerodynamics.h"
 
 namespace JSBSim {
 
index 8976d7a525d3c59ccc4fceb19148b5309b7cd746..d1484115c034a612afd0154d649461e0d5293e58 100644 (file)
@@ -31,8 +31,8 @@ HISTORY
 SENTRY
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <math/FGColumnVector3.h>
-#include <math/FGLocation.h>
+#include "math/FGColumnVector3.h"
+#include "math/FGLocation.h"
 #include "FGGroundCallback.h"
 
 namespace JSBSim {
index bb36e650c6581369345a90e043e88a240459d576..4def8c1ca35f556104cbc8694452405ebf72b976 100644 (file)
@@ -38,8 +38,8 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <math/FGColumnVector3.h>
-#include <math/FGLocation.h>
+#include "math/FGColumnVector3.h"
+#include "math/FGLocation.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 40c173fcdc0e9558585631204323266e5a8d9eb5..f775d435c1b9c26108836a2e4cbeba7bd6c91fc0 100644 (file)
@@ -43,9 +43,9 @@ INCLUDES
 
 #include <string>
 #include <iostream>
-#include <simgear/props/props.hxx>
+#include "simgear/props/props.hxx"
 #if !PROPS_STANDALONE
-# include <simgear/math/SGMath.hxx>
+# include "simgear/math/SGMath.hxx"
 #endif
 
 #include "FGJSBBase.h"
index e0fff6a13069b0a574110b2d06f6c6174dd301fa..6c49b4f15a35bc692f74e83d09ee7d53414c20b7 100755 (executable)
@@ -42,8 +42,8 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGScript.h"
-#include <input_output/FGXMLParse.h>
-#include <initialization/FGTrim.h>
+#include "input_output/FGXMLParse.h"
+#include "initialization/FGTrim.h"
 
 #include <iostream>
 
index 41037c1d9589ffe1ee73b09bd1e3c59b5466715d..4dc5c8cf9eddea44611835e96e627762cb5786be 100644 (file)
@@ -40,10 +40,10 @@ INCLUDES
 #include "FGJSBBase.h"
 #include "FGState.h"
 #include "FGFDMExec.h"
-#include <math/FGFunction.h>
-#include <math/FGCondition.h>
+#include "math/FGFunction.h"
+#include "math/FGCondition.h"
 #include <vector>
-#include <input_output/FGXMLFileRead.h>
+#include "input_output/FGXMLFileRead.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index f4f628e8b9cc63b497b441ed10d46b3872d00836..50eba40abc66c141b501a77417eb3eb4f5146655 100755 (executable)
@@ -42,6 +42,9 @@ namespace JSBSim {
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_XMLELEMENT;
 
+bool Element::converterIsInitialized = false;
+map <string, map <string, double> > Element::convert;
+
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@@ -52,149 +55,152 @@ Element::Element(string nm)
   parent = 0L;
   element_index = 0;
 
-  // convert ["from"]["to"] = factor, so: from * factor = to
-  // Length
-  convert["M"]["FT"] = 3.2808399;
-  convert["FT"]["M"] = 1.0/convert["M"]["FT"];
-  convert["FT"]["IN"] = 12.0;
-  convert["IN"]["FT"] = 1.0/convert["FT"]["IN"];
-  convert["IN"]["M"] = convert["IN"]["FT"] * convert["FT"]["M"];
-  convert["M"]["IN"] = convert["M"]["FT"] * convert["FT"]["IN"];
-  // Area
-  convert["M2"]["FT2"] = convert["M"]["FT"]*convert["M"]["FT"];
-  convert["FT2"]["M2"] = 1.0/convert["M2"]["FT2"];
-  convert["M2"]["IN2"] = convert["M"]["IN"]*convert["M"]["IN"];
-  convert["IN2"]["M2"] = 1.0/convert["M2"]["IN2"];
-  convert["FT2"]["IN2"] = 144.0;
-  convert["IN2"]["FT2"] = 1.0/convert["FT2"]["IN2"];
-  // Volume
-  convert["IN3"]["CC"] = 16.387064;
-  convert["CC"]["IN3"] = 1.0/convert["IN3"]["CC"];
-  convert["FT3"]["IN3"] = 1728.0;
-  convert["IN3"]["FT3"] = 1.0/convert["FT3"]["IN3"];
-  convert["M3"]["FT3"] = 35.3146667;
-  convert["FT3"]["M3"] = 1.0/convert["M3"]["FT3"];
-  convert["LTR"]["IN3"] = 61.0237441;
-  convert["IN3"]["LTR"] = 1.0/convert["LTR"]["IN3"];
-  // Mass & Weight
-  convert["LBS"]["KG"] = 0.45359237;
-  convert["KG"]["LBS"] = 1.0/convert["LBS"]["KG"];
-  convert["SLUG"]["KG"] = 14.59390;
-  convert["KG"]["SLUG"] = 1.0/convert["SLUG"]["KG"];
-  // Moments of Inertia
-  convert["SLUG*FT2"]["KG*M2"] = 1.35594;
-  convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"];
-  // Angles
-  convert["RAD"]["DEG"] = 360.0/(2.0*3.1415926);
-  convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"];
-  // Spring force
-  convert["LBS/FT"]["N/M"] = 14.5939;
-  convert["N/M"]["LBS/FT"] = 1.0/convert["LBS/FT"]["N/M"];
-  // Damping force
-  convert["LBS/FT/SEC"]["N/M/SEC"] = 14.5939;
-  convert["N/M/SEC"]["LBS/FT/SEC"] = 1.0/convert["LBS/FT/SEC"]["N/M/SEC"];
-  // Damping force (Square Law)
-  convert["LBS/FT2/SEC2"]["N/M2/SEC2"] = 47.880259;
-  convert["N/M2/SEC2"]["LBS/FT2/SEC2"] = 1.0/convert["LBS/FT2/SEC2"]["N/M2/SEC2"];
-  // Power
-  convert["WATTS"]["HP"] = 0.001341022;
-  convert["HP"]["WATTS"] = 1.0/convert["WATTS"]["HP"];
-  // Force
-  convert["N"]["LBS"] = 0.22482;
-  convert["LBS"]["N"] = 1.0/convert["N"]["LBS"];
-  // Velocity
-  convert["KTS"]["FT/SEC"] = 1.68781;
-  convert["FT/SEC"]["KTS"] = 1.0/convert["KTS"]["FT/SEC"];
-  convert["M/S"]["FT/S"] = 3.2808399;
-  convert["FT/S"]["M/S"] = 1.0/convert["M/S"]["FT/S"];
-  // Torque
-  convert["FT*LBS"]["N*M"] = 1.35581795;
-  convert["N*M"]["FT*LBS"] = 1/convert["FT*LBS"]["N*M"];
-  // Valve
-  convert["M4*SEC/KG"]["FT4*SEC/SLUG"] = convert["M"]["FT"]*convert["M"]["FT"]*
-    convert["M"]["FT"]*convert["M"]["FT"]/convert["KG"]["SLUG"];
-  convert["FT4*SEC/SLUG"]["M4*SEC/KG"] =
-    1.0/convert["M4*SEC/KG"]["FT4*SEC/SLUG"];
-  // Pressure
-  convert["INHG"]["PSF"] = 70.7180803;
-  convert["PSF"]["INHG"] = 1.0/convert["INHG"]["PSF"];
-  convert["ATM"]["INHG"] = 29.9246899;
-  convert["INHG"]["ATM"] = 1.0/convert["ATM"]["INHG"];
-  convert["PSI"]["INHG"] = 2.03625437;
-  convert["INHG"]["PSI"] = 1.0/convert["PSI"]["INHG"];
-  convert["INHG"]["PA"] = 3386.0; // inches Mercury to pascals
-  convert["PA"]["INHG"] = 1.0/convert["INHG"]["PA"];
-  convert["LBS/FT2"]["N/M2"] = 14.5939/convert["FT"]["M"];
-  convert["N/M2"]["LBS/FT2"] = 1.0/convert["LBS/FT2"]["N/M2"];
-  convert["LBS/FT2"]["PA"] = convert["LBS/FT2"]["N/M2"];
-  convert["PA"]["LBS/FT2"] = 1.0/convert["LBS/FT2"]["PA"];
-  // Mass flow
-  convert["KG/MIN"]["LBS/MIN"] = convert["KG"]["LBS"];
-  // Fuel Consumption
-  convert["LBS/HP*HR"]["KG/KW*HR"] = 0.6083;
-  convert["KG/KW*HR"]["LBS/HP*HR"] = 1.0/convert["LBS/HP*HR"]["KG/KW*HR"];
-
-  // Length
-  convert["M"]["M"] = 1.00;
-  convert["FT"]["FT"] = 1.00;
-  convert["IN"]["IN"] = 1.00;
-  // Area
-  convert["M2"]["M2"] = 1.00;
-  convert["FT2"]["FT2"] = 1.00;
-  // Volume
-  convert["IN3"]["IN3"] = 1.00;
-  convert["CC"]["CC"] = 1.0;
-  convert["M3"]["M3"] = 1.0;
-  convert["FT3"]["FT3"] = 1.0;
-  convert["LTR"]["LTR"] = 1.0;
-  // Mass & Weight
-  convert["KG"]["KG"] = 1.00;
-  convert["LBS"]["LBS"] = 1.00;
-  // Moments of Inertia
-  convert["KG*M2"]["KG*M2"] = 1.00;
-  convert["SLUG*FT2"]["SLUG*FT2"] = 1.00;
-  // Angles
-  convert["DEG"]["DEG"] = 1.00;
-  convert["RAD"]["RAD"] = 1.00;
-  // Spring force
-  convert["LBS/FT"]["LBS/FT"] = 1.00;
-  convert["N/M"]["N/M"] = 1.00;
-  // Damping force
-  convert["LBS/FT/SEC"]["LBS/FT/SEC"] = 1.00;
-  convert["N/M/SEC"]["N/M/SEC"] = 1.00;
-  // Damping force (Square law)
-  convert["LBS/FT2/SEC2"]["LBS/FT2/SEC2"] = 1.00;
-  convert["N/M2/SEC2"]["N/M2/SEC2"] = 1.00;
-  // Power
-  convert["HP"]["HP"] = 1.00;
-  convert["WATTS"]["WATTS"] = 1.00;
-  // Force
-  convert["N"]["N"] = 1.00;
-  // Velocity
-  convert["FT/SEC"]["FT/SEC"] = 1.00;
-  convert["KTS"]["KTS"] = 1.00;
-  convert["M/S"]["M/S"] = 1.0;
-  // Torque
-  convert["FT*LBS"]["FT*LBS"] = 1.00;
-  convert["N*M"]["N*M"] = 1.00;
-  // Valve
-  convert["M4*SEC/KG"]["M4*SEC/KG"] = 1.0;
-  convert["FT4*SEC/SLUG"]["FT4*SEC/SLUG"] = 1.0;
-  // Pressure
-  convert["PSI"]["PSI"] = 1.00;
-  convert["PSF"]["PSF"] = 1.00;
-  convert["INHG"]["INHG"] = 1.00;
-  convert["ATM"]["ATM"] = 1.0;
-  convert["PA"]["PA"] = 1.0;
-  convert["N/M2"]["N/M2"] = 1.00;
-  convert["LBS/FT2"]["LBS/FT2"] = 1.00;
-  // Mass flow
-  convert["LBS/SEC"]["LBS/SEC"] = 1.00;
-  convert["KG/MIN"]["KG/MIN"] = 1.0;
-  convert["LBS/MIN"]["LBS/MIN"] = 1.0;
-  // Fuel Consumption
-  convert["LBS/HP*HR"]["LBS/HP*HR"] = 1.0;
-  convert["KG/KW*HR"]["KG/KW*HR"] = 1.0;
+  if (!converterIsInitialized) {
+    converterIsInitialized = true;
+    // convert ["from"]["to"] = factor, so: from * factor = to
+    // Length
+    convert["M"]["FT"] = 3.2808399;
+    convert["FT"]["M"] = 1.0/convert["M"]["FT"];
+    convert["FT"]["IN"] = 12.0;
+    convert["IN"]["FT"] = 1.0/convert["FT"]["IN"];
+    convert["IN"]["M"] = convert["IN"]["FT"] * convert["FT"]["M"];
+    convert["M"]["IN"] = convert["M"]["FT"] * convert["FT"]["IN"];
+    // Area
+    convert["M2"]["FT2"] = convert["M"]["FT"]*convert["M"]["FT"];
+    convert["FT2"]["M2"] = 1.0/convert["M2"]["FT2"];
+    convert["M2"]["IN2"] = convert["M"]["IN"]*convert["M"]["IN"];
+    convert["IN2"]["M2"] = 1.0/convert["M2"]["IN2"];
+    convert["FT2"]["IN2"] = 144.0;
+    convert["IN2"]["FT2"] = 1.0/convert["FT2"]["IN2"];
+    // Volume
+    convert["IN3"]["CC"] = 16.387064;
+    convert["CC"]["IN3"] = 1.0/convert["IN3"]["CC"];
+    convert["FT3"]["IN3"] = 1728.0;
+    convert["IN3"]["FT3"] = 1.0/convert["FT3"]["IN3"];
+    convert["M3"]["FT3"] = 35.3146667;
+    convert["FT3"]["M3"] = 1.0/convert["M3"]["FT3"];
+    convert["LTR"]["IN3"] = 61.0237441;
+    convert["IN3"]["LTR"] = 1.0/convert["LTR"]["IN3"];
+    // Mass & Weight
+    convert["LBS"]["KG"] = 0.45359237;
+    convert["KG"]["LBS"] = 1.0/convert["LBS"]["KG"];
+    convert["SLUG"]["KG"] = 14.59390;
+    convert["KG"]["SLUG"] = 1.0/convert["SLUG"]["KG"];
+    // Moments of Inertia
+    convert["SLUG*FT2"]["KG*M2"] = 1.35594;
+    convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"];
+    // Angles
+    convert["RAD"]["DEG"] = 360.0/(2.0*3.1415926);
+    convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"];
+    // Spring force
+    convert["LBS/FT"]["N/M"] = 14.5939;
+    convert["N/M"]["LBS/FT"] = 1.0/convert["LBS/FT"]["N/M"];
+    // Damping force
+    convert["LBS/FT/SEC"]["N/M/SEC"] = 14.5939;
+    convert["N/M/SEC"]["LBS/FT/SEC"] = 1.0/convert["LBS/FT/SEC"]["N/M/SEC"];
+    // Damping force (Square Law)
+    convert["LBS/FT2/SEC2"]["N/M2/SEC2"] = 47.880259;
+    convert["N/M2/SEC2"]["LBS/FT2/SEC2"] = 1.0/convert["LBS/FT2/SEC2"]["N/M2/SEC2"];
+    // Power
+    convert["WATTS"]["HP"] = 0.001341022;
+    convert["HP"]["WATTS"] = 1.0/convert["WATTS"]["HP"];
+    // Force
+    convert["N"]["LBS"] = 0.22482;
+    convert["LBS"]["N"] = 1.0/convert["N"]["LBS"];
+    // Velocity
+    convert["KTS"]["FT/SEC"] = 1.68781;
+    convert["FT/SEC"]["KTS"] = 1.0/convert["KTS"]["FT/SEC"];
+    convert["M/S"]["FT/S"] = 3.2808399;
+    convert["FT/S"]["M/S"] = 1.0/convert["M/S"]["FT/S"];
+    // Torque
+    convert["FT*LBS"]["N*M"] = 1.35581795;
+    convert["N*M"]["FT*LBS"] = 1/convert["FT*LBS"]["N*M"];
+    // Valve
+    convert["M4*SEC/KG"]["FT4*SEC/SLUG"] = convert["M"]["FT"]*convert["M"]["FT"]*
+      convert["M"]["FT"]*convert["M"]["FT"]/convert["KG"]["SLUG"];
+    convert["FT4*SEC/SLUG"]["M4*SEC/KG"] =
+      1.0/convert["M4*SEC/KG"]["FT4*SEC/SLUG"];
+    // Pressure
+    convert["INHG"]["PSF"] = 70.7180803;
+    convert["PSF"]["INHG"] = 1.0/convert["INHG"]["PSF"];
+    convert["ATM"]["INHG"] = 29.9246899;
+    convert["INHG"]["ATM"] = 1.0/convert["ATM"]["INHG"];
+    convert["PSI"]["INHG"] = 2.03625437;
+    convert["INHG"]["PSI"] = 1.0/convert["PSI"]["INHG"];
+    convert["INHG"]["PA"] = 3386.0; // inches Mercury to pascals
+    convert["PA"]["INHG"] = 1.0/convert["INHG"]["PA"];
+    convert["LBS/FT2"]["N/M2"] = 14.5939/convert["FT"]["M"];
+    convert["N/M2"]["LBS/FT2"] = 1.0/convert["LBS/FT2"]["N/M2"];
+    convert["LBS/FT2"]["PA"] = convert["LBS/FT2"]["N/M2"];
+    convert["PA"]["LBS/FT2"] = 1.0/convert["LBS/FT2"]["PA"];
+    // Mass flow
+    convert["KG/MIN"]["LBS/MIN"] = convert["KG"]["LBS"];
+    // Fuel Consumption
+    convert["LBS/HP*HR"]["KG/KW*HR"] = 0.6083;
+    convert["KG/KW*HR"]["LBS/HP*HR"] = 1.0/convert["LBS/HP*HR"]["KG/KW*HR"];
+
+    // Length
+    convert["M"]["M"] = 1.00;
+    convert["FT"]["FT"] = 1.00;
+    convert["IN"]["IN"] = 1.00;
+    // Area
+    convert["M2"]["M2"] = 1.00;
+    convert["FT2"]["FT2"] = 1.00;
+    // Volume
+    convert["IN3"]["IN3"] = 1.00;
+    convert["CC"]["CC"] = 1.0;
+    convert["M3"]["M3"] = 1.0;
+    convert["FT3"]["FT3"] = 1.0;
+    convert["LTR"]["LTR"] = 1.0;
+    // Mass & Weight
+    convert["KG"]["KG"] = 1.00;
+    convert["LBS"]["LBS"] = 1.00;
+    // Moments of Inertia
+    convert["KG*M2"]["KG*M2"] = 1.00;
+    convert["SLUG*FT2"]["SLUG*FT2"] = 1.00;
+    // Angles
+    convert["DEG"]["DEG"] = 1.00;
+    convert["RAD"]["RAD"] = 1.00;
+    // Spring force
+    convert["LBS/FT"]["LBS/FT"] = 1.00;
+    convert["N/M"]["N/M"] = 1.00;
+    // Damping force
+    convert["LBS/FT/SEC"]["LBS/FT/SEC"] = 1.00;
+    convert["N/M/SEC"]["N/M/SEC"] = 1.00;
+    // Damping force (Square law)
+    convert["LBS/FT2/SEC2"]["LBS/FT2/SEC2"] = 1.00;
+    convert["N/M2/SEC2"]["N/M2/SEC2"] = 1.00;
+    // Power
+    convert["HP"]["HP"] = 1.00;
+    convert["WATTS"]["WATTS"] = 1.00;
+    // Force
+    convert["N"]["N"] = 1.00;
+    // Velocity
+    convert["FT/SEC"]["FT/SEC"] = 1.00;
+    convert["KTS"]["KTS"] = 1.00;
+    convert["M/S"]["M/S"] = 1.0;
+    // Torque
+    convert["FT*LBS"]["FT*LBS"] = 1.00;
+    convert["N*M"]["N*M"] = 1.00;
+    // Valve
+    convert["M4*SEC/KG"]["M4*SEC/KG"] = 1.0;
+    convert["FT4*SEC/SLUG"]["FT4*SEC/SLUG"] = 1.0;
+    // Pressure
+    convert["PSI"]["PSI"] = 1.00;
+    convert["PSF"]["PSF"] = 1.00;
+    convert["INHG"]["INHG"] = 1.00;
+    convert["ATM"]["ATM"] = 1.0;
+    convert["PA"]["PA"] = 1.0;
+    convert["N/M2"]["N/M2"] = 1.00;
+    convert["LBS/FT2"]["LBS/FT2"] = 1.00;
+    // Mass flow
+    convert["LBS/SEC"]["LBS/SEC"] = 1.00;
+    convert["KG/MIN"]["KG/MIN"] = 1.0;
+    convert["LBS/MIN"]["LBS/MIN"] = 1.0;
+    // Fuel Consumption
+    convert["LBS/HP*HR"]["LBS/HP*HR"] = 1.0;
+    convert["KG/KW*HR"]["KG/KW*HR"] = 1.0;
+  }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index f8a85bbcdb5f92196b66bf9f2b554a1916505b47..d00986e3ef3d7c8fc17a6d662412b27ab41e2c29 100755 (executable)
@@ -45,7 +45,7 @@ using std::vector;
 using std::cout;
 using std::endl;
 
-#include <math/FGColumnVector3.h>
+#include "math/FGColumnVector3.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -335,7 +335,8 @@ private:
   Element *parent;
   unsigned int element_index;
   typedef map <string, map <string, double> > tMapConvert;
-  tMapConvert convert;
+  static tMapConvert convert;
+  static bool converterIsInitialized;
 };
 
 } // namespace JSBSim
index ce33d8c5bc4bcba1ef9583ded75192643e41b2c9..39323daf285121ddc63eb65e91f98dc8a6d1aae5 100755 (executable)
@@ -35,7 +35,7 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <input_output/FGXMLParse.h>
+#include "input_output/FGXMLParse.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index cc63d117a4333c039e29a7b7d420cd42bf4835f2..3becca592ef0858318a2752a49d3ac65d4803d0b 100644 (file)
@@ -38,9 +38,9 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include <map>
-#include <FGJSBBase.h>
-#include <input_output/FGXMLElement.h>
-#include <input_output/FGPropertyManager.h>
+#include "FGJSBBase.h"
+#include "input_output/FGXMLElement.h"
+#include "input_output/FGPropertyManager.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 7a185ec01ccdbcabc7eee58c840bada112115ae6..597fe2f2fae7af59b7bde6a00f8365cdc9f3aa96 100755 (executable)
@@ -49,7 +49,6 @@ FGFunction::FGFunction(FGPropertyManager* propMan, Element* el, string prefix)
 {
   Element* element;
   string operation, property_name;
-  int size = el->GetNumElements();
   cached = false;
   cachedValue = -HUGE_VAL;
 
index a4ba9694ba13dde4dd17c0525b6d8ef446cdc4f7..e946ab60a66a37841d1b3c95eb64504392e0f412 100755 (executable)
@@ -37,8 +37,8 @@ INCLUDES
 #include <vector>
 #include <string>
 #include "FGParameter.h"
-#include <input_output/FGXMLElement.h>
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGXMLElement.h"
+#include "input_output/FGPropertyManager.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index d740d01b120dc4e135737180f8ea5c07fbfd9320..42619b93fbac45f03566f36174389a78578b551f 100644 (file)
@@ -41,7 +41,7 @@ INCLUDES
 #include <cmath>
 
 #include "FGLocation.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
 
 namespace JSBSim {
 
index e55f31c81e627a8086df4e67eaf8a8997e915d66..b61ffa966cbbc287553edf15dd8523732ce09776 100644 (file)
@@ -39,8 +39,8 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <FGJSBBase.h>
-#include <input_output/FGPropertyManager.h>
+#include "FGJSBBase.h"
+#include "input_output/FGPropertyManager.h"
 #include "FGColumnVector3.h"
 #include "FGMatrix33.h"
 
index 60ad5f5ce4b3df4ee1227c801ce97a15001c26cc..82803f55818e6cd2f1600829ef9e75eb50f5dec5 100755 (executable)
@@ -35,7 +35,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGParameter.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 3607c2064f3bc771bca29765f73903112710fd35..73c0e009a0833807242b1d1efb87e284caee9c62 100644 (file)
@@ -40,10 +40,10 @@ SENTRY
   INCLUDES
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <FGJSBBase.h>
+#include "FGJSBBase.h"
 #include "FGMatrix33.h"
 #include "FGColumnVector3.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   DEFINITIONS
index 079631db55615da53fdaa204dc8b9ecb58c4a623..d0027aec3b22e53daac2e720011dc3c534ff716c 100644 (file)
@@ -488,7 +488,7 @@ void FGTable::operator<<(stringstream& in_stream)
 FGTable& FGTable::operator<<(const double n)
 {
   Data[rowCounter][colCounter] = n;
-  if (colCounter == nCols) {
+  if (colCounter == (int)nCols) {
     colCounter = 0;
     rowCounter++;
   } else {
index a90654a18c2fb19f1ac947df8e2d964fa94b74a3..600f08d4b2bae84d57291841d5687a605dfe80b9 100644 (file)
@@ -38,9 +38,9 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGXMLElement.h"
 #include "FGParameter.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
 #include <sstream>
 #include <vector>
 
index 829697024ae7143df6f7e4131c5cfe330de2deff..cc7fd0d561ab3d81ce4323a6493c740c02e890f0 100644 (file)
@@ -42,7 +42,7 @@ INCLUDES
 #include "FGAircraft.h"
 #include "FGAuxiliary.h"
 #include "FGMassBalance.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
 
 namespace JSBSim {
 
@@ -324,21 +324,21 @@ bool FGAerodynamics::Load(Element *element)
 
   Debug(2);
 
-  if (temp_element = document->FindElement("alphalimits")) {
+  if ((temp_element = document->FindElement("alphalimits"))) {
     scratch_unit = temp_element->GetAttributeValue("unit");
     if (scratch_unit.empty()) scratch_unit = "RAD";
     alphaclmin = temp_element->FindElementValueAsNumberConvertFromTo("min", scratch_unit, "RAD");
     alphaclmax = temp_element->FindElementValueAsNumberConvertFromTo("max", scratch_unit, "RAD");
   }
 
-  if (temp_element = document->FindElement("hysteresis_limits")) {
+  if ((temp_element = document->FindElement("hysteresis_limits"))) {
     scratch_unit = temp_element->GetAttributeValue("unit");
     if (scratch_unit.empty()) scratch_unit = "RAD";
     alphahystmin = temp_element->FindElementValueAsNumberConvertFromTo("min", scratch_unit, "RAD");
     alphahystmax = temp_element->FindElementValueAsNumberConvertFromTo("max", scratch_unit, "RAD");
   }
 
-  if (temp_element = document->FindElement("aero_ref_pt_shift_x")) {
+  if ((temp_element = document->FindElement("aero_ref_pt_shift_x"))) {
     function_element = temp_element->FindElement("function");
     AeroRPShift = new FGFunction(PropertyManager, function_element);
   }
@@ -558,6 +558,9 @@ void FGAerodynamics::Debug(int from)
         case (atBodyXYZ):
           cout << endl << "  Aerodynamics (X|Y|Z axes):" << endl << endl;
           break;
+      case (atNone):
+          cout << endl << "  Aerodynamics (undefined axes):" << endl << endl;
+          break;
       }
     }
   }
index 9e2e47b22e9dbf2dccd418ce9887148a76a66fb3..fce51a1015111d35eb7b6524605b21ef8efad78c 100644 (file)
@@ -42,10 +42,10 @@ INCLUDES
 #include <map>
 
 #include "FGModel.h"
-#include <math/FGFunction.h>
-#include <math/FGColumnVector3.h>
-#include <math/FGMatrix33.h>
-#include <input_output/FGXMLFileRead.h>
+#include "math/FGFunction.h"
+#include "math/FGColumnVector3.h"
+#include "math/FGMatrix33.h"
+#include "input_output/FGXMLFileRead.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 9c6ffef856ac47a6585fcaa43f476fe5cfb80bf3..2e65dc021a62d8e052eaed52557556c069966891 100644 (file)
@@ -50,9 +50,9 @@ INCLUDES
 #include "FGExternalReactions.h"
 #include "FGBuoyantForces.h"
 #include "FGAerodynamics.h"
-#include <FGFDMExec.h>
+#include "FGFDMExec.h"
 #include "FGPropagate.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
 
 namespace JSBSim {
 
index bc32b1afbd7b1ff8959f5264ef2f5dba415c2c99..10f75aa0ba267f8e3d83d3b92b6f86f236dad2d4 100644 (file)
@@ -41,8 +41,8 @@ INCLUDES
 #include <vector>
 
 #include "FGModel.h"
-#include <input_output/FGXMLElement.h>
-#include <math/FGColumnVector3.h>
+#include "input_output/FGXMLElement.h"
+#include "math/FGColumnVector3.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index b1826b716083cf929fabffa0fe36b9c6906a547d..e1daeb0f9e3d317483f9c5b0c0b51df25164a0fd 100644 (file)
@@ -48,12 +48,12 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGAtmosphere.h"
-#include <FGState.h>
-#include <FGFDMExec.h>
+#include "FGState.h"
+#include "FGFDMExec.h"
 #include "FGAircraft.h"
 #include "FGPropagate.h"
 #include "FGInertial.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
 
 namespace JSBSim {
 
@@ -454,10 +454,12 @@ void FGAtmosphere::Turbulence(void)
     vDirectiondAccelDt(eX) = GaussianRandomNumber();
     vDirectiondAccelDt(eY) = GaussianRandomNumber();
     vDirectiondAccelDt(eZ) = GaussianRandomNumber();
-
+/*
     MagnitudedAccelDt = GaussianRandomNumber();
     MagnitudeAccel    += MagnitudedAccelDt * DeltaT;
     Magnitude         += MagnitudeAccel * DeltaT;
+*/
+    Magnitude         += GaussianRandomNumber() * DeltaT;
 
     vDirectiondAccelDt.Normalize();
     vDirectionAccel += TurbRate * vDirectiondAccelDt * DeltaT;
index bd550246e378d6cff2f46dec7a617b852e4be7f6..2a7443e5d02c8557e3b9a142beffc9901a76f01b 100644 (file)
@@ -43,7 +43,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGModel.h"
-#include <math/FGColumnVector3.h>
+#include "math/FGColumnVector3.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index be578ae1c4c95805f1e3d8db1cf3721c83c15ab4..465c2468ffc8fead2e462f1ef22638a27fffcbdc 100755 (executable)
@@ -44,14 +44,14 @@ INCLUDES
 #include "FGAerodynamics.h"
 #include "FGPropagate.h"
 #include "FGAtmosphere.h"
-#include <FGFDMExec.h>
+#include "FGFDMExec.h"
 #include "FGAircraft.h"
 #include "FGInertial.h"
 #include "FGExternalReactions.h"
 #include "FGBuoyantForces.h"
 #include "FGGroundReactions.h"
 #include "FGPropulsion.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
 
 namespace JSBSim {
 
index 6420e3b975bce333e338e0dfe275ab371e489b79..751dd14f116929cce070417584a61831ae67ce72 100644 (file)
@@ -40,9 +40,9 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGModel.h"
-#include <FGFDMExec.h>
-#include <math/FGColumnVector3.h>
-#include <math/FGLocation.h>
+#include "FGFDMExec.h"
+#include "math/FGColumnVector3.h"
+#include "math/FGLocation.h"
 #include "FGPropagate.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 12979754919ec29c41416b12e2f8534db4366515..4827793ca271acc7bc7d5e9370f839cffe785847 100644 (file)
@@ -38,7 +38,7 @@ INCLUDES
 
 #include "FGBuoyantForces.h"
 #include "FGMassBalance.h"
-#include <input_output/FGPropertyManager.h>  // Need?
+#include "input_output/FGPropertyManager.h"  // Need?
 
 namespace JSBSim {
 
index f03a00df26e152f72f6e70558a632aa9fd46cfe9..ec664b3abde02c096869c8751da1a83b082129ed 100644 (file)
@@ -44,8 +44,8 @@ INCLUDES
 
 #include "FGModel.h"
 #include "FGGasCell.h"
-#include <math/FGColumnVector3.h>
-#include <input_output/FGXMLFileRead.h>
+#include "math/FGColumnVector3.h"
+#include "input_output/FGXMLFileRead.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index c6573924891d5782bc1b2202528e94760a3cc4ba..d4a90db83b2b1437f6ef57c3aed35b6774f8510f 100755 (executable)
@@ -39,13 +39,13 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <FGFDMExec.h>
-#include <FGJSBBase.h>
-#include <models/propulsion/FGForce.h>
+#include "FGFDMExec.h"
+#include "FGJSBBase.h"
+#include "models/propulsion/FGForce.h"
 #include <string>
-#include <input_output/FGPropertyManager.h>
-#include <math/FGColumnVector3.h>
-#include <math/FGFunction.h>
+#include "input_output/FGPropertyManager.h"
+#include "math/FGColumnVector3.h"
+#include "math/FGFunction.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 60cca4440ba53c4123ead7c7669c64947cce3c6b..08e2e6cc1c663e4a588b29b73b2e01796ebac96b 100755 (executable)
@@ -40,7 +40,7 @@ INCLUDES
 
 #include "FGModel.h"
 #include "FGExternalForce.h"
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGXMLElement.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index e1b7b9fb42e6a29aa2f790c9d6288bda5cf68798..aaca68478d4639e0cf439d5ced5e23cc9355542b 100644 (file)
@@ -38,24 +38,25 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCS.h"
-#include <FGFDMExec.h>
-#include <input_output/FGPropertyManager.h>
+#include "FGFDMExec.h"
+#include "input_output/FGPropertyManager.h"
 #include <fstream>
 #include <sstream>
 #include <iomanip>
 
-#include <models/flight_control/FGFilter.h>
-#include <models/flight_control/FGDeadBand.h>
-#include <models/flight_control/FGGain.h>
-#include <models/flight_control/FGPID.h>
-#include <models/flight_control/FGSwitch.h>
-#include <models/flight_control/FGSummer.h>
-#include <models/flight_control/FGKinemat.h>
-#include <models/flight_control/FGFCSFunction.h>
-#include <models/flight_control/FGSensor.h>
-#include <models/flight_control/FGActuator.h>
-#include <models/flight_control/FGAccelerometer.h>
-#include <models/flight_control/FGGyro.h>
+#include "models/flight_control/FGFilter.h"
+#include "models/flight_control/FGDeadBand.h"
+#include "models/flight_control/FGGain.h"
+#include "models/flight_control/FGPID.h"
+#include "models/flight_control/FGSwitch.h"
+#include "models/flight_control/FGSummer.h"
+#include "models/flight_control/FGKinemat.h"
+#include "models/flight_control/FGFCSFunction.h"
+#include "models/flight_control/FGSensor.h"
+#include "models/flight_control/FGActuator.h"
+#include "models/flight_control/FGAccelerometer.h"
+#include "models/flight_control/FGMagnetometer.h"
+#include "models/flight_control/FGGyro.h"
 
 namespace JSBSim {
 
@@ -643,6 +644,8 @@ bool FGFCS::Load(Element* el, SystemType systype)
           Components->push_back(new FGSensor(this, component_element));
         } else if (component_element->GetName() == string("accelerometer")) {
           Components->push_back(new FGAccelerometer(this, component_element));
+        } else if (component_element->GetName() == string("magnetometer")) {
+          Components->push_back(new FGMagnetometer(this, component_element));
         } else if (component_element->GetName() == string("gyro")) {
           Components->push_back(new FGGyro(this, component_element));
         } else {
index 79535f261dda2c0b83edf5fee016cbb668637722..8d4f521c123572eef87ee88afbc170994d927a22 100644 (file)
@@ -41,10 +41,10 @@ INCLUDES
 #include <vector>
 
 #include <string>
-#include <models/flight_control/FGFCSComponent.h>
-#include <models/FGModel.h>
-#include <models/FGLGear.h>
-#include <input_output/FGXMLFileRead.h>
+#include "models/flight_control/FGFCSComponent.h"
+#include "models/FGModel.h"
+#include "models/FGLGear.h"
+#include "input_output/FGXMLFileRead.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index e6b32b6e00ec1ccd967d4f7b35397210a78653de..3b1278fa4bd1b9332663f7445f854e61a9482a8d 100644 (file)
@@ -35,11 +35,11 @@ HISTORY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <FGFDMExec.h>
-#include <models/FGAuxiliary.h>
-#include <models/FGAtmosphere.h>
-#include <models/FGInertial.h>
-#include <models/FGMassBalance.h>
+#include "FGFDMExec.h"
+#include "models/FGAuxiliary.h"
+#include "models/FGAtmosphere.h"
+#include "models/FGInertial.h"
+#include "models/FGMassBalance.h"
 #include "FGGasCell.h"
 
 using std::cerr;
index fa7021ff474bd8a54f9691077164847f9c292b7b..0ad485cee3928530fec98ce46a86ce543a17d180 100644 (file)
@@ -39,11 +39,11 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <FGJSBBase.h>
-#include <input_output/FGXMLElement.h>
-#include <math/FGColumnVector3.h>
-#include <models/propulsion/FGForce.h>
-#include <math/FGFunction.h>
+#include "FGJSBBase.h"
+#include "input_output/FGXMLElement.h"
+#include "math/FGColumnVector3.h"
+#include "models/propulsion/FGForce.h"
+#include "math/FGFunction.h"
 
 #include <string>
 using std::string;
index 4a430144d6045966df1d64b3c98dc2a95d5cd849..36837004a6a387a682c019391ddefd0e0c59070f 100644 (file)
@@ -39,7 +39,7 @@ INCLUDES
 #include <iomanip>
 
 #include "FGGroundReactions.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
 
 namespace JSBSim {
 
@@ -95,8 +95,8 @@ bool FGGroundReactions::Run(void)
   // Perhaps there is some commonality for things which only need to be
   // calculated once.
   for (unsigned int i=0; i<lGear.size(); i++) {
-    vForces  += lGear[i]->Force();
-    vMoments += lGear[i]->Moment();
+    vForces  += lGear[i]->GetBodyForces();
+    vMoments += lGear[i]->GetMoments();
   }
 
   return false;
index 9ad5ae8365fc91aa17fe1c0cf6f48a5f6ecadedb..a5785d6ca72139060cf1daf39966e87169b8bb02 100644 (file)
@@ -42,8 +42,8 @@ INCLUDES
 
 #include "FGModel.h"
 #include "FGLGear.h"
-#include <math/FGColumnVector3.h>
-#include <input_output/FGXMLElement.h>
+#include "math/FGColumnVector3.h"
+#include "input_output/FGXMLElement.h"
 
 #define ID_GROUNDREACTIONS "$Id$"
 
index 6db0555e0caadb99f7f71b04eec9ef7dab84db59..a14245bca5dfc3cc115dc2bcb08ae427b8bd01ef 100644 (file)
@@ -36,7 +36,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGInertial.h"
-#include <FGFDMExec.h>
+#include "FGFDMExec.h"
 #include "FGPropagate.h"
 #include "FGState.h"
 #include "FGMassBalance.h"
index f17d0c7ffdf29358706cec523820be76acdd6cab..cf457923636242ad26510d8eb416bcae13dfcc89 100644 (file)
@@ -41,7 +41,7 @@ INCLUDES
 #include <vector>
 
 #include "FGModel.h"
-#include <math/FGColumnVector3.h>
+#include "math/FGColumnVector3.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index e36abc27161ddc988d0500f874be369f6cdcfd17..4715ad05a4f10660ee0d0ed6532473de3830182e 100755 (executable)
@@ -90,8 +90,7 @@ bool FGInput::InitModel(void)
 bool FGInput::Run(void)
 {
   string line, token, info_string;
-  int start=0, string_start=0, string_end=0;
-  int token_start=0, token_end=0;
+  size_t start=0, string_start=0, string_end=0;
   char buf[100];
   double value=0;
   FGPropertyManager* node=0;
@@ -181,7 +180,7 @@ bool FGInput::Run(void)
       } else if (command == "info") {                   // INFO
 
         // get info about the sim run and/or aircraft, etc.
-        sprintf(buf, "%8.3f\0", State->Getsim_time());
+        sprintf(buf, "%8.3f", State->Getsim_time());
         info_string  = "JSBSim version: " + JSBSim_version + "\n";
         info_string += "Config File version: " + needed_cfg_version + "\n";
         info_string += "Aircraft simulated: " + Aircraft->GetAircraftName() + "\n";
index 2344c3a799bd4ea95717459b748804e51d393469..840b24d663dad4a5fdfbef309d9ed948a9c49376 100755 (executable)
@@ -43,8 +43,8 @@ INCLUDES
 #include <iostream>
 #include <fstream>
 
-#include <input_output/FGfdmSocket.h>
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGfdmSocket.h"
+#include "input_output/FGXMLElement.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index e3cfeadf21f44c6eed4f0fa465332458e9b7c55b..7df378b83cad4de07c1414cc6cfc077065876d2f 100644 (file)
@@ -55,13 +55,17 @@ GLOBAL DATA
 static const char *IdSrc = "$Id$";
 static const char *IdHdr = ID_LGEAR;
 
+// Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
+// ft instead of inches)
+const FGMatrix33 FGLGear::Tb2s(-1./inchtoft, 0., 0., 0., 1./inchtoft, 0., 0., 0., -1./inchtoft);
+
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
-  GearNumber(number),
-  Exec(fdmex)
+  FGForce(fdmex),
+  GearNumber(number)
 {
   Element *force_table=0;
   Element *dampCoeff=0;
@@ -81,7 +85,8 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
   } else if (sContactType == "STRUCTURE") {
     eContactType = ctSTRUCTURE;
   } else {
-    eContactType = ctUNKNOWN;
+    // Unknown contact point types will be treated as STRUCTURE.
+    eContactType = ctSTRUCTURE;
   }
 
   if (el->FindElement("spring_coeff"))
@@ -125,7 +130,7 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
   while (force_table) {
     force_type = force_table->GetAttributeValue("type");
     if (force_type == "CORNERING_COEFF") {
-      ForceY_Table = new FGTable(Exec->GetPropertyManager(), force_table);
+      ForceY_Table = new FGTable(fdmex->GetPropertyManager(), force_table);
     } else {
       cerr << "Undefined force table for " << name << " contact point" << endl;
     }
@@ -139,8 +144,37 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
   else sSteerType = "STEERABLE";
 
   Element* element = el->FindElement("location");
-  if (element) vXYZ = element->FindElementTripletConvertTo("IN");
+  if (element) vXYZn = element->FindElementTripletConvertTo("IN");
   else {cerr << "No location given for contact " << name << endl; exit(-1);}
+  SetTransformType(FGForce::tCustom);
+
+  element = el->FindElement("orientation");
+  if (element && (eContactType == ctBOGEY)) {
+    vGearOrient = element->FindElementTripletConvertTo("RAD");
+
+    double cp,sp,cr,sr,cy,sy;
+
+    cp=cos(vGearOrient(ePitch)); sp=sin(vGearOrient(ePitch));
+    cr=cos(vGearOrient(eRoll));  sr=sin(vGearOrient(eRoll));
+    cy=cos(vGearOrient(eYaw));   sy=sin(vGearOrient(eYaw));
+
+    mTGear(1,1) =  cp*cy;
+    mTGear(2,1) =  cp*sy;
+    mTGear(3,1) = -sp;
+
+    mTGear(1,2) = sr*sp*cy - cr*sy;
+    mTGear(2,2) = sr*sp*sy + cr*cy;
+    mTGear(3,2) = sr*cp;
+
+    mTGear(1,3) = cr*sp*cy + sr*sy;
+    mTGear(2,3) = cr*sp*sy - sr*cy;
+    mTGear(3,3) = cr*cp;
+  }
+  else {
+    mTGear(1,1) = 1.;
+    mTGear(2,2) = 1.;
+    mTGear(3,3) = 1.;
+  }
 
   if      (sBrakeGroup == "LEFT"  ) eBrakeGrp = bgLeft;
   else if (sBrakeGroup == "RIGHT" ) eBrakeGrp = bgRight;
@@ -178,7 +212,13 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
     }
   }
 
-  State = Exec->GetState();
+  State       = fdmex->GetState();
+  Aircraft    = fdmex->GetAircraft();
+  Propagate   = fdmex->GetPropagate();
+  Auxiliary   = fdmex->GetAuxiliary();
+  FCS         = fdmex->GetFCS();
+  MassBalance = fdmex->GetMassBalance();
+
   LongForceLagFilterCoeff = 1/State->Getdt(); // default longitudinal force filter coefficient
   LatForceLagFilterCoeff  = 1/State->Getdt(); // default lateral force filter coefficient
 
@@ -213,13 +253,6 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
 // Add some AI here to determine if gear is located properly according to its
 // brake group type ??
 
-  State       = Exec->GetState();
-  Aircraft    = Exec->GetAircraft();
-  Propagate   = Exec->GetPropagate();
-  Auxiliary   = Exec->GetAuxiliary();
-  FCS         = Exec->GetFCS();
-  MassBalance = Exec->GetMassBalance();
-
   WOW = lastWOW = false;
   ReportEnable = true;
   FirstContact = false;
@@ -229,11 +262,9 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
   MaximumStrutForce = MaximumStrutTravel = 0.0;
   SinkRate = GroundSpeed = 0.0;
 
-  vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
-
+  vWhlBodyVec = MassBalance->StructuralToBody(vXYZn);
   vLocalGear = Propagate->GetTb2l() * vWhlBodyVec;
-
-  vLocalWhlVel.InitMatrix();
+  vWhlVelVec.InitMatrix();
 
   compressLength  = 0.0;
   compressSpeed   = 0.0;
@@ -263,36 +294,38 @@ FGLGear::~FGLGear()
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-FGColumnVector3& FGLGear::Force(void)
+FGColumnVector3& FGLGear::GetBodyForces(void)
 {
-  double t = Exec->GetState()->Getsim_time();
-  dT = State->Getdt()*Exec->GetGroundReactions()->GetRate();
+  double t = fdmex->GetState()->Getsim_time();
+  dT = State->Getdt()*fdmex->GetGroundReactions()->GetRate();
 
-  vForce.InitMatrix();
-  vLocalForce.InitMatrix();
-  vMoment.InitMatrix();
+  vFn.InitMatrix();
 
   if (isRetractable) ComputeRetractionState();
 
   if (GearDown) {
+    double verticalZProj = 0.;
 
-    vWhlBodyVec = MassBalance->StructuralToBody(vXYZ); // Get wheel in body frame
+    vWhlBodyVec = MassBalance->StructuralToBody(vXYZn); // Get wheel in body frame
     vLocalGear = Propagate->GetTb2l() * vWhlBodyVec; // Get local frame wheel location
 
     gearLoc = Propagate->GetLocation().LocalToLocation(vLocalGear);
     // Compute the height of the theoretical location of the wheel (if strut is not compressed) with
     // respect to the ground level
-    double height = Exec->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel);
+    double height = fdmex->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel);
     vGroundNormal = -1. * Propagate->GetTec2b() * normal;
 
+    // The height returned above is the AGL and is expressed in the Z direction of the local
+    // coordinate frame. We now need to transform this height in actual compression of the strut (BOGEY)
+    // of in the normal direction to the ground (STRUCTURE)
     switch (eContactType) {
     case ctBOGEY:
-      // Project the height in the local coordinate frame of the strut to compute the actual compression
-      // length. The strut is assumed to be parallel to Z in the body frame.
-      compressLength = vGroundNormal(eZ) < 0.0 ? height / vGroundNormal(eZ) : 0.0;
+      verticalZProj = (Propagate->GetTb2l()*mTGear*FGColumnVector3(0.,0.,1.))(eZ);
+      compressLength = verticalZProj > 0.0 ? -height / verticalZProj : 0.0;
       break;
     case ctSTRUCTURE:
-      compressLength = -height;
+      verticalZProj = (Propagate->GetTec2l()*normal)(eZ);
+      compressLength = fabs(verticalZProj) > 0.0 ? -height / verticalZProj : 0.0;
       break;
     }
 
@@ -303,20 +336,28 @@ FGColumnVector3& FGLGear::Force(void)
       // [The next equation should really use the vector to the contact patch of
       // the tire including the strut compression and not the original vWhlBodyVec.]
 
-      FGColumnVector3 vWhlContactVec = vWhlBodyVec - FGColumnVector3(0., 0., compressLength);
-      vWhlVelVec      =  Propagate->GetPQR() * vWhlContactVec;
-      vWhlVelVec     +=  Propagate->GetUVW() - Propagate->GetTec2b() * cvel;
+      FGColumnVector3 vWhlDisplVec = mTGear * FGColumnVector3(0., 0., compressLength);
+      FGColumnVector3 vWhlContactVec = vWhlBodyVec - vWhlDisplVec;
+      vActingXYZn = vXYZn - Tb2s * vWhlDisplVec;
+      FGColumnVector3 vBodyWhlVel  = Propagate->GetPQR() * vWhlContactVec;
+      vBodyWhlVel += Propagate->GetUVW() - Propagate->GetTec2b() * cvel;
+
+      vWhlVelVec = mTGear.Transposed() * vBodyWhlVel;
 
       InitializeReporting();
       ComputeSteeringAngle();
       ComputeGroundCoordSys();
 
-      vLocalWhlVel = Tb2g * vWhlVelVec;
+      vLocalWhlVel = Transform().Transposed() * vBodyWhlVel;
 
-      compressSpeed = -vLocalWhlVel(eZ);
-      if (eContactType == ctBOGEY)
-        // Project the compression speed in the local coordinate frame of the strut
-        compressSpeed /= -vGroundNormal(eZ);
+      switch (eContactType) {
+      case ctBOGEY:
+        // Compression speed along the strut
+        compressSpeed = -vWhlVelVec(eZ);
+      case ctSTRUCTURE:
+        // Compression speed along the ground normal
+        compressSpeed = -vLocalWhlVel(eX);
+      }
 
       ComputeVerticalStrutForce();
 
@@ -325,15 +366,15 @@ FGColumnVector3& FGLGear::Force(void)
         ComputeSlipAngle();
         ComputeBrakeForceCoefficient();
         ComputeSideForceCoefficient();
-        double sign = vLocalWhlVel(eX)>0?1.0:(vLocalWhlVel(eX)<0?-1.0:0.0);
-        vLocalForce(eX) = - ((1.0 - TirePressureNorm) * 30 + vLocalForce(eZ) * BrakeFCoeff) * sign;
-        vLocalForce(eY) = vLocalForce(eZ) * FCoeff;
+        double sign = vLocalWhlVel(eY)>0?1.0:(vLocalWhlVel(eY)<0?-1.0:0.0);
+        vFn(eY) = - ((1.0 - TirePressureNorm) * 30 + vFn(eX) * BrakeFCoeff) * sign;
+        vFn(eZ) = vFn(eX) * FCoeff;
       }
       else if (eContactType == ctSTRUCTURE) {
         FGColumnVector3 vSlipVec = vLocalWhlVel;
-        vSlipVec(eZ) = 0.;
+        vSlipVec(eX) = 0.;
         vSlipVec.Normalize();
-        vLocalForce -= staticFCoeff * vLocalForce(eZ) * vSlipVec;
+        vFn -= staticFCoeff * vFn(eX) * vSlipVec;
       }
 
       // Lag and attenuate the XY-plane forces dependent on velocity. This code
@@ -343,19 +384,14 @@ FGColumnVector3& FGLGear::Force(void)
       // If a coefficient is set to something equal to or less than zero, the
       // filter is bypassed.
 
-      if (LongForceLagFilterCoeff > 0) vLocalForce(eX) = LongForceFilter.execute(vLocalForce(eX));
-      if (LatForceLagFilterCoeff > 0)  vLocalForce(eY) = LatForceFilter.execute(vLocalForce(eY));
+      if (LongForceLagFilterCoeff > 0) vFn(eY) = LongForceFilter.execute(vFn(eY));
+      if (LatForceLagFilterCoeff > 0)  vFn(eZ) = LatForceFilter.execute(vFn(eZ));
 
-      if ((fabs(vLocalWhlVel(eX)) <= RFRV) && RFRV > 0) vLocalForce(eX) *= fabs(vLocalWhlVel(eX))/RFRV;
-      if ((fabs(vLocalWhlVel(eY)) <= SFRV) && SFRV > 0) vLocalForce(eY) *= fabs(vLocalWhlVel(eY))/SFRV;
+      if ((fabs(vLocalWhlVel(eY)) <= RFRV) && RFRV > 0) vFn(eY) *= fabs(vLocalWhlVel(eY))/RFRV;
+      if ((fabs(vLocalWhlVel(eZ)) <= SFRV) && SFRV > 0) vFn(eZ) *= fabs(vLocalWhlVel(eZ))/SFRV;
 
       // End section for attenuating gear jitter
 
-      // Transform the forces back to the body frame and compute the moment.
-
-      vForce  = Tg2b * vLocalForce;
-      vMoment = vWhlContactVec * vForce;
-
     } else { // Gear is NOT compressed
 
       WOW = false;
@@ -363,8 +399,8 @@ FGColumnVector3& FGLGear::Force(void)
       compressSpeed = 0.0;
 
       // Let wheel spin down slowly
-      vLocalWhlVel(eX) -= 13.0*dT;
-      if (vLocalWhlVel(eX) < 0.0) vLocalWhlVel(eX) = 0.0;
+      vWhlVelVec(eX) -= 13.0*dT;
+      if (vWhlVelVec(eX) < 0.0) vWhlVelVec(eX) = 0.0;
 
       // Return to neutral position between 1.0 and 0.8 gear pos.
       SteerAngle *= max(GetGearUnitPos()-0.8, 0.0)/0.2;
@@ -381,64 +417,46 @@ FGColumnVector3& FGLGear::Force(void)
 
   lastWOW = WOW;
 
-  return vForce;
+  return FGForce::GetBodyForces();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 // Build a local "ground" coordinate system defined by
-//  eX : projection of the rolling direction on the ground
-//  eY : projection of the sliping direction on the ground
-//  eZ : normal to the ground
+//  eX : normal to the ground
+//  eY : projection of the rolling direction on the ground
+//  eZ : projection of the sliping direction on the ground
 
 void FGLGear::ComputeGroundCoordSys(void)
 {
-  FGColumnVector3 vRollingGroundVec;
+  // Euler angles are built up to create a local frame to describe the forces
+  // applied to the gear by the ground. Here pitch, yaw and roll do not have
+  // any physical meaning. It is just a convenient notation.
+  // First, "pitch" and "yaw" are determined in order to align eX with the
+  // ground normal.
+  if (vGroundNormal(eZ) < -1.0)
+    vOrient(ePitch) = 0.5*M_PI;
+  else if (1.0 < vGroundNormal(eZ))
+    vOrient(ePitch) = -0.5*M_PI;
+  else
+    vOrient(ePitch) = asin(-vGroundNormal(eZ));
+
+  if (fabs(vOrient(ePitch)) == 0.5*M_PI)
+    vOrient(eYaw) = 0.;
+  else
+    vOrient(eYaw) = atan2(vGroundNormal(eY), vGroundNormal(eX));
+  
+  vOrient(eRoll) = 0.;
+  UpdateCustomTransformMatrix();
 
   if (eContactType == ctBOGEY) {
-    // Compute the rolling direction projected on the ground
-    // It consists in finding a vector 'r' such that 'r' lies in the plane (w,z) and r.n = 0 (scalar
-    // product) where:
-    // 'n' is the normal to the ground,
-    // (x,y,z) are the directions defined in the body coord system
-    // and 'w' is 'x' rotated by the steering angle (SteerAngle) in the plane (x,y). 
-    // r = u * w + v * z and r.n = 0 => v/u = -w.n/z.n = a
-    // We also want u**2+v**2=1 and u > 0 (i.e. r orientated in the same 'direction' than w)
-    // after some arithmetic, one finds that :
-    double a = -(vGroundNormal(eX)*cos(SteerAngle)+vGroundNormal(eY)*sin(SteerAngle)) / vGroundNormal(eZ);
-    double u = 1. / sqrt(1. + a*a);
-    double v = a * u;
-    vRollingGroundVec = FGColumnVector3(u * cos(SteerAngle), u * sin(SteerAngle), v);
-  }
-  else {
-    // Here the only significant direction is the normal to the ground "vGroundNormal". Since there is
-    // no wheel the 2 other vectors of the orthonormal basis are not meaningful and are only used to
-    // create the transformation matrix Tg2b. So we are building vRollingGroundVec as an arbitrary
-    // vector normal to vGroundNormal
-    if (fabs(vGroundNormal(eX)) > 0.)
-      vRollingGroundVec = FGColumnVector3(-vGroundNormal(eZ)/vGroundNormal(eX), 0., 1.);
-    else if (fabs(vGroundNormal(eY)) > 0.)
-      vRollingGroundVec = FGColumnVector3(0., -vGroundNormal(eZ)/vGroundNormal(eY), 1.);
-    else
-      vRollingGroundVec = FGColumnVector3(1., 0., -vGroundNormal(eX)/vGroundNormal(eZ));
+    // In the case of a bogey, the third angle "roll" is used to align the axis eY and eZ
+    // to the rolling and sliping direction respectively.
+    FGColumnVector3 updatedRollingAxis = Transform().Transposed() * mTGear
+                                       * FGColumnVector3(-sin(SteerAngle), cos(SteerAngle), 0.);
 
-    vRollingGroundVec.Normalize();
+    vOrient(eRoll) = atan2(updatedRollingAxis(eY), -updatedRollingAxis(eZ));
+    UpdateCustomTransformMatrix();
   }
-
-  // The sliping direction is the cross product multiplication of the ground normal and rolling
-  // directions
-  FGColumnVector3 vSlipGroundVec = vGroundNormal * vRollingGroundVec;
-
-  Tg2b(1,1) = vRollingGroundVec(eX);
-  Tg2b(2,1) = vRollingGroundVec(eY);
-  Tg2b(3,1) = vRollingGroundVec(eZ);
-  Tg2b(1,2) = vSlipGroundVec(eX);
-  Tg2b(2,2) = vSlipGroundVec(eY);
-  Tg2b(3,2) = vSlipGroundVec(eZ);
-  Tg2b(1,3) = vGroundNormal(eX);
-  Tg2b(2,3) = vGroundNormal(eY);
-  Tg2b(3,3) = vGroundNormal(eZ);
-
-  Tb2g = Tg2b.Transposed();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -450,7 +468,7 @@ void FGLGear::ComputeRetractionState(void)
     GearUp   = true;
     WOW      = false;
     GearDown = false;
-    vLocalWhlVel.InitMatrix();
+    vWhlVelVec.InitMatrix();
   } else if (gearPos > 0.99) {
     GearDown = true;
     GearUp   = false;
@@ -465,7 +483,7 @@ void FGLGear::ComputeRetractionState(void)
 void FGLGear::ComputeSlipAngle(void)
 {
   // Calculate tire slip angle.
-  WheelSlip = -atan2(vLocalWhlVel(eY), fabs(vLocalWhlVel(eX)))*radtodeg;
+  WheelSlip = -atan2(vLocalWhlVel(eZ), fabs(vLocalWhlVel(eY)))*radtodeg;
 
   // Filter the wheel slip angle
   if (WheelSlipLagFilterCoeff > 0) WheelSlip = WheelSlipFilter.execute(WheelSlip);
@@ -485,7 +503,7 @@ void FGLGear::ComputeSteeringAngle(void)
     SteerAngle = 0.0;
     break;
   case stCaster:
-    SteerAngle = atan2(fabs(vWhlVelVec(eX)), vWhlVelVec(eY));
+    SteerAngle = atan2(vWhlVelVec(eY), fabs(vWhlVelVec(eX)));
     break;
   default:
     cerr << "Improper steering type membership detected for this gear." << endl;
@@ -540,7 +558,7 @@ void FGLGear::InitializeReporting(void)
 
 void FGLGear::ReportTakeoffOrLanding(void)
 {
-  double deltaT = State->Getdt()*Exec->GetGroundReactions()->GetRate();
+  double deltaT = State->Getdt()*fdmex->GetGroundReactions()->GetRate();
 
   if (FirstContact)
     LandingDistanceTraveled += Auxiliary->GetVground()*deltaT;
@@ -553,7 +571,7 @@ void FGLGear::ReportTakeoffOrLanding(void)
   if ( ReportEnable
        && Auxiliary->GetVground() <= 0.05
        && !LandingReported
-       && Exec->GetGroundReactions()->GetWOW())
+       && fdmex->GetGroundReactions()->GetWOW())
   {
     if (debug_lvl > 0) Report(erLand);
   }
@@ -561,7 +579,7 @@ void FGLGear::ReportTakeoffOrLanding(void)
   if ( ReportEnable
        && !TakeoffReported
        && (Propagate->GetDistanceAGL() - vLocalGear(eZ)) > 50.0
-       && !Exec->GetGroundReactions()->GetWOW())
+       && !fdmex->GetGroundReactions()->GetWOW())
   {
     if (debug_lvl > 0) Report(erTakeoff);
   }
@@ -575,8 +593,8 @@ void FGLGear::ReportTakeoffOrLanding(void)
 void FGLGear::CrashDetect(void)
 {
   if ( (compressLength > 500.0 ||
-      vForce.Magnitude() > 100000000.0 ||
-      vMoment.Magnitude() > 5000000000.0 ||
+      vFn.Magnitude() > 100000000.0 ||
+      GetMoments().Magnitude() > 5000000000.0 ||
       SinkRate > 1.4666*30 ) && !State->IntegrationSuspended())
   {
     PutMessage("Crash Detected: Simulation FREEZE.");
@@ -678,10 +696,10 @@ void FGLGear::ComputeVerticalStrutForce(void)
   switch (eContactType) {
   case ctBOGEY:
     // Project back the strut force in the local coordinate frame of the ground
-    vLocalForce(eZ) =  StrutForce / vGroundNormal(eZ);
+    vFn(eX) = StrutForce / (mTGear.Transposed()*vGroundNormal)(eZ);
     break;
   case ctSTRUCTURE:
-    vLocalForce(eZ) = -StrutForce;
+    vFn(eX) = -StrutForce;
     break;
   }
 
@@ -711,30 +729,33 @@ void FGLGear::bind(void)
   base_property_name = CreateIndexedPropertyName("gear/unit", GearNumber);
   if (eContactType == ctBOGEY) {
     property_name = base_property_name + "/slip-angle-deg";
-    Exec->GetPropertyManager()->Tie( property_name.c_str(), &WheelSlip );
+    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &WheelSlip );
     property_name = base_property_name + "/WOW";
-    Exec->GetPropertyManager()->Tie( property_name.c_str(), &WOW );
+    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &WOW );
     property_name = base_property_name + "/wheel-speed-fps";
-    Exec->GetPropertyManager()->Tie( property_name.c_str(), (FGLGear*)this,
+    fdmex->GetPropertyManager()->Tie( property_name.c_str(), (FGLGear*)this,
                           &FGLGear::GetWheelRollVel);
     property_name = base_property_name + "/z-position";
-    Exec->GetPropertyManager()->Tie( property_name.c_str(), (FGLGear*)this,
-                          &FGLGear::GetZPosition, &FGLGear::SetZPosition);
+    fdmex->GetPropertyManager()->Tie( property_name.c_str(), (FGForce*)this,
+                          &FGForce::GetLocationZ, &FGForce::SetLocationZ);
     property_name = base_property_name + "/compression-ft";
-    Exec->GetPropertyManager()->Tie( property_name.c_str(), &compressLength );
+    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &compressLength );
     property_name = base_property_name + "/side_friction_coeff";
-    Exec->GetPropertyManager()->Tie( property_name.c_str(), &FCoeff );
+    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &FCoeff );
 
     property_name = base_property_name + "/static_friction_coeff";
-    Exec->GetPropertyManager()->Tie( property_name.c_str(), &staticFCoeff );
+    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &staticFCoeff );
 
+    if (eSteerType == stCaster) {
+      property_name = base_property_name + "/steering-angle-rad";
+      fdmex->GetPropertyManager()->Tie( property_name.c_str(), &SteerAngle );
+    }
   }
 
   if( isRetractable ) {
     property_name = base_property_name + "/pos-norm";
-    Exec->GetPropertyManager()->Tie( property_name.c_str(), &GearPos );
+    fdmex->GetPropertyManager()->Tie( property_name.c_str(), &GearPos );
   }
-
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -746,7 +767,7 @@ void FGLGear::Report(ReportType repType)
   switch(repType) {
   case erLand:
     cout << endl << "Touchdown report for " << name << " (WOW at time: "
-         << Exec->GetState()->Getsim_time() << " seconds)" << endl;
+         << fdmex->GetState()->Getsim_time() << " seconds)" << endl;
     cout << "  Sink rate at contact:  " << SinkRate                << " fps,    "
                                 << SinkRate*0.3048          << " mps"     << endl;
     cout << "  Contact ground speed:  " << GroundSpeed*.5925       << " knots,  "
@@ -761,18 +782,20 @@ void FGLGear::Report(ReportType repType)
     break;
   case erTakeoff:
     cout << endl << "Takeoff report for " << name << " (Liftoff at time: "
-         << Exec->GetState()->Getsim_time() << " seconds)" << endl;
+         << fdmex->GetState()->Getsim_time() << " seconds)" << endl;
     cout << "  Distance traveled:                " << TakeoffDistanceTraveled
          << " ft,     " << TakeoffDistanceTraveled*0.3048  << " meters"  << endl;
     cout << "  Distance traveled (over 50'):     " << TakeoffDistanceTraveled50ft
          << " ft,     " << TakeoffDistanceTraveled50ft*0.3048 << " meters" << endl;
-    cout << "  [Altitude (ASL): " << Exec->GetPropagate()->GetAltitudeASL() << " ft. / "
-         << Exec->GetPropagate()->GetAltitudeASLmeters() << " m  | Temperature: "
-         << Exec->GetAtmosphere()->GetTemperature() - 459.67 << " F / "
-         << RankineToCelsius(Exec->GetAtmosphere()->GetTemperature()) << " C]" << endl;
-    cout << "  [Velocity (KCAS): " << Exec->GetAuxiliary()->GetVcalibratedKTS() << "]" << endl;
+    cout << "  [Altitude (ASL): " << fdmex->GetPropagate()->GetAltitudeASL() << " ft. / "
+         << fdmex->GetPropagate()->GetAltitudeASLmeters() << " m  | Temperature: "
+         << fdmex->GetAtmosphere()->GetTemperature() - 459.67 << " F / "
+         << RankineToCelsius(fdmex->GetAtmosphere()->GetTemperature()) << " C]" << endl;
+    cout << "  [Velocity (KCAS): " << fdmex->GetAuxiliary()->GetVcalibratedKTS() << "]" << endl;
     TakeoffReported = true;
     break;
+  case erNone:
+    break;
   }
 }
 
@@ -802,7 +825,7 @@ void FGLGear::Debug(int from)
   if (debug_lvl & 1) { // Standard console startup message output
     if (from == 0) { // Constructor - loading and initialization
       cout << "    " << sContactType << " " << name          << endl;
-      cout << "      Location: "         << vXYZ          << endl;
+      cout << "      Location: "         << vXYZn          << endl;
       cout << "      Spring Constant:  " << kSpring       << endl;
 
       if (eDampType == dtLinear)
index b7e2f1b83de5e55c08728bc9c8a47ad66a5a90e4..14f57510c2a339a95cfd49f7c1c6e9db8e7f5cc9 100644 (file)
@@ -38,11 +38,11 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <FGJSBBase.h>
-#include <FGFDMExec.h>
-#include <input_output/FGXMLElement.h>
-#include <math/FGColumnVector3.h>
-#include <math/FGTable.h>
+#include "FGFDMExec.h"
+#include "models/propulsion/FGForce.h"
+#include "input_output/FGXMLElement.h"
+#include "math/FGColumnVector3.h"
+#include "math/FGTable.h"
 #include <string>
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -199,7 +199,7 @@ CLASS DOCUMENTATION
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGLGear : public FGJSBBase
+class FGLGear : public FGForce
 {
 public:
   /// Brake grouping enumerators
@@ -207,7 +207,7 @@ public:
   /// Steering group membership enumerators
   enum SteerType {stSteer, stFixed, stCaster};
   /// Contact point type
-  enum ContactType {ctBOGEY, ctSTRUCTURE, ctUNKNOWN};
+  enum ContactType {ctBOGEY, ctSTRUCTURE};
   /// Report type enumerators
   enum ReportType {erNone=0, erTakeoff, erLand};
   /// Damping types
@@ -222,9 +222,7 @@ public:
   ~FGLGear();
 
   /// The Force vector for this gear
-  FGColumnVector3& Force(void);
-  /// The Moment vector for this gear
-  FGColumnVector3& Moment(void) {return vMoment;}
+  FGColumnVector3& GetBodyForces(void);
 
   /// Gets the location of the gear in Body axes
   FGColumnVector3& GetBodyLocation(void) { return vWhlBodyVec; }
@@ -269,35 +267,34 @@ public:
   int GetBrakeGroup(void) const { return (int)eBrakeGrp; }
   int GetSteerType(void) const  { return (int)eSteerType; }
 
-  double GetZPosition(void) const { return vXYZ(3); }
-  void SetZPosition(double z) { vXYZ(3) = z; }
-
-  bool GetSteerable(void) const { return eSteerType != stFixed; }
+  bool GetSteerable(void) const        { return eSteerType != stFixed; }
   bool GetRetractable(void) const      { return isRetractable;   }
   bool GetGearUnitUp(void) const       { return GearUp;          }
   bool GetGearUnitDown(void) const     { return GearDown;        }
-  double GetWheelSideForce(void) const { return vLocalForce(eY); }
-  double GetWheelRollForce(void) const { return vLocalForce(eX); }
-  double GetWheelSideVel(void) const   { return vWhlVelVec(eY);  }
-  double GetWheelRollVel(void) const   { return vWhlVelVec(eX);  }
-  double GetBodyXForce(void) const     { return vForce(eX);      }
-  double GetBodyYForce(void) const     { return vForce(eY);      }
+  double GetWheelRollForce(void) {
+    FGColumnVector3 vForce = mTGear.Transposed() * FGForce::GetBodyForces();
+    return vForce(eX)*cos(SteerAngle) + vForce(eY)*sin(SteerAngle); }
+  double GetWheelSideForce(void) {
+    FGColumnVector3 vForce = mTGear.Transposed() * FGForce::GetBodyForces();
+    return vForce(eY)*cos(SteerAngle) - vForce(eX)*sin(SteerAngle); }
+  double GetWheelRollVel(void) const   { return vWhlVelVec(eX)*cos(SteerAngle)
+                                              + vWhlVelVec(eY)*sin(SteerAngle);  }
+  double GetWheelSideVel(void) const   { return vWhlVelVec(eY)*cos(SteerAngle)
+                                              - vWhlVelVec(eX)*sin(SteerAngle);  }
   double GetWheelSlipAngle(void) const { return WheelSlip;       }
-  double GetWheelVel(int axis) const          { return vWhlVelVec(axis);}
-  bool IsBogey(void) const                    { return (eContactType == ctBOGEY);}
+  double GetWheelVel(int axis) const   { return vWhlVelVec(axis);}
+  bool IsBogey(void) const             { return (eContactType == ctBOGEY);}
   double GetGearUnitPos(void);
 
   void bind(void);
 
 private:
   int GearNumber;
-  FGMatrix33 Tg2b, Tb2g;
-  FGColumnVector3 vXYZ;
-  FGColumnVector3 vMoment;
+  static const FGMatrix33 Tb2s;
+  FGMatrix33 mTGear;
+  FGColumnVector3 vGearOrient;
   FGColumnVector3 vWhlBodyVec;
   FGColumnVector3 vLocalGear;
-  FGColumnVector3 vForce;
-  FGColumnVector3 vLocalForce;
   FGColumnVector3 vWhlVelVec, vLocalWhlVel;     // Velocity of this wheel
   FGColumnVector3 normal, cvel, vGroundNormal;
   FGLocation contact, gearLoc;
@@ -358,7 +355,6 @@ private:
   Filter LatForceFilter;
   Filter WheelSlipFilter;
 
-  FGFDMExec*     Exec;
   FGState*       State;
   FGAircraft*    Aircraft;
   FGPropagate*   Propagate;
index 2b599ffcc9947186f3ee5dfbbfb56b7a5e30c479..a3b0d60fce4974b38faaadae6edbc1979d4527f0 100644 (file)
@@ -41,7 +41,7 @@ INCLUDES
 #include "FGMassBalance.h"
 #include "FGPropulsion.h"
 #include "FGBuoyantForces.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
 
 namespace JSBSim {
 
index 9abb191721c6472a373678313745ef3af50e284b..46f99e4351728d30f4d507a5a148f0bb083b9c55 100644 (file)
@@ -39,9 +39,9 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGModel.h"
-#include <math/FGColumnVector3.h>
-#include <math/FGMatrix33.h>
-#include <input_output/FGXMLElement.h>
+#include "math/FGColumnVector3.h"
+#include "math/FGMatrix33.h"
+#include "input_output/FGXMLElement.h"
 #include <vector>
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 1464296aabd417599295eac0f3d2c33f770171c4..859db0b418744f1234380cf1215d7b9e63735836 100644 (file)
@@ -38,9 +38,9 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <FGJSBBase.h>
-#include <input_output/FGPropertyManager.h>
-#include <input_output/FGXMLElement.h>
+#include "FGJSBBase.h"
+#include "input_output/FGPropertyManager.h"
+#include "input_output/FGXMLElement.h"
 
 #include <iostream>
 #include <string>
index 4a34a5c22d2c6680ef5f11c70032a62f50f3f13a..87d7cee245a8eecf268f8ab2d21b5ca7d3e5996b 100644 (file)
@@ -162,8 +162,8 @@ bool FGOutput::InitModel(void)
   if (!FGModel::InitModel()) return false;
 
   if (Filename.size() > 0 && StartNewFile) {
-    int idx = BaseFilename.find_last_of(".");
-    int len = BaseFilename.length();
+    size_t idx = BaseFilename.find_last_of(".");
+    size_t len = BaseFilename.length();
     string extension = "";
     if (idx != string::npos) {
       extension = BaseFilename.substr(idx, len-idx);
@@ -1084,6 +1084,7 @@ void FGOutput::Debug(int from)
         cout << scratch << " in CSV format output at rate " << 1/(State->Getdt()*rate) << " Hz" << endl;
         break;
       case otNone:
+      default:
         cout << "  No log output" << endl;
         break;
       }
index 93d6d4749e89f14dc7d80ce6195d21547a4bec79..432ec509b81b7ace10a4e6f65a20d02b2f55b5f3 100644 (file)
@@ -57,12 +57,12 @@ INCLUDES
 #include <iomanip>
 
 #include "FGPropagate.h"
-#include <FGFDMExec.h>
-#include <FGState.h>
+#include "FGFDMExec.h"
+#include "FGState.h"
 #include "FGAircraft.h"
 #include "FGMassBalance.h"
 #include "FGInertial.h"
-#include <input_output/FGPropertyManager.h>
+#include "input_output/FGPropertyManager.h"
 
 namespace JSBSim {
 
index 6de7d11c4a0921f964e90531f7d54edc921e7c1c..c8400531870c6c46568cc272f83a01a5516605fd 100644 (file)
@@ -38,11 +38,11 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <models/FGModel.h>
-#include <math/FGColumnVector3.h>
-#include <math/FGLocation.h>
-#include <math/FGQuaternion.h>
-#include <math/FGMatrix33.h>
+#include "models/FGModel.h"
+#include "math/FGColumnVector3.h"
+#include "math/FGLocation.h"
+#include "math/FGQuaternion.h"
+#include "math/FGMatrix33.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -538,6 +538,6 @@ private:
 }
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-#include <initialization/FGInitialCondition.h>
+#include "initialization/FGInitialCondition.h"
 
 #endif
index ed066b26c3ecf2fce85daa4b7f6cefff87737166..88fbff084ee37506ed727c0b2fd61cfcef316023 100644 (file)
@@ -45,14 +45,14 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGPropulsion.h"
-#include <models/propulsion/FGRocket.h>
-#include <models/propulsion/FGTurbine.h>
-#include <models/propulsion/FGPiston.h>
-#include <models/propulsion/FGElectric.h>
-#include <models/propulsion/FGTurboProp.h>
-#include <input_output/FGPropertyManager.h>
-#include <input_output/FGXMLParse.h>
-#include <math/FGColumnVector3.h>
+#include "models/propulsion/FGRocket.h"
+#include "models/propulsion/FGTurbine.h"
+#include "models/propulsion/FGPiston.h"
+#include "models/propulsion/FGElectric.h"
+#include "models/propulsion/FGTurboProp.h"
+#include "input_output/FGPropertyManager.h"
+#include "input_output/FGXMLParse.h"
+#include "math/FGColumnVector3.h"
 #include <sstream>
 
 namespace JSBSim {
@@ -255,6 +255,20 @@ bool FGPropulsion::Load(Element* el)
 
   FGModel::Load(el); // Perform base class Load.
 
+  // Process tank definitions first to establish the number of fuel tanks
+
+  Element* tank_element = el->FindElement("tank");
+  while (tank_element) {
+    Tanks.push_back(new FGTank(FDMExec, tank_element, numTanks));
+    if (Tanks.back()->GetType() == FGTank::ttFUEL) numFuelTanks++;
+    else if (Tanks.back()->GetType() == FGTank::ttOXIDIZER) numOxiTanks++;
+    else {cerr << "Unknown tank type specified." << endl; return false;}
+    numTanks++;
+    tank_element = el->FindNextElement("tank");
+  }
+  numSelectedFuelTanks = numFuelTanks;
+  numSelectedOxiTanks  = numOxiTanks;
+
   Element* engine_element = el->FindElement("engine");
   while (engine_element) {
     engine_filename = engine_element->GetAttributeValue("file");
@@ -303,20 +317,6 @@ bool FGPropulsion::Load(Element* el)
     ResetParser();
   }
 
-  // Process tank definitions
-
-  Element* tank_element = el->FindElement("tank");
-  while (tank_element) {
-    Tanks.push_back(new FGTank(FDMExec, tank_element, numTanks));
-    if (Tanks.back()->GetType() == FGTank::ttFUEL) numFuelTanks++;
-    else if (Tanks.back()->GetType() == FGTank::ttOXIDIZER) numOxiTanks++;
-    else {cerr << "Unknown tank type specified." << endl; return false;}
-    numTanks++;
-    tank_element = el->FindNextElement("tank");
-  }
-  numSelectedFuelTanks = numFuelTanks;
-  numSelectedOxiTanks  = numOxiTanks;
-
   CalculateTankInertias();
   if (!ThrottleAdded) FCS->AddThrottle(); // need to have at least one throttle
 
index e356c0b154a5b1a7d560f6f0de3ce1674dfcb726..3ef37afec42e122035a6a6fc58519f6bcac100ec 100644 (file)
@@ -42,10 +42,10 @@ INCLUDES
 #include <fstream>
 
 #include "FGModel.h"
-#include <models/propulsion/FGEngine.h>
-#include <models/propulsion/FGTank.h>
-#include <math/FGMatrix33.h>
-#include <input_output/FGXMLFileRead.h>
+#include "models/propulsion/FGEngine.h"
+#include "models/propulsion/FGTank.h"
+#include "math/FGMatrix33.h"
+#include "input_output/FGXMLFileRead.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 02de74903d684d5892d531818031770c60f84a8b..1765388a7e9a75bb97965b817ddc401e34c6241f 100755 (executable)
@@ -40,7 +40,7 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <models/FGAtmosphere.h>
+#include "models/FGAtmosphere.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index c07a789655e417c5121d23c10582271ce00f472f..5f4bba35083f89c1ce51bcc7e7211232338c5a6f 100755 (executable)
@@ -38,7 +38,7 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <models/FGAtmosphere.h>
+#include "models/FGAtmosphere.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index b2c3ca573b25024accc64934e8f64db259d612af..e5c529de5f507b8f8c7c6a99934dbb8075c13e21 100755 (executable)
@@ -48,7 +48,9 @@ static const char *IdHdr = ID_ACCELEROMETER;
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGAccelerometer::FGAccelerometer(FGFCS* fcs, Element* element) : FGSensor(fcs, element)
+FGAccelerometer::FGAccelerometer(FGFCS* fcs, Element* element)
+  : FGSensor(fcs, element),
+    FGSensorOrientation(element)
 {
   Propagate = fcs->GetExec()->GetPropagate();
   MassBalance = fcs->GetExec()->GetMassBalance();
@@ -60,27 +62,6 @@ FGAccelerometer::FGAccelerometer(FGFCS* fcs, Element* element) : FGSensor(fcs, e
 
   vRadius = MassBalance->StructuralToBody(vLocation);
 
-  Element* orient_element = element->FindElement("orientation");
-  if (orient_element) vOrient = orient_element->FindElementTripletConvertTo("RAD");
-  else {cerr << "No orientation given for accelerometer. " << 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 accelerometer; assuming X axis" << endl;
-      axis = 1;
-    }
-  }
-
-  CalculateTransformMatrix();
-
   Debug(0);
 }
 
@@ -96,7 +77,7 @@ FGAccelerometer::~FGAccelerometer()
 bool FGAccelerometer::Run(void )
 {
   // There is no input assumed. This is a dedicated acceleration sensor.
-  
+
   vRadius = MassBalance->StructuralToBody(vLocation);
     
   //gravitational forces
@@ -112,59 +93,11 @@ bool FGAccelerometer::Run(void )
 
   Input = vAccel(axis);
 
-  Output = Input; // perfect accelerometer
-
-  // Degrade signal as specified
-
-  if (fail_stuck) {
-    Output = PreviousOutput;
-    return true;
-  }
-
-  if (lag != 0.0)            Lag();       // models accelerometer 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;
+  ProcessSensorSignal();
 
-  if (bits != 0)             Quantize();  // models quantization degradation
-//  if (delay != 0.0)          Delay();     // models system signal transport latencies
-
-  Clip(); // Is it right to clip an accelerometer?
   return true;
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGAccelerometer::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 accelerometer 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
index bf3a58c6e666b8f461071b580706f52a05a78b04..d552fe434de6846fbcadf270ec7e643ab817ff1f 100755 (executable)
@@ -38,12 +38,13 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGSensor.h"
-#include <input_output/FGXMLElement.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"
+#include "FGSensorOrientation.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -116,7 +117,7 @@ time.
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGAccelerometer  : public FGSensor
+class FGAccelerometer  : public FGSensor, public FGSensorOrientation
 {
 public:
   FGAccelerometer(FGFCS* fcs, Element* element);
@@ -129,12 +130,8 @@ private:
   FGMassBalance* MassBalance;
   FGInertial* Inertial;
   FGColumnVector3 vLocation;
-  FGColumnVector3 vOrient;
   FGColumnVector3 vRadius;
   FGColumnVector3 vAccel;
-  FGMatrix33 mT;
-  void CalculateTransformMatrix(void);
-  int axis;
   
   void Debug(int from);
 };
index 9b0a3cc8a6da773b1b56cc330e349739ba12cb04..e7ba4205f5953490d323d2ba3ce7e563f647c6e3 100755 (executable)
@@ -52,7 +52,6 @@ CLASS IMPLEMENTATION
 FGActuator::FGActuator(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
 {
   double denom;
-  dt = fcs->GetDt();
 
   // inputs are read from the base class constructor
 
@@ -101,8 +100,6 @@ FGActuator::~FGActuator()
 
 bool FGActuator::Run(void )
 {
-  dt = fcs->GetDt();
-
   Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
 
   if (fail_zero) Input = 0;
@@ -237,7 +234,10 @@ void FGActuator::Debug(int from)
       else
         cout << "      INPUT: " << InputNodes[0]->getName() << endl;
 
-      if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
+      if (IsOutput) {
+        for (unsigned int i=0; i<OutputNodes.size(); i++)
+          cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
+      }
       if (bias != 0.0) cout << "      Bias: " << bias << endl;
       if (rate_limit != 0) cout << "      Rate limit: " << rate_limit << endl;
       if (lag != 0) cout << "      Actuator lag: " << lag << endl;
index 79571fbe66107ec926384c296c0cc4537e38d152..ecfb3bf8af0dfb72688cca59029b714ddd95224d 100755 (executable)
@@ -38,7 +38,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCSComponent.h"
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGXMLElement.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -144,7 +144,6 @@ public:
   inline bool GetFailStuck(void) const {return fail_stuck;}
   
 private:
-  double dt;
   double span;
   double bias;
   double rate_limit;
index 745f8ad281d5804fa14fa14ae82b0c2009ea7c35..babd910e2acfe26fe34ce8563d41bc75e9df026b 100644 (file)
@@ -144,7 +144,10 @@ void FGDeadBand::Debug(int from)
         cout << "      DEADBAND WIDTH: " << width << endl;
       }
       cout << "      GAIN: " << gain << endl;
-      if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
+      if (IsOutput) {
+        for (unsigned int i=0; i<OutputNodes.size(); i++)
+          cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
+      }
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
index d07b88cc4fbaacb33ac0afef4808f8e220eb7015..82523bdc56207a11b6e0bacfda215612142b1a84 100644 (file)
@@ -38,7 +38,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCSComponent.h"
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGXMLElement.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 954be235449c224144106c6681bd269155efd94a..e2e4e1b9520a49ecc4f85fb52b4f6e053761b01c 100644 (file)
@@ -52,11 +52,13 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
 {
   Element *input_element, *clip_el;
   Input = Output = clipmin = clipmax = 0.0;
-  OutputNode = treenode = 0;
+  treenode = 0;
+  delay = index = 0;
   ClipMinPropertyNode = ClipMaxPropertyNode = 0;
   clipMinSign = clipMaxSign = 1.0;
   IsOutput   = clip = false;
   string input, clip_string;
+  dt = fcs->GetDt();
 
   PropertyManager = fcs->GetPropertyManager();
   if        (element->GetName() == string("lag_filter")) {
@@ -91,6 +93,8 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
     Type = "SENSOR";
   } else if (element->GetName() == string("accelerometer")) {
     Type = "ACCELEROMETER";
+  } else if (element->GetName() == string("magnetometer")) {
+    Type = "MAGNETOMETER";
   } else if (element->GetName() == string("gyro")) {
     Type = "GYRO";
   } else if (element->GetName() == string("actuator")) {
@@ -123,13 +127,34 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
     input_element = element->FindNextElement("input");
   }
 
-  if (element->FindElement("output")) {
+  Element *out_elem = element->FindElement("output");
+  while (out_elem) {
     IsOutput = true;
-    OutputNode = PropertyManager->GetNode( element->FindElementValue("output"), true );
+    string output_node_name = out_elem->GetDataLine();
+    FGPropertyManager* OutputNode = PropertyManager->GetNode( output_node_name, true );
+    OutputNodes.push_back(OutputNode);
     if (!OutputNode) {
-      cerr << endl << "  Unable to process property: " << element->FindElementValue("output") << endl;
+      cerr << endl << "  Unable to process property: " << output_node_name << endl;
       throw(string("Invalid output property name in flight control definition"));
     }
+    out_elem = element->FindNextElement("output");
+  }
+
+  Element* delay_elem = element->FindElement("delay");
+  if ( delay_elem ) {
+    delay = (unsigned int)delay_elem->GetDataAsNumber();
+    string delayType = delay_elem->GetAttributeValue("type");
+    if (delayType.length() > 0) {
+      if (delayType == "time") {
+        delay = (int)(delay / dt);
+      } else {
+        cerr << "Unallowed delay type" << endl;
+      }
+    } else {
+      delay = (int)(delay / dt);
+    }
+    output_array.resize(delay);
+    for (int i=0; i<delay; i++) output_array[i] = 0.0;
   }
 
   clip_el = element->FindElement("clipto");
@@ -171,7 +196,7 @@ FGFCSComponent::~FGFCSComponent()
 
 void FGFCSComponent::SetOutput(void)
 {
-  OutputNode->setDoubleValue(Output);
+  for (unsigned int i=0; i<OutputNodes.size(); i++) OutputNodes[i]->setDoubleValue(Output);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -183,6 +208,16 @@ bool FGFCSComponent::Run(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+void FGFCSComponent::Delay(void)
+{
+  output_array[index] = Output;
+  if (index == delay-1) index = 0;
+  else index++;
+  Output = output_array[index];
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 void FGFCSComponent::Clip(void)
 {
   if (clip) {
@@ -258,6 +293,8 @@ void FGFCSComponent::Debug(int from)
           cout << "      Maximum limit: " << clipmax << endl;
         }
       }  
+      if (delay > 0) cout <<"      Frame delay: " << delay
+                                   << " frames (" << delay*dt << " sec)" << endl;
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
index fa8506131c560864e080b16b692c624e0ad41e1e..f64b204c35b24f756851a2d12a1a08ad7328f708 100644 (file)
@@ -37,9 +37,9 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <FGJSBBase.h>
-#include <input_output/FGPropertyManager.h>
-#include <input_output/FGXMLElement.h>
+#include "FGJSBBase.h"
+#include "input_output/FGPropertyManager.h"
+#include "input_output/FGXMLElement.h"
 #include <string>
 #include <vector>
 
@@ -101,30 +101,34 @@ public:
 
   virtual bool Run(void);
   virtual void SetOutput(void);
-  inline double GetOutput (void) const {return Output;}
-  inline FGPropertyManager* GetOutputNode(void) { return OutputNode; }
-  inline string GetName(void) const {return Name;}
-  inline string GetType(void) const { return Type; }
+  double GetOutput (void) const {return Output;}
+  string GetName(void) const {return Name;}
+  string GetType(void) const { return Type; }
   virtual double GetOutputPct(void) const { return 0; }
 
 protected:
   FGFCS* fcs;
   FGPropertyManager* PropertyManager;
   FGPropertyManager* treenode;
-  FGPropertyManager* OutputNode;
+  vector <FGPropertyManager*> OutputNodes;
   FGPropertyManager* ClipMinPropertyNode;
   FGPropertyManager* ClipMaxPropertyNode;
   vector <FGPropertyManager*> InputNodes;
   vector <float> InputSigns;
+  vector <double> output_array;
   string Type;
   string Name;
   double Input;
   double Output;
   double clipmax, clipmin;
+  int delay;
+  int index;
   float clipMinSign, clipMaxSign;
+  double dt;
   bool IsOutput;
   bool clip;
 
+  void Delay(void);
   void Clip(void);
   virtual void bind();
   virtual void Debug(int from);
index ea86d4114c2d7ea1c11dc27275154fdc8b8de0d6..b8512bb41e268c04bc895d26e4e7f35b6913f083 100755 (executable)
@@ -119,7 +119,10 @@ void FGFCSFunction::Debug(int from)
       if (InputNodes.size()>0)
         cout << "      INPUT: " << InputNodes[0]->getName() << endl;
 //    cout << "      Function: " << endl;
-      if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
+      if (IsOutput) {
+        for (unsigned int i=0; i<OutputNodes.size(); i++)
+          cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
+      }
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
index 422d0b0930e9bead004bc09759b82ac32f0d420c..fe731e8c3f25a8db1ee566ae5b8c9625a2f52ec6 100755 (executable)
@@ -38,8 +38,8 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCSComponent.h"
-#include <input_output/FGXMLElement.h>
-#include <math/FGFunction.h>
+#include "input_output/FGXMLElement.h"
+#include "math/FGFunction.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 99793923871efc2c86870efa0de2613352a62f14..6122e15d0c9408e4973288555d66efc6ce9ce814 100644 (file)
@@ -50,7 +50,6 @@ CLASS IMPLEMENTATION
 
 FGFilter::FGFilter(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
 {
-  dt = fcs->GetState()->Getdt();
   Trigger = 0;
   DynamicFilter = false;
 
@@ -323,8 +322,13 @@ void FGFilter::Debug(int from)
           if (PropertyNode[1] == 0L) cout << "      C[1]: " << C[1] << endl;
           else cout << "      C[1] is the value of property: " << sgn << PropertyNode[1]->GetName() << endl;
           break;
+        case eUnknown:
+          break;
        } 
-      if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
+      if (IsOutput) {
+        for (unsigned int i=0; i<OutputNodes.size(); i++)
+          cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
+      }
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
index c7c0a4143b2933d523f06bbffb6c461a7cc706e0..5e7f10b74a5606c77d5821d431f430b75ed52d48 100644 (file)
@@ -38,7 +38,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCSComponent.h"
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGXMLElement.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -249,7 +249,6 @@ public:
   enum {eLag, eLeadLag, eOrder2, eWashout, eIntegrator, eUnknown} FilterType;
 
 private:
-  double dt;
   double ca;
   double cb;
   double cc;
index f8f73daf38d0bc5171ee75140e14555514ac7b2d..f72e6c4f44f724b16910b0d0e609f5f7c01b04c5 100644 (file)
@@ -212,7 +212,10 @@ void FGGain::Debug(int from)
       } else {
         cout << "      GAIN: " << Gain << endl;
       }
-      if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
+      if (IsOutput) {
+        for (unsigned int i=0; i<OutputNodes.size(); i++)
+          cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
+      }
       if (Type == "AEROSURFACE_SCALE") {
         cout << "      In/Out Mapping:" << endl;
         cout << "        Input MIN: " << InMin << endl;
index faf535c6908444e7317710e2941d3557c69b707a..543a3d88332dc8cd6f34af1379c57420d28fe787 100644 (file)
@@ -39,8 +39,8 @@ INCLUDES
 
 #include "FGFCSComponent.h"
 #include <string>
-#include <input_output/FGXMLElement.h>
-#include <math/FGTable.h>
+#include "input_output/FGXMLElement.h"
+#include "math/FGTable.h"
 
 using std::string;
 
index 0d2ad21db0f7a2e16998292159c524e9dca962ae..ce7dac4f8042ddf48c0a53089a281dcf2d24fe74 100644 (file)
@@ -38,7 +38,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCSComponent.h"
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGXMLElement.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 0fcd127e836fdc5885a778c74e7fe9645e9b9169..f48af626c0b3813b3f61ac007919a36b515a9e9b 100755 (executable)
@@ -48,31 +48,11 @@ static const char *IdHdr = ID_GYRO;
 CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-FGGyro::FGGyro(FGFCS* fcs, Element* element) : FGSensor(fcs, element)
+FGGyro::FGGyro(FGFCS* fcs, Element* element) : FGSensor(fcs, element),
+                                               FGSensorOrientation(element)
 {
   Propagate = fcs->GetExec()->GetPropagate();
   
-  Element* orient_element = element->FindElement("orientation");
-  if (orient_element) vOrient = orient_element->FindElementTripletConvertTo("RAD");
-  else {cerr << "No orientation given for gyro. " << endl;}
-
-  Element* axis_element = element->FindElement("axis");
-  if (axis_element) {
-    string sAxis = element->FindElementValue("axis");
-    if (sAxis == "ROLL" || sAxis == "roll") {
-      axis = 1;
-    } else if (sAxis == "PITCH" || sAxis == "pitch") {
-      axis = 2;
-    } else if (sAxis == "YAW" || sAxis == "yaw") {
-      axis = 3;
-    } else {
-      cerr << "  Incorrect/no axis specified for gyro; assuming Roll axis" << endl;
-      axis = 1;
-    }
-  }
-
-  CalculateTransformMatrix();
-
   Debug(0);
 }
 
@@ -94,59 +74,11 @@ bool FGGyro::Run(void )
 
   Input = vAccel(axis);
 
-  Output = Input; // perfect gyro
-
-  // Degrade signal as specified
-
-  if (fail_stuck) {
-    Output = PreviousOutput;
-    return true;
-  }
-
-  if (lag != 0.0)            Lag();       // models gyro 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
+  ProcessSensorSignal();
 
-  Clip(); // Is it right to clip a gyro?
   return true;
 }
 
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGGyro::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 gyro 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
index c486eee5073a5a60724a49b2ccdf172750a8639a..af10851bfa463f8e091d96538bf36e4102d21511 100755 (executable)
@@ -38,12 +38,13 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGSensor.h"
-#include <input_output/FGXMLElement.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"
+#include "FGSensorOrientation.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -116,7 +117,7 @@ time.
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGGyro  : public FGSensor
+class FGGyro  : public FGSensor, public FGSensorOrientation
 {
 public:
   FGGyro(FGFCS* fcs, Element* element);
@@ -126,11 +127,8 @@ public:
 
 private:
   FGPropagate* Propagate;
-  FGColumnVector3 vOrient;
   FGColumnVector3 vAccel;
-  FGMatrix33 mT;
   void CalculateTransformMatrix(void);
-  int axis;
   
   void Debug(int from);
 };
index 5949cf710b7c2572824789ad84d8e306baea3d46..d25182a13933f312edd79234957c9e018eb7aebd 100644 (file)
@@ -98,13 +98,13 @@ FGKinemat::~FGKinemat()
 
 bool FGKinemat::Run(void )
 {
-  double dt = fcs->GetState()->Getdt();
+  double dt0 = dt;
 
   Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
 
   if (DoScale) Input *= Detents[NumDetents-1];
 
-  if (IsOutput) Output = OutputNode->getDoubleValue();
+  if (IsOutput) Output = OutputNodes[0]->getDoubleValue();
 
   if (Input < Detents[0])
     Input = Detents[0];
@@ -113,7 +113,7 @@ bool FGKinemat::Run(void )
 
   // Process all detent intervals the movement traverses until either the
   // final value is reached or the time interval has finished.
-  while ( 0.0 < dt && !EqualToRoundoff(Input, Output) ) {
+  while ( dt0 > 0.0 && !EqualToRoundoff(Input, Output) ) {
 
     // Find the area where Output is in
     int ind;
@@ -137,8 +137,8 @@ bool FGKinemat::Run(void )
       double ThisDt = fabs((ThisInput-Output)/Rate);
 
       // and clip to the timestep size
-      if (dt < ThisDt) {
-        ThisDt = dt;
+      if (dt0 < ThisDt) {
+        ThisDt = dt0;
         if (Output < Input)
           Output += ThisDt*Rate;
         else
@@ -148,7 +148,7 @@ bool FGKinemat::Run(void )
         // is met even in inexact arithmetics ...
         Output = ThisInput;
 
-      dt -= ThisDt;
+      dt0 -= ThisDt;
     }
   }
 
@@ -190,7 +190,10 @@ void FGKinemat::Debug(int from)
       for (int i=0;i<NumDetents;i++) {
         cout << "        " << Detents[i] << " " << TransitionTimes[i] << endl;
       }
-      if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
+      if (IsOutput) {
+        for (unsigned int i=0; i<OutputNodes.size(); i++)
+          cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
+      }
       if (!DoScale) cout << "      NOSCALE" << endl;
     }
   }
index 13d2ec7d967491de46c220ad22b386834d8d96db..f836567d1a5cce4f279b5bbca9db586ecac2b605 100644 (file)
@@ -38,7 +38,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCSComponent.h"
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGXMLElement.h"
 #include <vector>
 #include <string>
 
index 561e0dcca3aa82101cb966025f547ed3ddb39e2b..c4be3c471a58bcdcd35e04ea0bc88633a4db1e63 100755 (executable)
@@ -51,7 +51,8 @@ CLASS IMPLEMENTATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 
-FGMagnetometer::FGMagnetometer(FGFCS* fcs, Element* element) : FGSensor(fcs, element),\
+FGMagnetometer::FGMagnetometer(FGFCS* fcs, Element* element) : FGSensor(fcs, element),
+                                                               FGSensorOrientation(element),
                                                                counter(0),
                                                                INERTIAL_UPDATE_RATE(1000)
 {
@@ -65,27 +66,6 @@ FGMagnetometer::FGMagnetometer(FGFCS* fcs, Element* element) : FGSensor(fcs, ele
 
   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;
@@ -114,7 +94,7 @@ FGMagnetometer::~FGMagnetometer()
 void FGMagnetometer::updateInertialMag(void)
 {
   counter++;
-  if(counter > INERTIAL_UPDATE_RATE)//dont need to update every iteration
+  if (counter > INERTIAL_UPDATE_RATE)//dont need to update every iteration
   {
       counter = 0;
 
@@ -123,11 +103,11 @@ void FGMagnetometer::updateInertialMag(void)
       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 );
+      calc_magvar( usedLat,
+                   usedLon,
+                   usedAlt,
+                   date,
+                   field );
   }
 }
 
@@ -135,75 +115,25 @@ void FGMagnetometer::updateInertialMag(void)
 
 bool FGMagnetometer::Run(void )
 {
-  // There is no input assumed. This is a dedicated acceleration sensor.
+  // There is no input assumed. This is a dedicated magnetic field sensor.
   
   vRadius = MassBalance->StructuralToBody(vLocation);
 
-
   updateInertialMag();
-  //Inertial magnetic field rotated to the body frame
+
+  // Inertial magnetic field rotated to the body frame
   vMag = Propagate->GetTl2b() * FGColumnVector3(field[3], field[4], field[5]);
 
-  //allow for sensor orientation
+  // 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
+  ProcessSensorSignal();
 
-  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
index 456d14d6d356ae764fcd05331f29e284d639716c..e806fb62280a8b614203f30d24d3cd1649651020 100755 (executable)
@@ -38,12 +38,13 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGSensor.h"
-#include <input_output/FGXMLElement.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"
+#include "FGSensorOrientation.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -118,7 +119,7 @@ time.
 CLASS DECLARATION
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-class FGMagnetometer  : public FGSensor
+class FGMagnetometer  : public FGSensor, public FGSensorOrientation
 {
 public:
   FGMagnetometer(FGFCS* fcs, Element* element);
@@ -131,13 +132,9 @@ private:
   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;
index da1b4b0cd1a6f45c40f1465161d675947a0b6f85..7df31c67c466b71ea60a72b79528507f78e195eb 100755 (executable)
@@ -49,7 +49,6 @@ CLASS IMPLEMENTATION
 FGPID::FGPID(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
 {
   string kp_string, ki_string, kd_string;
-  dt = fcs->GetState()->Getdt();
 
   Kp = Ki = Kd = 0.0;
   KpPropertyNode = 0;
@@ -189,7 +188,10 @@ void FGPID::Debug(int from)
       else
         cout << "      INPUT: " << InputNodes[0]->getName() << endl;
 
-      if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
+      if (IsOutput) {
+        for (unsigned int i=0; i<OutputNodes.size(); i++)
+          cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
+      }
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
index 5839b238a2d75f4f1a7266e77da625bc2600ed3f..670c1af2373e39791069dbfc9c8f45a88c800dc2 100755 (executable)
@@ -39,7 +39,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCSComponent.h"
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGXMLElement.h"
 #include <string>
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -105,7 +105,6 @@ public:
   void ResetPastStates(void) {Input_prev = Input_prev2 = Output = I_out_total = 0.0;}
 
 private:
-  double dt;
   FGPropertyManager *Trigger;
   double Kp, Ki, Kd;
   double I_out_total;
index bd6a384179a172b913a4835db9513bfaa9508d51..d2f9243d92a49147fc03524deba9a2391d233af3 100755 (executable)
@@ -52,11 +52,10 @@ CLASS IMPLEMENTATION
 FGSensor::FGSensor(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
 {
   double denom;
-  dt = fcs->GetDt();
 
   // inputs are read from the base class constructor
 
-  bits = quantized = divisions = index = delay = 0;
+  bits = quantized = divisions = 0;
   PreviousInput = PreviousOutput = 0.0;
   min = max = bias = gain = noise_variance = lag = drift_rate = drift = span = 0.0;
   granularity = 0.0;
@@ -117,11 +116,6 @@ FGSensor::FGSensor(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
       cerr << "  defaulting to UNIFORM." << endl;
     }
   }
-  if ( element->FindElement("delay") ) {
-    delay = (unsigned int)element->FindElementValueAsNumber("delay");
-    output_array.resize(delay);
-    for (unsigned int i=0; i<delay; i++) output_array[i] = 0.0;
-  }
 
   FGFCSComponent::bind();
   bind();
@@ -138,34 +132,41 @@ FGSensor::~FGSensor()
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-bool FGSensor::Run(void )
+bool FGSensor::Run(void)
 {
   Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
 
+  ProcessSensorSignal();
+
+  return true;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGSensor::ProcessSensorSignal(void)
+{
   Output = Input; // perfect sensor
 
   // Degrade signal as specified
 
   if (fail_stuck) {
     Output = PreviousOutput;
-    return true;
-  }
-
-  if (lag != 0.0)            Lag();       // models sensor lag and filter
-  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 finite gain
+  } else {
+    if (lag != 0.0)            Lag();       // models sensor lag and filter
+    if (noise_variance != 0.0) Noise();     // models noise
+    if (drift_rate != 0.0)     Drift();     // models drift over time
+    if (gain != 0.0)           Gain();      // models a finite gain
+    if (bias != 0.0)           Bias();      // models a finite bias
 
-  if (delay != 0.0)          Delay();     // models system signal transport latencies
+    if (delay != 0)            Delay();     // models system signal transport latencies
 
-  if (fail_low)  Output = -HUGE_VAL;
-  if (fail_high) Output =  HUGE_VAL;
+    if (fail_low)  Output = -HUGE_VAL;
+    if (fail_high) Output =  HUGE_VAL;
 
-  if (bits != 0)             Quantize();  // models quantization degradation
+    if (bits != 0)             Quantize();  // models quantization degradation
 
-  Clip(); // Is it right to clip a sensor?
-  return true;
+    Clip();
+  }
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -237,16 +238,6 @@ void FGSensor::Lag(void)
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGSensor::Delay(void)
-{
-  output_array[index] = Output;
-  if (index == delay-1) index = 0;
-  else index++;
-  Output = output_array[index];
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
 void FGSensor::bind(void)
 {
   string tmp = Name;
@@ -301,8 +292,6 @@ void FGSensor::Debug(int from)
         else
           cout << "      INPUT: " << InputNodes[0]->getName() << endl;
       }
-      if (delay > 0) cout <<"      Frame delay: " << delay
-                                   << " frames (" << delay*dt << " sec)" << endl;
       if (bits != 0) {
         if (quant_property.empty())
           cout << "      Quantized output" << endl;
@@ -332,7 +321,10 @@ void FGSensor::Debug(int from)
           cout << "      Random noise is gaussian distributed." << endl;
         }
       }
-      if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
+      if (IsOutput) {
+        for (unsigned int i=0; i<OutputNodes.size(); i++)
+          cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
+      }
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
index 1e8701c90c5e1491a165c60ffee9e8036e5c0503..18699e966958eb99cc540f37c197a03e20acc8cd 100755 (executable)
@@ -38,7 +38,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCSComponent.h"
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGXMLElement.h"
 #include <vector>
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -135,7 +135,6 @@ public:
 protected:
   enum eNoiseType {ePercent=0, eAbsolute} NoiseType;
   enum eDistributionType {eUniform=0, eGaussian} DistributionType;
-  double dt;
   double min, max;
   double span;
   double bias;
@@ -153,20 +152,17 @@ protected:
   int bits;
   int quantized;
   int divisions;
-  int delay;
-  int index;
   bool fail_low;
   bool fail_high;
   bool fail_stuck;
   string quant_property;
-  vector <double> output_array;
 
+  void ProcessSensorSignal(void);
   void Noise(void);
   void Bias(void);
   void Drift(void);
   void Quantize(void);
   void Lag(void);
-  void Delay(void);
   void Gain(void);
 
   void bind(void);
diff --git a/src/FDM/JSBSim/models/flight_control/FGSensorOrientation.h b/src/FDM/JSBSim/models/flight_control/FGSensorOrientation.h
new file mode 100755 (executable)
index 0000000..cbd43de
--- /dev/null
@@ -0,0 +1,136 @@
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Header:       FGSensorOrientation.h
+ Author:       Jon Berndt
+ Date started: September 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 FGSENSORORIENTATION_H
+#define FGSENSORORIENTATION_H
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#include "FGSensor.h"
+#include "input_output/FGXMLElement.h"
+#include "math/FGColumnVector3.h"
+#include "math/FGMatrix33.h"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#define ID_SensorOrientation "$Id$"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+FORWARD DECLARATIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+namespace JSBSim {
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/** Encapsulates a SensorOrientation capability for a sensor.
+
+Syntax:
+
+@author Jon S. Berndt
+@version $Revision$
+*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DECLARATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+class FGSensorOrientation  : public FGJSBBase
+{
+public:
+  FGSensorOrientation(Element* element)
+  {
+    Element* orient_element = element->FindElement("orientation");
+    if (orient_element) vOrient = orient_element->FindElementTripletConvertTo("RAD");
+    else {cerr << "No orientation given for this sensor. " << 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 this sensor; assuming X axis" << endl;
+        axis = 1;
+      }
+    }
+
+    CalculateTransformMatrix();
+  }
+
+//  ~FGSensorOrientation();
+
+protected:
+  FGColumnVector3 vOrient;
+  FGMatrix33 mT;
+  int axis;
+  void 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 accelerometer frame. So, the next line is commented out.
+    // mT = mT.Inverse();
+  }
+
+private:
+  void Debug(int from);
+};
+}
+#endif
index 5071e7a2d1a440d87faf65af7940e84895858e3d..c8a1fcadc8d9fc17d1869704f2eae1a95124e409 100644 (file)
@@ -119,7 +119,10 @@ void FGSummer::Debug(int from)
           cout << "       " << InputNodes[i]->getName() << endl;
       }
       if (Bias != 0.0) cout << "       Bias: " << Bias << endl;
-      if (IsOutput) cout << "      OUTPUT: " <<OutputNode->getName() <<  endl;
+      if (IsOutput) {
+        for (unsigned int i=0; i<OutputNodes.size(); i++)
+          cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
+      }
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
index cc11352f50d42d976dbefe65d3f5c3d5f975bdb3..9ffeddb8e243898ef23f6c0691000a560345bef6 100644 (file)
@@ -38,7 +38,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCSComponent.h"
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGXMLElement.h"
 #include <vector>
 #include <string>
 
index 5ed272155b32175cfb68d8c89cac55937fcb642c..76b9fc1e6da8abde37a1b2a6b6c0219db83d99db 100644 (file)
@@ -261,7 +261,10 @@ void FGSwitch::Debug(int from)
         }
         cout << endl;
       }
-      if (IsOutput) cout << "      OUTPUT: " << OutputNode->getName() << endl;
+      if (IsOutput) {
+        for (unsigned int i=0; i<OutputNodes.size(); i++)
+          cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
+      }
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
index 4efec9dfbf141a29aa15a09042fa77af353bc7cd..a68c2c4a55829a24dd992a83e61885c70f36b52a 100644 (file)
@@ -38,8 +38,8 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFCSComponent.h"
-#include <input_output/FGXMLElement.h>
-#include <math/FGCondition.h>
+#include "input_output/FGXMLElement.h"
+#include "math/FGCondition.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index ca924fdd9d712c7237354a36c4765c8144e22868..2d7a1aa679b662c07229ec283724b8f622f2ca58 100644 (file)
@@ -9,6 +9,7 @@ libFlightControl_a_SOURCES = \
 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
+       FGSensor.h FGActuator.h FGAccelerometer.h FGGyro.h FGMagnetometer.h \
+       FGSensorOrientation.h
 
 INCLUDES = -I$(top_srcdir)/src/FDM/JSBSim
index 32b05ea19254b273b7fd1f40b69a1acb2cd35fed..255fb644d33223d3058777245e73cb57f52f7fdf 100644 (file)
@@ -40,7 +40,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGElectric.h"
-#include <models/FGPropulsion.h>
+#include "models/FGPropulsion.h"
 
 namespace JSBSim {
 
index ed5a93f57de26ade3ed4a1223bde9d0ab93b60c8..663a153f35d7041134e361f7310b543aee5bec4b 100644 (file)
@@ -39,7 +39,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGEngine.h"
-#include <input_output/FGXMLElement.h>
+#include "input_output/FGXMLElement.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index edddc11fa3947395f2f679ac44f0248bb0e71e0c..b46830aef47fcee1a188e8ecc0423cfc17e96b66 100644 (file)
@@ -41,8 +41,8 @@ INCLUDES
 #include "FGTank.h"
 #include "FGPropeller.h"
 #include "FGNozzle.h"
-#include <input_output/FGXMLParse.h>
-#include <math/FGColumnVector3.h>
+#include "input_output/FGXMLParse.h"
+#include "math/FGColumnVector3.h"
 #include <fstream>
 
 namespace JSBSim {
@@ -67,6 +67,7 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
   SLFuelFlowMax = 0.0;
   MaxThrottle = 1.0;
   MinThrottle = 0.0;
+  unsigned int i;
 
   ResetToIC(); // initialize dynamic terms
 
@@ -104,11 +105,17 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
     cerr << "No thruster definition supplied with engine definition." << endl;
   }
 
+  // Build and initialize the feed tank vector.
+  for (i=0; i<(Propulsion->GetNumTanks()); i++) {
+    SourceTanks.push_back(0);
+  }
+
   // Load feed tank[s] references
   local_element = engine_element->GetParent()->FindElement("feed");
   if (local_element) {
     while (local_element) {
-      AddFeedTank((int)local_element->GetDataAsNumber());
+      int tankID = (int)local_element->GetDataAsNumber();
+      AddFeedTank( tankID , Propulsion->GetTank(tankID)->GetPriority());
       local_element = engine_element->GetParent()->FindNextElement("feed");
     }
   } else {
@@ -165,35 +172,55 @@ void FGEngine::ConsumeFuel(void)
   if (TrimMode) return;
 
   unsigned int i;
-  double Fshortage, TanksWithFuel;
+  double Fshortage, TanksWithFuel, FuelNeeded;
   FGTank* Tank;
-  Fshortage = TanksWithFuel = 0.0;
+  Fshortage = TanksWithFuel = FuelNeeded = 0.0;
+  double FuelToBurn = CalcFuelNeed();
+  unsigned int CurrentPriority = 1;
+  vector <int> FeedList;
+  Starved = false;
+
+  while (FuelToBurn > 0.0) {
+
+    // Count how many fuel tanks with the current priority level have fuel.
+    // If none, then try next lower priority.  Build the feed list.
+    while ((TanksWithFuel == 0.0) && (CurrentPriority <= Propulsion->GetNumTanks())) {
+      for (i=0; i<Propulsion->GetNumTanks(); i++) {
+        Tank = Propulsion->GetTank(i);
+        if (Tank->GetType() == FGTank::ttFUEL) {
+          if ((Tank->GetContents() > 0.0) && ((unsigned int)Tank->GetPriority() == CurrentPriority)) {
+             ++TanksWithFuel;
+             FeedList.push_back(i);
+           } 
+        } else {
+           cerr << "No oxidizer tanks should be used for this engine type." << endl;
+        }
+      }
+      if (TanksWithFuel == 0.0) CurrentPriority++;
+    }
 
-  // count how many assigned tanks have fuel
-  for (i=0; i<SourceTanks.size(); i++) {
-    Tank = Propulsion->GetTank(SourceTanks[i]);
-    if (Tank->GetType() == FGTank::ttFUEL){
-      if (Tank->GetContents() > 0.0) ++TanksWithFuel;
-    } else {
-       cerr << "No oxidizer tanks should be used for this engine type." << endl;
+    // No fuel found at any priority!
+    if (TanksWithFuel == 0.0) {
+      Starved = true;
+      return;
     }
-  }
-  if (TanksWithFuel==0) {
-    Starved = true;
-    return;
-  }
 
-  for (i=0; i<SourceTanks.size(); i++) {
-    Tank = Propulsion->GetTank(SourceTanks[i]);
-    if (Tank->GetType() == FGTank::ttFUEL) {
-       Fshortage += Tank->Drain(CalcFuelNeed()/TanksWithFuel);
-    } else {
-       cerr << "No oxidizer tanks should be used for this engine type." << endl;
+    // Remove equal amount of fuel from each feed tank.  
+    FuelNeeded = FuelToBurn/TanksWithFuel;
+    for (i=0; i<FeedList.size(); i++) {
+      Tank = Propulsion->GetTank(FeedList[i]);
+      Tank->Drain(FuelNeeded); 
+      FuelToBurn -= FuelNeeded;
     }
-  }
 
-  if (Fshortage < 0.00) Starved = true;
-  else Starved = false;
+    // check if we were not able to burn all the fuel we needed to at this priority level
+    if (FuelToBurn > 0.001) {
+      CurrentPriority++;
+      TanksWithFuel = 0.0;
+      FeedList.clear();
+    }
+  }  // while
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -219,9 +246,9 @@ void FGEngine::SetPlacement(FGColumnVector3& location, FGColumnVector3& orientat
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-void FGEngine::AddFeedTank(int tkID)
+void FGEngine::AddFeedTank(int tkID, int priority)
 {
-  SourceTanks.push_back(tkID);
+  SourceTanks[tkID] = priority;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -244,7 +271,6 @@ bool FGEngine::LoadThruster(Element *thruster_element)
 {
   string token, fullpath, localpath;
   string thruster_filename, thruster_fullpathname, thrType;
-  double P_Factor = 0, Sense = 0.0;
   string enginePath = FDMExec->GetEnginePath();
   string aircraftPath = FDMExec->GetFullAircraftPath();
   ifstream thruster_file;
index 0e79e3a725d106c8ed219a88ca2c2ada3af5ffc5..66ad9bf93f8b7dafdbe16384aed3c63a17e4d8e1 100644 (file)
@@ -43,10 +43,10 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <FGJSBBase.h>
+#include "FGJSBBase.h"
 #include "FGThruster.h"
-#include <input_output/FGPropertyManager.h>
-#include <input_output/FGXMLFileRead.h>
+#include "input_output/FGPropertyManager.h"
+#include "input_output/FGXMLFileRead.h"
 #include <vector>
 #include <string>
 
@@ -159,7 +159,7 @@ public:
 
   virtual void SetRunning(bool bb) { Running=bb; }
   virtual void SetName(string name) { Name = name; }
-  virtual void AddFeedTank(int tkID);
+  virtual void AddFeedTank(int tkID, int priority);
   virtual void SetFuelFreeze(bool f) { FuelFreeze = f; }
 
   virtual void SetStarter(bool s) { Starter = s; }
@@ -244,16 +244,16 @@ protected:
   void Debug(int from);
 };
 }
-#include <FGState.h>
-#include <FGFDMExec.h>
-#include <models/FGAtmosphere.h>
-#include <models/FGFCS.h>
-#include <models/FGAircraft.h>
-#include <models/FGPropagate.h>
-#include <models/FGPropulsion.h>
-#include <models/FGAuxiliary.h>
-#include <models/propulsion/FGThruster.h>
-#include <input_output/FGXMLElement.h>
+#include "FGState.h"
+#include "FGFDMExec.h"
+#include "models/FGAtmosphere.h"
+#include "models/FGFCS.h"
+#include "models/FGAircraft.h"
+#include "models/FGPropagate.h"
+#include "models/FGPropulsion.h"
+#include "models/FGAuxiliary.h"
+#include "models/propulsion/FGThruster.h"
+#include "input_output/FGXMLElement.h"
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 #endif
index 9f39088d7788d5702fadb42a32d71e1c1f2487b8..4d907e3f41ae4dc258185428890da89014e557be 100644 (file)
@@ -41,11 +41,11 @@ and the cg.
 */
 
 #include "FGForce.h"
-#include <FGFDMExec.h>
-#include <models/FGAircraft.h>
-#include <models/FGPropagate.h>
-#include <models/FGMassBalance.h>
-#include <models/FGAerodynamics.h>
+#include "FGFDMExec.h"
+#include "models/FGAircraft.h"
+#include "models/FGPropagate.h"
+#include "models/FGMassBalance.h"
+#include "models/FGAerodynamics.h"
 
 namespace JSBSim {
 
@@ -55,8 +55,8 @@ static const char *IdHdr = ID_FORCE;
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 FGForce::FGForce(FGFDMExec *FDMExec) :
-                 ttype(tNone),
-                 fdmex(FDMExec)
+                 fdmex(FDMExec),
+                 ttype(tNone)
 {
   mT(1,1) = 1; //identity matrix
   mT(2,2) = 1;
@@ -112,23 +112,27 @@ FGMatrix33 FGForce::Transform(void)
 void FGForce::UpdateCustomTransformMatrix(void)
 {
   double cp,sp,cr,sr,cy,sy;
+  double srsp, crcy, crsy;
 
   cp=cos(vOrient(ePitch)); sp=sin(vOrient(ePitch));
   cr=cos(vOrient(eRoll));  sr=sin(vOrient(eRoll));
   cy=cos(vOrient(eYaw));   sy=sin(vOrient(eYaw));
 
+  srsp = sr*sp;
+  crcy = cr*cy;
+  crsy = cr*sy;
+
   mT(1,1) =  cp*cy;
-  mT(1,2) =  cp*sy;
-  mT(1,3) = -sp;
+  mT(2,1) =  cp*sy;
+  mT(3,1) = -sp;
 
-  mT(2,1) = sr*sp*cy - cr*sy;
-  mT(2,2) = sr*sp*sy + cr*cy;
-  mT(2,3) = sr*cp;
+  mT(1,2) = srsp*cy - crsy;
+  mT(2,2) = srsp*sy + crcy;
+  mT(3,2) = sr*cp;
 
-  mT(3,1) = cr*sp*cy + sr*sy;
-  mT(3,2) = cr*sp*sy - sr*cy;
+  mT(1,3) = crcy*sp + sr*sy;
+  mT(2,3) = crsy*sp - sr*cy;
   mT(3,3) = cr*cp;
-  mT = mT.Inverse();
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 0798d00e27c16184097449b2f6ef7151c318c72a..eb2f59506290ca98fc3f537fb81eea7262e335fd 100644 (file)
@@ -57,10 +57,10 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#include <FGFDMExec.h>
-#include <FGJSBBase.h>
-#include <math/FGMatrix33.h>
-#include <math/FGColumnVector3.h>
+#include "FGFDMExec.h"
+#include "FGJSBBase.h"
+#include "math/FGMatrix33.h"
+#include "math/FGColumnVector3.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -240,6 +240,9 @@ public:
 
   virtual FGColumnVector3& GetBodyForces(void);
 
+  inline double GetBodyXForce(void) const { return vFb(eX); }
+  inline double GetBodyYForce(void) const { return vFb(eY); }
+  inline double GetBodyZForce(void) const { return vFb(eZ); }
   inline FGColumnVector3& GetMoments(void) { return vM; }
 
   // Normal point of application, JSBsim structural coords
@@ -273,12 +276,12 @@ public:
   inline void SetLocation(FGColumnVector3 vv) { vXYZn = vv; SetActingLocation(vv);}
   inline void SetActingLocation(FGColumnVector3 vv) { vActingXYZn = vv; }
 
-  inline double GetLocationX( void ) { return vXYZn(eX);}
-  inline double GetLocationY( void ) { return vXYZn(eY);}
-  inline double GetLocationZ( void ) { return vXYZn(eZ);}
-  inline double GetActingLocationX( void ) { return vActingXYZn(eX);}
-  inline double GetActingLocationY( void ) { return vActingXYZn(eY);}
-  inline double GetActingLocationZ( void ) { return vActingXYZn(eZ);}
+  inline double GetLocationX( void ) const { return vXYZn(eX);}
+  inline double GetLocationY( void ) const { return vXYZn(eY);}
+  inline double GetLocationZ( void ) const { return vXYZn(eZ);}
+  inline double GetActingLocationX( void ) const { return vActingXYZn(eX);}
+  inline double GetActingLocationY( void ) const { return vActingXYZn(eY);}
+  inline double GetActingLocationZ( void ) const { return vActingXYZn(eZ);}
   FGColumnVector3& GetLocation(void) { return vXYZn; }
   FGColumnVector3& GetActingLocation(void) { return vActingXYZn; }
 
@@ -302,10 +305,10 @@ public:
   double GetYaw(void) const {return vOrient(eYaw);}
 
   inline FGColumnVector3& GetAnglesToBody(void) {return vOrient;}
-  inline double GetAnglesToBody(int axis) {return vOrient(axis);}
+  inline double GetAnglesToBody(int axis) const {return vOrient(axis);}
 
   inline void SetTransformType(TransformType ii) { ttype=ii; }
-  inline TransformType GetTransformType(void) { return ttype; }
+  inline TransformType GetTransformType(void) const { return ttype; }
 
   FGMatrix33 Transform(void);
 
index 78059bd2b2f58ae493fd30e6c5de2fb968cd03e4..45b0065c4588e1806a9a069f6532ed59e7d0e106 100644 (file)
@@ -38,7 +38,7 @@ INCLUDES
 #include <sstream>
 
 #include "FGNozzle.h"
-#include <models/FGAtmosphere.h>
+#include "models/FGAtmosphere.h"
 
 namespace JSBSim {
 
index 19150d4bbb2b31bd250078e5917d721e3a16133d..d2a0831ac3a38321484035ad766d43244805a0da 100644 (file)
@@ -43,7 +43,7 @@ INCLUDES
 #include <sstream>
 
 #include "FGPiston.h"
-#include <models/FGPropulsion.h>
+#include "models/FGPropulsion.h"
 #include "FGPropeller.h"
 
 namespace JSBSim {
@@ -61,7 +61,8 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
   rho_fuel(800),                 // estimate
   calorific_value_fuel(47.3e6),
   Cp_air(1005),                  // Specific heat (constant pressure) J/Kg/K
-  Cp_fuel(1700)
+  Cp_fuel(1700),
+  standard_pressure(101320.73)
 {
   string token;
 
@@ -87,6 +88,9 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
   Stroke = 4.375;
   Cylinders = 4;
   CompressionRatio = 8.5;
+  Z_airbox = -999;
+  Ram_Air_Factor = 1;
+  PeakMeanPistonSpeed_fps = 100;
 
   // These are internal program variables
 
@@ -102,6 +106,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
   BoostSpeed = 0;
   Boosted = false;
   BoostOverride = 0;
+  BoostManual = 0;
   bBoostOverride = false;
   bTakeoffBoost = false;
   TakeoffBoost = 0.0;   // Default to no extra takeoff-boost
@@ -187,10 +192,18 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
     Stroke = el->FindElementValueAsNumberConvertTo("stroke","IN");
   if (el->FindElement("cylinders"))
     Cylinders = el->FindElementValueAsNumber("cylinders");
+  if (el->FindElement("air-intake-impedance-factor"))
+    Z_airbox = el->FindElementValueAsNumber("air-intake-impedance-factor");
+  if (el->FindElement("ram-air-factor"))
+    Ram_Air_Factor  = el->FindElementValueAsNumber("ram-air-factor");
+  if (el->FindElement("peak-piston-speed"))
+    PeakMeanPistonSpeed_fps  = el->FindElementValueAsNumber("peak-piston-speed");
   if (el->FindElement("numboostspeeds")) { // Turbo- and super-charging parameters
     BoostSpeeds = (int)el->FindElementValueAsNumber("numboostspeeds");
     if (el->FindElement("boostoverride"))
       BoostOverride = (int)el->FindElementValueAsNumber("boostoverride");
+    if (el->FindElement("boostmanual"))
+      BoostManual = (int)el->FindElementValueAsNumber("boostmanual");
     if (el->FindElement("takeoffboost"))
       TakeoffBoost = el->FindElementValueAsNumberConvertTo("takeoffboost", "PSI");
     if (el->FindElement("ratedboost1"))
@@ -243,6 +256,14 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
   minMAP = MinManifoldPressure_inHg * inhgtopa;  // inHg to Pa
   maxMAP = MaxManifoldPressure_inHg * inhgtopa;
 
+// For throttle
+  RatedMeanPistonSpeed_fps =  ( MaxRPM * Stroke) / (360); // AKA 2 * (RPM/60) * ( Stroke / 12) or 2NS
+  if(Z_airbox < 998){
+    double Ze=RatedMeanPistonSpeed_fps/PeakMeanPistonSpeed_fps; // engine impedence
+    Z_airbox = (standard_pressure *Ze / maxMAP) - Ze; // impedence of airbox
+  }
+  Z_throttle=(((MaxRPM * Stroke) / 360)/((IdleRPM * Stroke) / 360))*(standard_pressure/minMAP - 1) - Z_airbox; // Constant for Throttle impedence
+
   string property_name, base_property_name;
   base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
   property_name = base_property_name + "/power-hp";
@@ -255,6 +276,12 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
   PropertyManager->Tie(property_name, &MAP);
   property_name = base_property_name + "/map-inhg";
   PropertyManager->Tie(property_name, &ManifoldPressure_inHg);
+  property_name = base_property_name + "/air-intake-impedance-factor";
+  PropertyManager->Tie(property_name, &Z_airbox);
+  property_name = base_property_name + "/ram-air-factor";
+  PropertyManager->Tie(property_name, &Ram_Air_Factor);
+  property_name = base_property_name + "/boost-speed";
+  PropertyManager->Tie(property_name, &BoostSpeed);
 
   // Set up and sanity-check the turbo/supercharging configuration based on the input values.
   if (TakeoffBoost > RatedBoost[0]) bTakeoffBoost = true;
@@ -302,6 +329,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
     BoostSpeed = 0;
   }
   bBoostOverride = (BoostOverride == 1 ? true : false);
+  bBoostManual   = (BoostManual   == 1 ? true : false);
   Debug(0); // Call Debug() routine from constructor if needed
 }
 
@@ -349,6 +377,8 @@ double FGPiston::Calculate(void)
   //
 
   p_amb = Atmosphere->GetPressure() * psftopa;
+  double p = Auxiliary->GetTotalPressure() * psftopa;
+  p_ram = (p - p_amb) * Ram_Air_Factor + p_amb;
   T_amb = RankineToKelvin(Atmosphere->GetTemperature());
 
   RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
@@ -488,15 +518,20 @@ void FGPiston::doEngineStartup(void)
 
 void FGPiston::doBoostControl(void)
 {
-  if(BoostSpeed < BoostSpeeds - 1) {
-    // Check if we need to change to a higher boost speed
-    if(p_amb < BoostSwitchPressure[BoostSpeed] - BoostSwitchHysteresis) {
-      BoostSpeed++;
-    }
-  } else if(BoostSpeed > 0) {
-    // Check if we need to change to a lower boost speed
-    if(p_amb > BoostSwitchPressure[BoostSpeed - 1] + BoostSwitchHysteresis) {
-      BoostSpeed--;
+  if(BoostManual) {
+    if(BoostSpeed > BoostSpeeds-1) BoostSpeed = BoostSpeeds-1;
+    if(BoostSpeed < 0) BoostSpeed = 0;
+  } else {
+    if(BoostSpeed < BoostSpeeds - 1) {
+      // Check if we need to change to a higher boost speed
+      if(p_amb < BoostSwitchPressure[BoostSpeed] - BoostSwitchHysteresis) {
+        BoostSpeed++;
+      }
+    } else if(BoostSpeed > 0) {
+      // Check if we need to change to a lower boost speed
+      if(p_amb > BoostSwitchPressure[BoostSpeed - 1] + BoostSwitchHysteresis) {
+        BoostSpeed--;
+      }
     }
   }
 }
@@ -518,15 +553,13 @@ void FGPiston::doBoostControl(void)
 
 void FGPiston::doMAP(void)
 {
- // estimate throttle plate area.
-  double throttle_area = ThrottleAngle*ThrottleAngle;
- // Internal Combustion Engine in Theory and Practice, Volume 2.  Charles Fayette Taylor.  Revised Edition, 1985 fig 6-13
-  double map_coefficient = 1-((MeanPistonSpeed_fps*MeanPistonSpeed_fps)/(24978*throttle_area));
+  double Zt =(1-Throttle)*(1-Throttle)*Z_throttle; // throttle impedence
+  double Ze= MeanPistonSpeed_fps > 0 ? PeakMeanPistonSpeed_fps/MeanPistonSpeed_fps : 999999; // engine impedence
 
-  if ( map_coefficient < 0.1 ) map_coefficient = 0.1;
+  double map_coefficient = Ze/(Ze+Z_airbox+Zt);
 
   // Add a one second lag to manifold pressure changes
-  double dMAP = (TMAP - p_amb * map_coefficient) * dt;
+  double dMAP = (TMAP - p_ram * map_coefficient) * dt;
   TMAP -=dMAP;
 
   // Find the mean effective pressure required to achieve this manifold pressure
@@ -548,8 +581,7 @@ void FGPiston::doMAP(void)
       }
     }
     // Boost the manifold pressure.
-    double boost_factor = BoostMul[BoostSpeed] * RPM/RatedRPM[BoostSpeed];
-    if (boost_factor < 1.0) boost_factor = 1.0;  // boost will never reduce the MAP
+    double boost_factor = (( BoostMul[BoostSpeed] - 1 ) / RatedRPM[BoostSpeed] ) * RPM + 1;
     MAP = TMAP * boost_factor;
     // Now clip the manifold pressure to BCV or Wastegate setting.
     if (bTakeoffPos) {
@@ -581,7 +613,7 @@ void FGPiston::doMAP(void)
 
 void FGPiston::doAirFlow(void)
 {
-  double gamma = 1.4; // specific heat constants
+  double gamma = 1.1; // specific heat constants
 // loss of volumentric efficiency due to difference between MAP and exhaust pressure
   double ve =((gamma-1)/gamma)+( CompressionRatio -(p_amb/MAP))/(gamma*( CompressionRatio - 1));
 
@@ -872,6 +904,7 @@ void FGPiston::Debug(int from)
       cout << "      MaxHP: "               << MaxHP                    << endl;
       cout << "      Cycles: "              << Cycles                   << endl;
       cout << "      IdleRPM: "             << IdleRPM                  << endl;
+      cout << "      MaxRPM: "              << MaxRPM                   << endl;
       cout << "      MaxThrottle: "         << MaxThrottle              << endl;
       cout << "      MinThrottle: "         << MinThrottle              << endl;
       cout << "      ISFC: "                << ISFC                     << endl;
index 4c40565a42ee346f23fbe0b4847611594691d087..cbcac27631318082b5e4ad25314511a20497171f 100644 (file)
@@ -40,8 +40,8 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGEngine.h"
-#include <math/FGTable.h>
-#include <input_output/FGXMLElement.h>
+#include "math/FGTable.h"
+#include "input_output/FGXMLElement.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
@@ -81,9 +81,10 @@ CLASS DOCUMENTATION
   <maxthrottle> {number} </maxthrottle>
   <minthrottle> {number} </minthrottle>
   <bsfc unit="{LBS/HP*HR | "KG/KW*HR"}"> {number} </bsfc>
-  <volumetric_efficiency> {number} </volumetric_efficiency>
+  <volumetric-efficiency> {number} </volumetric-efficiency>
   <numboostspeeds> {number} </numboostspeeds>
   <boostoverride> {0 | 1} </boostoverride>
+  <boostmanual> {0 | 1} </boostmanual>
   <ratedboost1 unit="{INHG | PA | ATM}"> {number} </ratedboost1>
   <ratedpower1 unit="{HP | WATTS}"> {number} </ratedpower1>
   <ratedrpm1> {number} </ratedrpm1>
@@ -97,6 +98,8 @@ CLASS DOCUMENTATION
   <ratedrpm3> {number} </ratedrpm3>
   <ratedaltitude3 unit="{FT | M}"> {number} </ratedaltitude3>
   <takeoffboost unit="{INHG | PA | ATM}"> {number} </takeoffboost>
+  <air-intake-impedance-factor> {number} </air-intake-impedance-factor>
+  <ram-air-factor> {number} </ram-air-factor>
 </piston_engine>
 @endcode
 
@@ -120,6 +123,10 @@ CLASS DOCUMENTATION
       some way of getting the boost control cutout lever position (on or off)
       from FlightGear first.
 
+    - BOOSTMANUAL - whether a multispeed supercharger will manually or
+      automatically shift boost speeds.  On manual shifting the boost speeds
+      is accomplished by controling propulsion/engine/boostspeed
+
     - The next items are all appended with either 1, 2 or 3 depending on which
       boost speed they refer to, eg RATEDBOOST1.  The rated values seems to have
       been a common convention at the time to express the maximum continuously
@@ -247,6 +254,8 @@ private:
   const double calorific_value_fuel;  // W/Kg (approximate)
   const double Cp_air;      // J/KgK
   const double Cp_fuel;     // J/KgK
+  const double standard_pressure; //Pa
+
 
   FGTable *Lookup_Combustion_Efficiency;
   FGTable *Mixture_Efficiency_Correlation;
@@ -267,12 +276,19 @@ private:
   double Bore;                     // inches
   double Stroke;                   // inches
   double Cylinders;                // number
-  double CompressionRatio;        // number
+  double CompressionRatio;         // number
+  double Z_airbox; // number representing intake impediance before the throttle
+  double Z_throttle; // number representing slope of throttle impediance
+  double PeakMeanPistonSpeed_fps; // ft/sec speed where intake valves begin to choke. Typically 33-50 fps
+  double RatedMeanPistonSpeed_fps; // ft/sec derived from MaxRPM and stroke.
+  double Ram_Air_Factor;           // number
 
   double StarterHP;                // initial horsepower of starter motor
   int BoostSpeeds;     // Number of super/turbocharger boost speeds - zero implies no turbo/supercharging.
   int BoostSpeed;      // The current boost-speed (zero-based).
   bool Boosted;                // Set true for boosted engine.
+  int BoostManual;     // The raw value read in from the config file - should be 1 or 0 - see description below.
+  bool bBoostManual;   // Set true if pilot must manually control the boost speed.
   int BoostOverride;   // The raw value read in from the config file - should be 1 or 0 - see description below.
   bool bBoostOverride; // Set true if pilot override of the boost regulator was fitted.
               // (Typically called 'war emergency power').
@@ -302,6 +318,7 @@ private:
   // Inputs (in addition to those in FGEngine).
   //
   double p_amb;              // Pascals
+  double p_ram;              // Pascals
   double T_amb;              // degrees Kelvin
   double RPM;                // revolutions per minute
   double IAS;                // knots
index 2f5b39523940b2be6f1e5bade71c5bbdc3aa4f6d..a7e1a59c33bb46a634316462f60acc0e6927f38e 100644 (file)
@@ -38,9 +38,9 @@ INCLUDES
 #include <sstream>
 
 #include "FGPropeller.h"
-#include <models/FGPropagate.h>
-#include <models/FGAtmosphere.h>
-#include <models/FGAuxiliary.h>
+#include "models/FGPropagate.h"
+#include "models/FGAtmosphere.h"
+#include "models/FGAuxiliary.h"
 
 namespace JSBSim {
 
index a2ddc9f419fc4223bd4612d9cd48fa49e849e8f4..500e6798599bf2372f7eedd2f052887525a26f0f 100644 (file)
@@ -39,7 +39,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGThruster.h"
-#include <math/FGTable.h>
+#include "math/FGTable.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 1f4ca5a6f0b04d42ed144d23169947ef821a9080..0debff012ccf76e91bb0ea02652a053d9b2e0400 100644 (file)
@@ -125,8 +125,12 @@ double FGRocket::Calculate(void)
     if ((Throttle == 1 || BurnTime > 0.0 ) && !Starved) {
       BurnTime += State->Getdt();
       double TotalEngineFuelAvailable=0.0;
-      for (int i=0; i<(int)SourceTanks.size(); i++)
-        TotalEngineFuelAvailable += Propulsion->GetTank(SourceTanks[i])->GetContents();
+      for (int i=0; i<(int)SourceTanks.size(); i++) {
+        FGTank* tank = Propulsion->GetTank(i);
+        if (SourceTanks[i] == 1) {
+          TotalEngineFuelAvailable += tank->GetContents();
+        }
+      }
 
       VacThrust = ThrustTable->GetValue(TotalEngineFuelAvailable);
     } else {
index 4e6e8120a5af3a49e4b07ce2eb1b9ef53f1fe858..f96d02010e2770dc3ab0c3fc2613bccf2ca9fe76 100644 (file)
@@ -39,8 +39,8 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGEngine.h"
-#include <math/FGTable.h>
-#include <input_output/FGXMLElement.h>
+#include "math/FGTable.h"
+#include "input_output/FGXMLElement.h"
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 DEFINITIONS
index 289fbb197c7aa769a1104d230ba59f5bfa099d91..56e68d08fd18f2015b1c41fcdb93d1b5c5e47d14 100644 (file)
@@ -37,7 +37,7 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGTank.h"
-#include <models/FGAuxiliary.h>
+#include "models/FGAuxiliary.h"
 
 using std::cerr;
 using std::endl;
@@ -61,7 +61,9 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
   Area = 1.0;
   Temperature = -9999.0;
   Ixx = Iyy = Izz = 0.0;
-  Radius = Capacity = Contents = Standpipe = Length = InnerRadius = 0.0;
+  Radius = Contents = Standpipe = Length = InnerRadius = 0.0;
+  Capacity = 0.00001;
+  Priority = InitialPriority = 1;
   PropertyManager = Exec->GetPropertyManager();
   vXYZ.InitMatrix();
   vXYZ_drain.InitMatrix();
@@ -92,15 +94,17 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
     InitialTemperature = Temperature = el->FindElementValueAsNumber("temperature");
   if (el->FindElement("standpipe"))
     InitialStandpipe = Standpipe = el->FindElementValueAsNumberConvertTo("standpipe", "LBS");
+  if (el->FindElement("priority"))
+    InitialPriority = Priority = el->FindElementValueAsNumber("priority");
 
-  Selected = true;
+  SetPriority( InitialPriority );     // this will also set the Selected flag
 
-  if (Capacity != 0) {
-    PctFull = 100.0*Contents/Capacity;            // percent full; 0 to 100.0
-  } else {
-    Contents = 0;
-    PctFull  = 0;
+  if (Capacity == 0) {
+    cerr << "Tank capacity must not be zero. Reset to 0.00001 lbs!" << endl;
+    Capacity = 0.00001;
+    Contents = 0.0;
   }
+  PctFull = 100.0*Contents/Capacity;            // percent full; 0 to 100.0
 
   // Check whether this is a solid propellant "tank". Initialize it if true.
 
@@ -145,6 +149,9 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
   property_name = base_property_name + "/contents-lbs";
   PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetContents,
                                        &FGTank::SetContents );
+  property_name = base_property_name + "/priority";
+  PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPriority,
+                                       &FGTank::SetPriority );
 
   if (Temperature != -9999.0)  InitialTemperature = Temperature = FahrenheitToCelsius(Temperature);
   Area = 40.0 * pow(Capacity/1975, 0.666666667);
@@ -163,11 +170,11 @@ FGTank::~FGTank()
 
 void FGTank::ResetToIC(void)
 {
-  Temperature = InitialTemperature;
-  Standpipe = InitialStandpipe;
-  Contents = InitialContents;
+  SetTemperature( InitialTemperature );
+  SetStandpipe ( InitialStandpipe );
+  SetContents ( InitialContents );
   PctFull = 100.0*Contents/Capacity;
-  Selected = true;
+  SetPriority( InitialPriority );
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -199,7 +206,7 @@ double FGTank::Drain(double used)
 
     Contents = 0.0;
     PctFull = 0.0;
-    Selected = false;
+    SetPriority(0);
   }
 
   if (grainType != gtUNKNOWN) CalculateInertias();
@@ -284,6 +291,10 @@ void FGTank::CalculateInertias(void)
       Ixx = 0.5*Mass*Rad2/144.0;
       Iyy = Mass*(3.0*Rad2 + Length*Length)/(144.0*12.0);
       break;
+    case gtUNKNOWN:
+      cerr << "Unknown grain type found." << endl;
+      exit(-1);
+      break;
   }
   Izz  = Iyy;
 
@@ -319,6 +330,7 @@ void FGTank::Debug(int from)
       cout << "      Tank location (X, Y, Z): " << vXYZ(eX) << ", " << vXYZ(eY) << ", " << vXYZ(eZ) << endl;
       cout << "      Effective radius: " << Radius << " inches" << endl;
       cout << "      Initial temperature: " << Temperature << " Fahrenheit" << endl;
+      cout << "      Priority: " << Priority << endl;
     }
   }
   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
index 479fcb6c69318bd861fd20a27e5cb63b34597c70..8bc0d0fa68981cb4824b5e3ab07b6718e7473aab 100644 (file)
@@ -45,9 +45,9 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGFDMExec.h"
-#include <FGJSBBase.h>
-#include <input_output/FGXMLElement.h>
-#include <math/FGColumnVector3.h>
+#include "FGJSBBase.h"
+#include "input_output/FGXMLElement.h"
+#include "math/FGColumnVector3.h"
 #include <string>
 
 using std::string;
@@ -127,6 +127,7 @@ CLASS DOCUMENTATION
   <contents unit="{LBS | KG}"> {number} </contents>
   <temperature> {number} </temperature> <!-- must be degrees fahrenheit -->
   <standpipe unit="{LBS | KG"}> {number} </standpipe>
+  <priority> {integer} </priority>
 </tank>
 @endcode
 
@@ -140,6 +141,7 @@ CLASS DOCUMENTATION
 - \b contents - Initial contents, defaults to pounds.
 - \b temperature - Initial temperature, defaults to degrees Fahrenheit.
 - \b standpipe - Minimum contents to which tank can dump, defaults to pounds.
+- \b priority - Establishes feed sequence of tank. "1" is the highest priority.
 
 location:
 - \b x - Location of tank on aircraft's x-axis, defaults to inches.
@@ -160,10 +162,11 @@ be printed to the console if the location is not given
 - \b y - 0.0  (both full and drained CG locations)
 - \b z - 0.0  (both full and drained CG locations)
 - \b radius - 0.0
-- \b capacity - 0.0
+- \b capacity - 0.00001 (tank capacity must not be zero)
 - \b contents - 0.0
-- \b temperature - -9999.0
-- \b standpipe - 0.0
+- \b temperature - -9999.0 (flag which indicates no temperature is set)
+- \b standpipe - 0.0 (all contents may be dumped)
+- \b priority - 1 (highest feed sequence priority)
 
     @author Jon Berndt, Dave Culp
     @see Akbar, Raza et al. "A Simple Analysis of Fuel Addition to the CWT of
@@ -211,8 +214,8 @@ public:
   /** Resets the tank parameters to the initial conditions */
   void ResetToIC(void);
 
-  /** If the tank is supplying fuel, this function returns true.
-      @return true if this tank is feeding an engine.*/
+  /** If the tank is set to supply fuel, this function returns true.
+      @return true if this tank is set to a non-zero priority.*/
   bool GetSelected(void) {return Selected;}
 
   /** Gets the tank fill level.
@@ -247,6 +250,9 @@ public:
 
   double GetStandpipe(void) {return Standpipe;}
 
+  int  GetPriority(void) const {return Priority;}
+  void SetPriority(int p) { Priority = p; Selected = p>0 ? true:false; } 
+
   const FGColumnVector3 GetXYZ(void);
   const double GetXYZ(int idx);
 
@@ -254,6 +260,7 @@ public:
   void SetContents(double amount);
   void SetTemperature(double temp) { Temperature = temp; }
   void SetStandpipe(double amount) { Standpipe = amount; }
+  void SetSelected(bool sel) { sel==true ? SetPriority(1):SetPriority(0); }
 
   enum TankType {ttUNKNOWN, ttFUEL, ttOXIDIZER};
   enum GrainType {gtUNKNOWN, gtCYLINDRICAL, gtENDBURNING};
@@ -281,6 +288,7 @@ private:
   double Temperature, InitialTemperature;
   double Standpipe, InitialStandpipe;
   bool  Selected;
+  int Priority, InitialPriority;
   FGFDMExec* Exec;
   FGPropertyManager* PropertyManager;
   void CalculateInertias(void);
index 860db5a554acd2504c1fc061b87195b68ae895d1..3c483657205e2d1157d70c35275f409386363c4f 100644 (file)
@@ -39,9 +39,9 @@ INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
 #include "FGForce.h"
-#include <input_output/FGXMLElement.h>
-#include <input_output/FGPropertyManager.h>
-#include <math/FGColumnVector3.h>
+#include "input_output/FGXMLElement.h"
+#include "input_output/FGPropertyManager.h"
+#include "math/FGColumnVector3.h"
 #include <string>
 
 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 6c4a7818c4a14a39d599e26f53315546479d8e60..20e5264195e77aa0937f20485b038beebae9316e 100644 (file)
@@ -99,8 +99,9 @@ void FGTurbine::ResetToIC(void)
   Stalled = Seized = Overtemp = Fire = Augmentation = Injection = Reversed = false;
   Cutoff = true;
   phase = tpOff;
-  EGT_degC = 0.0;
-  OilTemp_degK = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556 + 273.0;
+  TAT = (Auxiliary->GetTotalTemperature() - 491.69) * 0.5555556;
+  EGT_degC = TAT;
+  OilTemp_degK = TAT + 273.0;
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -313,8 +314,10 @@ double FGTurbine::Stall(void)
   N1 = Seek(&N1, qbar/10.0, 0, N1/10.0);
   N2 = Seek(&N2, qbar/15.0, 0, N2/10.0);
   ConsumeFuel();
-  if (ThrottlePos < 0.01) phase = tpRun;        // clear the stall with throttle
-
+  if (ThrottlePos < 0.01) {
+    phase = tpRun;               // clear the stall with throttle to idle
+    Stalled = false;
+    }
   return 0.0;
 }
 
@@ -325,7 +328,7 @@ double FGTurbine::Seize(void)
     double qbar = Auxiliary->Getqbar();
     N2 = 0.0;
     N1 = Seek(&N1, qbar/20.0, 0, N1/15.0);
-    FuelFlow_pph = IdleFF;
+    FuelFlow_pph = Cutoff ? 0.0 : IdleFF;
     ConsumeFuel();
     OilPressure_psi = 0.0;
     OilTemp_degK = Seek(&OilTemp_degK, TAT + 273.0, 0, 0.2);
@@ -514,6 +517,10 @@ void FGTurbine::bindmodel()
   property_name = base_property_name + "/injection_cmd";
   PropertyManager->Tie( property_name.c_str(), (FGTurbine*)this, 
                         &FGTurbine::GetInjection, &FGTurbine::SetInjection);
+  property_name = base_property_name + "/seized";
+  PropertyManager->Tie( property_name.c_str(), &Seized);
+  property_name = base_property_name + "/stalled";
+  PropertyManager->Tie( property_name.c_str(), &Stalled);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -522,7 +529,7 @@ int FGTurbine::InitRunning(void) {
   State->SuspendIntegration();
   Cutoff=false;
   Running=true;  
-  N2=16.0;
+  N2=IdleN2;
   Calculate();
   State->ResumeIntegration();
   return phase==tpRun;
index 552c258b14a9d4b5a31fd492f78391085c9370bb..fbb8497c90b0e752be710286bf8a6fba0f2ccc0e 100644 (file)
@@ -42,8 +42,8 @@ INCLUDES
 
 #include <vector>
 #include "FGEngine.h"
-#include <input_output/FGXMLElement.h>
-#include <math/FGFunction.h>
+#include "input_output/FGXMLElement.h"
+#include "math/FGFunction.h"
 
 #define ID_TURBINE "$Id$"
 
index 6501452b14bfb2b566e3fd7cf8ccde1099c5fb16..d3b137538267acdbe434a1ec9374db2cbefca724 100755 (executable)
@@ -43,8 +43,8 @@ INCLUDES
 
 #include <vector>
 #include "FGEngine.h"
-#include <input_output/FGXMLElement.h>
-#include <math/FGTable.h>
+#include "input_output/FGXMLElement.h"
+#include "math/FGTable.h"
 
 #define ID_TURBOPROP "$Id$"