sync. with JSBSim CVS again
This commit is contained in:
parent
a3af4ed1d8
commit
0f0f25512d
108 changed files with 1111 additions and 990 deletions
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -38,8 +38,8 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include <math/FGColumnVector3.h>
|
||||
#include <math/FGLocation.h>
|
||||
#include "math/FGColumnVector3.h"
|
||||
#include "math/FGLocation.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"];
|
||||
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;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -35,7 +35,7 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include <input_output/FGXMLParse.h>
|
||||
#include "input_output/FGXMLParse.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -41,7 +41,7 @@ INCLUDES
|
|||
#include <cmath>
|
||||
|
||||
#include "FGLocation.h"
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
#include "input_output/FGPropertyManager.h"
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGParameter.h"
|
||||
#include <input_output/FGPropertyManager.h>
|
||||
#include "input_output/FGPropertyManager.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -43,7 +43,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGModel.h"
|
||||
#include <math/FGColumnVector3.h>
|
||||
#include "math/FGColumnVector3.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -40,7 +40,7 @@ INCLUDES
|
|||
|
||||
#include "FGModel.h"
|
||||
#include "FGExternalForce.h"
|
||||
#include <input_output/FGXMLElement.h>
|
||||
#include "input_output/FGXMLElement.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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$"
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGInertial.h"
|
||||
#include <FGFDMExec.h>
|
||||
#include "FGFDMExec.h"
|
||||
#include "FGPropagate.h"
|
||||
#include "FGState.h"
|
||||
#include "FGMassBalance.h"
|
||||
|
|
|
@ -41,7 +41,7 @@ INCLUDES
|
|||
#include <vector>
|
||||
|
||||
#include "FGModel.h"
|
||||
#include <math/FGColumnVector3.h>
|
||||
#include "math/FGColumnVector3.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
// 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.);
|
||||
|
||||
vOrient(eRoll) = atan2(updatedRollingAxis(eY), -updatedRollingAxis(eZ));
|
||||
UpdateCustomTransformMatrix();
|
||||
}
|
||||
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));
|
||||
|
||||
vRollingGroundVec.Normalize();
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -40,7 +40,7 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include <models/FGAtmosphere.h>
|
||||
#include "models/FGAtmosphere.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
|
@ -38,7 +38,7 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include <models/FGAtmosphere.h>
|
||||
#include "models/FGAtmosphere.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
|
@ -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
|
||||
ProcessSensorSignal();
|
||||
|
||||
// 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;
|
||||
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -38,7 +38,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGFCSComponent.h"
|
||||
#include <input_output/FGXMLElement.h>
|
||||
#include "input_output/FGXMLElement.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGFCSComponent.h"
|
||||
#include <input_output/FGXMLElement.h>
|
||||
#include "input_output/FGXMLElement.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
|
@ -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
|
||||
ProcessSensorSignal();
|
||||
|
||||
// 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
|
||||
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGFCSComponent.h"
|
||||
#include <input_output/FGXMLElement.h>
|
||||
#include "input_output/FGXMLElement.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
|
|
@ -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
|
||||
ProcessSensorSignal();
|
||||
|
||||
// Degrade signal as specified
|
||||
|
||||
if (fail_stuck) {
|
||||
Output = PreviousOutput;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lag != 0.0) Lag(); // models magnetometer lag
|
||||
if (noise_variance != 0.0) Noise(); // models noise
|
||||
if (drift_rate != 0.0) Drift(); // models drift over time
|
||||
if (bias != 0.0) Bias(); // models a finite bias
|
||||
if (gain != 0.0) Gain(); // models a gain
|
||||
|
||||
if (fail_low) Output = -HUGE_VAL;
|
||||
if (fail_high) Output = HUGE_VAL;
|
||||
|
||||
if (bits != 0) Quantize(); // models quantization degradation
|
||||
// if (delay != 0.0) Delay(); // models system signal transport latencies
|
||||
|
||||
Clip(); // Is it right to clip an magnetometer?
|
||||
return true;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGMagnetometer::CalculateTransformMatrix(void)
|
||||
{
|
||||
double cp,sp,cr,sr,cy,sy;
|
||||
|
||||
cp=cos(vOrient(ePitch)); sp=sin(vOrient(ePitch));
|
||||
cr=cos(vOrient(eRoll)); sr=sin(vOrient(eRoll));
|
||||
cy=cos(vOrient(eYaw)); sy=sin(vOrient(eYaw));
|
||||
|
||||
|
||||
mT(1,1) = cp*cy;
|
||||
mT(1,2) = cp*sy;
|
||||
mT(1,3) = -sp;
|
||||
|
||||
mT(2,1) = sr*sp*cy - cr*sy;
|
||||
mT(2,2) = sr*sp*sy + cr*cy;
|
||||
mT(2,3) = sr*cp;
|
||||
|
||||
mT(3,1) = cr*sp*cy + sr*sy;
|
||||
mT(3,2) = cr*sp*sy - sr*cy;
|
||||
mT(3,3) = cr*cp;
|
||||
|
||||
|
||||
// This transform is different than for FGForce, where we want a native nozzle
|
||||
// force in body frame. Here we calculate the body frame accel and want it in
|
||||
// the transformed magnetometer frame. So, the next line is commented out.
|
||||
// mT = mT.Inverse();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// The bitmasked value choices are as follows:
|
||||
// unset: In this case (the default) JSBSim would only print
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
} 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) Delay(); // models system signal transport latencies
|
||||
|
||||
if (fail_low) Output = -HUGE_VAL;
|
||||
if (fail_high) Output = HUGE_VAL;
|
||||
|
||||
if (bits != 0) Quantize(); // models quantization degradation
|
||||
|
||||
Clip();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if (delay != 0.0) Delay(); // models system signal transport latencies
|
||||
|
||||
if (fail_low) Output = -HUGE_VAL;
|
||||
if (fail_high) Output = HUGE_VAL;
|
||||
|
||||
if (bits != 0) Quantize(); // models quantization degradation
|
||||
|
||||
Clip(); // Is it right to clip a sensor?
|
||||
return true;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
136
src/FDM/JSBSim/models/flight_control/FGSensorOrientation.h
Executable file
136
src/FDM/JSBSim/models/flight_control/FGSensorOrientation.h
Executable file
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -38,7 +38,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGFCSComponent.h"
|
||||
#include <input_output/FGXMLElement.h>
|
||||
#include "input_output/FGXMLElement.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -40,7 +40,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGElectric.h"
|
||||
#include <models/FGPropulsion.h>
|
||||
#include "models/FGPropulsion.h"
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGEngine.h"
|
||||
#include <input_output/FGXMLElement.h>
|
||||
#include "input_output/FGXMLElement.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
|
@ -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;
|
||||
|
||||
// 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;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
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;
|
||||
// No fuel found at any priority!
|
||||
if (TanksWithFuel == 0.0) {
|
||||
Starved = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Fshortage < 0.00) Starved = true;
|
||||
else Starved = false;
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ INCLUDES
|
|||
#include <sstream>
|
||||
|
||||
#include "FGNozzle.h"
|
||||
#include <models/FGAtmosphere.h>
|
||||
#include "models/FGAtmosphere.h"
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ INCLUDES
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#include "FGThruster.h"
|
||||
#include <math/FGTable.h>
|
||||
#include "math/FGTable.h"
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
DEFINITIONS
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue