1
0
Fork 0

sync. with JSBSim CVS again

This commit is contained in:
ehofman 2009-10-12 07:24:41 +00:00 committed by Tim Moore
parent a3af4ed1d8
commit 0f0f25512d
108 changed files with 1111 additions and 990 deletions

View file

@ -43,26 +43,26 @@ INCLUDES
#include "FGFDMExec.h"
#include "FGState.h"
#include <models/FGAtmosphere.h>
#include <models/atmosphere/FGMSIS.h>
#include <models/atmosphere/FGMars.h>
#include <models/FGFCS.h>
#include <models/FGPropulsion.h>
#include <models/FGMassBalance.h>
#include <models/FGGroundReactions.h>
#include <models/FGExternalReactions.h>
#include <models/FGBuoyantForces.h>
#include <models/FGAerodynamics.h>
#include <models/FGInertial.h>
#include <models/FGAircraft.h>
#include <models/FGPropagate.h>
#include <models/FGAuxiliary.h>
#include <models/FGInput.h>
#include <models/FGOutput.h>
#include <initialization/FGInitialCondition.h>
//#include <initialization/FGTrimAnalysis.h> // Remove until later
#include <input_output/FGPropertyManager.h>
#include <input_output/FGScript.h>
#include "models/FGAtmosphere.h"
#include "models/atmosphere/FGMSIS.h"
#include "models/atmosphere/FGMars.h"
#include "models/FGFCS.h"
#include "models/FGPropulsion.h"
#include "models/FGMassBalance.h"
#include "models/FGGroundReactions.h"
#include "models/FGExternalReactions.h"
#include "models/FGBuoyantForces.h"
#include "models/FGAerodynamics.h"
#include "models/FGInertial.h"
#include "models/FGAircraft.h"
#include "models/FGPropagate.h"
#include "models/FGAuxiliary.h"
#include "models/FGInput.h"
#include "models/FGOutput.h"
#include "initialization/FGInitialCondition.h"
//#include "initialization/FGTrimAnalysis.h" // Remove until later
#include "input_output/FGPropertyManager.h"
#include "input_output/FGScript.h"
#include <iostream>
#include <iterator>
@ -715,7 +715,7 @@ void FGFDMExec::BuildPropertyCatalog(struct PropertyCatalogStructure* pcs)
int node_idx = 0;
char int_buf[10];
for (unsigned int i=0; i<pcs->node->nChildren(); i++) {
for (int i=0; i<pcs->node->nChildren(); i++) {
pcsNew->base_string = pcs->base_string + "/" + pcs->node->getChild(i)->getName();
node_idx = pcs->node->getChild(i)->getIndex();
sprintf(int_buf, "[%d]", node_idx);

View file

@ -41,17 +41,17 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <models/FGModel.h>
#include <models/FGOutput.h>
#include <models/FGInput.h>
#include <initialization/FGTrim.h>
#include <initialization/FGInitialCondition.h>
#include <FGJSBBase.h>
#include <input_output/FGPropertyManager.h>
#include <input_output/FGGroundCallback.h>
#include <input_output/FGXMLFileRead.h>
#include <models/FGPropagate.h>
#include <math/FGColumnVector3.h>
#include "models/FGModel.h"
#include "models/FGOutput.h"
#include "models/FGInput.h"
#include "initialization/FGTrim.h"
#include "initialization/FGInitialCondition.h"
#include "FGJSBBase.h"
#include "input_output/FGPropertyManager.h"
#include "input_output/FGGroundCallback.h"
#include "input_output/FGXMLFileRead.h"
#include "models/FGPropagate.h"
#include "math/FGColumnVector3.h"
#include <vector>
#include <string>

View file

@ -45,18 +45,18 @@ INCLUDES
#include <string>
#include <map>
#include "FGJSBBase.h"
#include <initialization/FGInitialCondition.h>
#include <math/FGColumnVector3.h>
#include <math/FGQuaternion.h>
#include "initialization/FGInitialCondition.h"
#include "math/FGColumnVector3.h"
#include "math/FGQuaternion.h"
#include "FGFDMExec.h"
#include <models/FGAtmosphere.h>
#include <models/FGFCS.h>
#include <models/FGPropagate.h>
#include <models/FGAuxiliary.h>
#include <models/FGAerodynamics.h>
#include <models/FGAircraft.h>
#include <models/FGGroundReactions.h>
#include <models/FGPropulsion.h>
#include "models/FGAtmosphere.h"
#include "models/FGFCS.h"
#include "models/FGPropagate.h"
#include "models/FGAuxiliary.h"
#include "models/FGAerodynamics.h"
#include "models/FGAircraft.h"
#include "models/FGGroundReactions.h"
#include "models/FGPropulsion.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -43,15 +43,15 @@ INCLUDES
*******************************************************************************/
#include "FGInitialCondition.h"
#include <FGFDMExec.h>
#include <models/FGInertial.h>
#include <models/FGAtmosphere.h>
#include <models/FGAerodynamics.h>
#include <models/FGPropagate.h>
#include <input_output/FGPropertyManager.h>
#include <models/FGPropulsion.h>
#include <input_output/FGXMLParse.h>
#include <math/FGQuaternion.h>
#include "FGFDMExec.h"
#include "models/FGInertial.h"
#include "models/FGAtmosphere.h"
#include "models/FGAerodynamics.h"
#include "models/FGPropagate.h"
#include "input_output/FGPropertyManager.h"
#include "models/FGPropulsion.h"
#include "input_output/FGXMLParse.h"
#include "math/FGQuaternion.h"
#include <fstream>
namespace JSBSim {

View file

@ -47,10 +47,10 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <FGFDMExec.h>
#include <FGJSBBase.h>
#include <math/FGColumnVector3.h>
#include <input_output/FGXMLFileRead.h>
#include "FGFDMExec.h"
#include "FGJSBBase.h"
#include "math/FGColumnVector3.h"
#include "input_output/FGXMLFileRead.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -44,14 +44,14 @@ INCLUDES
#include <cstdlib>
#include <iomanip>
#include "FGTrim.h"
#include <models/FGAtmosphere.h>
#include "models/FGAtmosphere.h"
#include "FGInitialCondition.h"
#include <models/FGAircraft.h>
#include <models/FGMassBalance.h>
#include <models/FGGroundReactions.h>
#include <models/FGInertial.h>
#include <models/FGAerodynamics.h>
#include <math/FGColumnVector3.h>
#include "models/FGAircraft.h"
#include "models/FGMassBalance.h"
#include "models/FGGroundReactions.h"
#include "models/FGInertial.h"
#include "models/FGAerodynamics.h"
#include "math/FGColumnVector3.h"
#if _MSC_VER
#pragma warning (disable : 4786 4788)

View file

@ -38,13 +38,13 @@ INCLUDES
#include <string>
#include <cstdlib>
#include <FGFDMExec.h>
#include <models/FGAtmosphere.h>
#include "FGFDMExec.h"
#include "models/FGAtmosphere.h"
#include "FGInitialCondition.h"
#include "FGTrimAxis.h"
#include <models/FGAircraft.h>
#include <models/FGPropulsion.h>
#include <models/FGAerodynamics.h>
#include "models/FGAircraft.h"
#include "models/FGPropulsion.h"
#include "models/FGAerodynamics.h"
namespace JSBSim {

View file

@ -31,8 +31,8 @@ HISTORY
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <math/FGColumnVector3.h>
#include <math/FGLocation.h>
#include "math/FGColumnVector3.h"
#include "math/FGLocation.h"
#include "FGGroundCallback.h"
namespace JSBSim {

View file

@ -38,8 +38,8 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <math/FGColumnVector3.h>
#include <math/FGLocation.h>
#include "math/FGColumnVector3.h"
#include "math/FGLocation.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -43,9 +43,9 @@ INCLUDES
#include <string>
#include <iostream>
#include <simgear/props/props.hxx>
#include "simgear/props/props.hxx"
#if !PROPS_STANDALONE
# include <simgear/math/SGMath.hxx>
# include "simgear/math/SGMath.hxx"
#endif
#include "FGJSBBase.h"

View file

@ -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>

View file

@ -40,10 +40,10 @@ INCLUDES
#include "FGJSBBase.h"
#include "FGState.h"
#include "FGFDMExec.h"
#include <math/FGFunction.h>
#include <math/FGCondition.h>
#include "math/FGFunction.h"
#include "math/FGCondition.h"
#include <vector>
#include <input_output/FGXMLFileRead.h>
#include "input_output/FGXMLFileRead.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -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;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -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

View file

@ -35,7 +35,7 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <input_output/FGXMLParse.h>
#include "input_output/FGXMLParse.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -38,9 +38,9 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <map>
#include <FGJSBBase.h>
#include <input_output/FGXMLElement.h>
#include <input_output/FGPropertyManager.h>
#include "FGJSBBase.h"
#include "input_output/FGXMLElement.h"
#include "input_output/FGPropertyManager.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -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;

View file

@ -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

View file

@ -41,7 +41,7 @@ INCLUDES
#include <cmath>
#include "FGLocation.h"
#include <input_output/FGPropertyManager.h>
#include "input_output/FGPropertyManager.h"
namespace JSBSim {

View file

@ -39,8 +39,8 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <FGJSBBase.h>
#include <input_output/FGPropertyManager.h>
#include "FGJSBBase.h"
#include "input_output/FGPropertyManager.h"
#include "FGColumnVector3.h"
#include "FGMatrix33.h"

View file

@ -35,7 +35,7 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGParameter.h"
#include <input_output/FGPropertyManager.h>
#include "input_output/FGPropertyManager.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -40,10 +40,10 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <FGJSBBase.h>
#include "FGJSBBase.h"
#include "FGMatrix33.h"
#include "FGColumnVector3.h"
#include <input_output/FGPropertyManager.h>
#include "input_output/FGPropertyManager.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -488,7 +488,7 @@ void FGTable::operator<<(stringstream& in_stream)
FGTable& FGTable::operator<<(const double n)
{
Data[rowCounter][colCounter] = n;
if (colCounter == nCols) {
if (colCounter == (int)nCols) {
colCounter = 0;
rowCounter++;
} else {

View file

@ -38,9 +38,9 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <input_output/FGXMLElement.h>
#include "input_output/FGXMLElement.h"
#include "FGParameter.h"
#include <input_output/FGPropertyManager.h>
#include "input_output/FGPropertyManager.h"
#include <sstream>
#include <vector>

View file

@ -42,7 +42,7 @@ INCLUDES
#include "FGAircraft.h"
#include "FGAuxiliary.h"
#include "FGMassBalance.h"
#include <input_output/FGPropertyManager.h>
#include "input_output/FGPropertyManager.h"
namespace JSBSim {
@ -324,21 +324,21 @@ bool FGAerodynamics::Load(Element *element)
Debug(2);
if (temp_element = document->FindElement("alphalimits")) {
if ((temp_element = document->FindElement("alphalimits"))) {
scratch_unit = temp_element->GetAttributeValue("unit");
if (scratch_unit.empty()) scratch_unit = "RAD";
alphaclmin = temp_element->FindElementValueAsNumberConvertFromTo("min", scratch_unit, "RAD");
alphaclmax = temp_element->FindElementValueAsNumberConvertFromTo("max", scratch_unit, "RAD");
}
if (temp_element = document->FindElement("hysteresis_limits")) {
if ((temp_element = document->FindElement("hysteresis_limits"))) {
scratch_unit = temp_element->GetAttributeValue("unit");
if (scratch_unit.empty()) scratch_unit = "RAD";
alphahystmin = temp_element->FindElementValueAsNumberConvertFromTo("min", scratch_unit, "RAD");
alphahystmax = temp_element->FindElementValueAsNumberConvertFromTo("max", scratch_unit, "RAD");
}
if (temp_element = document->FindElement("aero_ref_pt_shift_x")) {
if ((temp_element = document->FindElement("aero_ref_pt_shift_x"))) {
function_element = temp_element->FindElement("function");
AeroRPShift = new FGFunction(PropertyManager, function_element);
}
@ -558,6 +558,9 @@ void FGAerodynamics::Debug(int from)
case (atBodyXYZ):
cout << endl << " Aerodynamics (X|Y|Z axes):" << endl << endl;
break;
case (atNone):
cout << endl << " Aerodynamics (undefined axes):" << endl << endl;
break;
}
}
}

View file

@ -42,10 +42,10 @@ INCLUDES
#include <map>
#include "FGModel.h"
#include <math/FGFunction.h>
#include <math/FGColumnVector3.h>
#include <math/FGMatrix33.h>
#include <input_output/FGXMLFileRead.h>
#include "math/FGFunction.h"
#include "math/FGColumnVector3.h"
#include "math/FGMatrix33.h"
#include "input_output/FGXMLFileRead.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -50,9 +50,9 @@ INCLUDES
#include "FGExternalReactions.h"
#include "FGBuoyantForces.h"
#include "FGAerodynamics.h"
#include <FGFDMExec.h>
#include "FGFDMExec.h"
#include "FGPropagate.h"
#include <input_output/FGPropertyManager.h>
#include "input_output/FGPropertyManager.h"
namespace JSBSim {

View file

@ -41,8 +41,8 @@ INCLUDES
#include <vector>
#include "FGModel.h"
#include <input_output/FGXMLElement.h>
#include <math/FGColumnVector3.h>
#include "input_output/FGXMLElement.h"
#include "math/FGColumnVector3.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -48,12 +48,12 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGAtmosphere.h"
#include <FGState.h>
#include <FGFDMExec.h>
#include "FGState.h"
#include "FGFDMExec.h"
#include "FGAircraft.h"
#include "FGPropagate.h"
#include "FGInertial.h"
#include <input_output/FGPropertyManager.h>
#include "input_output/FGPropertyManager.h"
namespace JSBSim {
@ -454,10 +454,12 @@ void FGAtmosphere::Turbulence(void)
vDirectiondAccelDt(eX) = GaussianRandomNumber();
vDirectiondAccelDt(eY) = GaussianRandomNumber();
vDirectiondAccelDt(eZ) = GaussianRandomNumber();
/*
MagnitudedAccelDt = GaussianRandomNumber();
MagnitudeAccel += MagnitudedAccelDt * DeltaT;
Magnitude += MagnitudeAccel * DeltaT;
*/
Magnitude += GaussianRandomNumber() * DeltaT;
vDirectiondAccelDt.Normalize();
vDirectionAccel += TurbRate * vDirectiondAccelDt * DeltaT;

View file

@ -43,7 +43,7 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGModel.h"
#include <math/FGColumnVector3.h>
#include "math/FGColumnVector3.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -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 {

View file

@ -40,9 +40,9 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGModel.h"
#include <FGFDMExec.h>
#include <math/FGColumnVector3.h>
#include <math/FGLocation.h>
#include "FGFDMExec.h"
#include "math/FGColumnVector3.h"
#include "math/FGLocation.h"
#include "FGPropagate.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -38,7 +38,7 @@ INCLUDES
#include "FGBuoyantForces.h"
#include "FGMassBalance.h"
#include <input_output/FGPropertyManager.h> // Need?
#include "input_output/FGPropertyManager.h" // Need?
namespace JSBSim {

View file

@ -44,8 +44,8 @@ INCLUDES
#include "FGModel.h"
#include "FGGasCell.h"
#include <math/FGColumnVector3.h>
#include <input_output/FGXMLFileRead.h>
#include "math/FGColumnVector3.h"
#include "input_output/FGXMLFileRead.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -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

View file

@ -40,7 +40,7 @@ INCLUDES
#include "FGModel.h"
#include "FGExternalForce.h"
#include <input_output/FGXMLElement.h>
#include "input_output/FGXMLElement.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -38,24 +38,25 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFCS.h"
#include <FGFDMExec.h>
#include <input_output/FGPropertyManager.h>
#include "FGFDMExec.h"
#include "input_output/FGPropertyManager.h"
#include <fstream>
#include <sstream>
#include <iomanip>
#include <models/flight_control/FGFilter.h>
#include <models/flight_control/FGDeadBand.h>
#include <models/flight_control/FGGain.h>
#include <models/flight_control/FGPID.h>
#include <models/flight_control/FGSwitch.h>
#include <models/flight_control/FGSummer.h>
#include <models/flight_control/FGKinemat.h>
#include <models/flight_control/FGFCSFunction.h>
#include <models/flight_control/FGSensor.h>
#include <models/flight_control/FGActuator.h>
#include <models/flight_control/FGAccelerometer.h>
#include <models/flight_control/FGGyro.h>
#include "models/flight_control/FGFilter.h"
#include "models/flight_control/FGDeadBand.h"
#include "models/flight_control/FGGain.h"
#include "models/flight_control/FGPID.h"
#include "models/flight_control/FGSwitch.h"
#include "models/flight_control/FGSummer.h"
#include "models/flight_control/FGKinemat.h"
#include "models/flight_control/FGFCSFunction.h"
#include "models/flight_control/FGSensor.h"
#include "models/flight_control/FGActuator.h"
#include "models/flight_control/FGAccelerometer.h"
#include "models/flight_control/FGMagnetometer.h"
#include "models/flight_control/FGGyro.h"
namespace JSBSim {
@ -643,6 +644,8 @@ bool FGFCS::Load(Element* el, SystemType systype)
Components->push_back(new FGSensor(this, component_element));
} else if (component_element->GetName() == string("accelerometer")) {
Components->push_back(new FGAccelerometer(this, component_element));
} else if (component_element->GetName() == string("magnetometer")) {
Components->push_back(new FGMagnetometer(this, component_element));
} else if (component_element->GetName() == string("gyro")) {
Components->push_back(new FGGyro(this, component_element));
} else {

View file

@ -41,10 +41,10 @@ INCLUDES
#include <vector>
#include <string>
#include <models/flight_control/FGFCSComponent.h>
#include <models/FGModel.h>
#include <models/FGLGear.h>
#include <input_output/FGXMLFileRead.h>
#include "models/flight_control/FGFCSComponent.h"
#include "models/FGModel.h"
#include "models/FGLGear.h"
#include "input_output/FGXMLFileRead.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -35,11 +35,11 @@ HISTORY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <FGFDMExec.h>
#include <models/FGAuxiliary.h>
#include <models/FGAtmosphere.h>
#include <models/FGInertial.h>
#include <models/FGMassBalance.h>
#include "FGFDMExec.h"
#include "models/FGAuxiliary.h"
#include "models/FGAtmosphere.h"
#include "models/FGInertial.h"
#include "models/FGMassBalance.h"
#include "FGGasCell.h"
using std::cerr;

View file

@ -39,11 +39,11 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <FGJSBBase.h>
#include <input_output/FGXMLElement.h>
#include <math/FGColumnVector3.h>
#include <models/propulsion/FGForce.h>
#include <math/FGFunction.h>
#include "FGJSBBase.h"
#include "input_output/FGXMLElement.h"
#include "math/FGColumnVector3.h"
#include "models/propulsion/FGForce.h"
#include "math/FGFunction.h"
#include <string>
using std::string;

View file

@ -39,7 +39,7 @@ INCLUDES
#include <iomanip>
#include "FGGroundReactions.h"
#include <input_output/FGPropertyManager.h>
#include "input_output/FGPropertyManager.h"
namespace JSBSim {
@ -95,8 +95,8 @@ bool FGGroundReactions::Run(void)
// Perhaps there is some commonality for things which only need to be
// calculated once.
for (unsigned int i=0; i<lGear.size(); i++) {
vForces += lGear[i]->Force();
vMoments += lGear[i]->Moment();
vForces += lGear[i]->GetBodyForces();
vMoments += lGear[i]->GetMoments();
}
return false;

View file

@ -42,8 +42,8 @@ INCLUDES
#include "FGModel.h"
#include "FGLGear.h"
#include <math/FGColumnVector3.h>
#include <input_output/FGXMLElement.h>
#include "math/FGColumnVector3.h"
#include "input_output/FGXMLElement.h"
#define ID_GROUNDREACTIONS "$Id$"

View file

@ -36,7 +36,7 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGInertial.h"
#include <FGFDMExec.h>
#include "FGFDMExec.h"
#include "FGPropagate.h"
#include "FGState.h"
#include "FGMassBalance.h"

View file

@ -41,7 +41,7 @@ INCLUDES
#include <vector>
#include "FGModel.h"
#include <math/FGColumnVector3.h>
#include "math/FGColumnVector3.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -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";

View file

@ -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

View file

@ -55,13 +55,17 @@ GLOBAL DATA
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_LGEAR;
// Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
// ft instead of inches)
const FGMatrix33 FGLGear::Tb2s(-1./inchtoft, 0., 0., 0., 1./inchtoft, 0., 0., 0., -1./inchtoft);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
GearNumber(number),
Exec(fdmex)
FGForce(fdmex),
GearNumber(number)
{
Element *force_table=0;
Element *dampCoeff=0;
@ -81,7 +85,8 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
} else if (sContactType == "STRUCTURE") {
eContactType = ctSTRUCTURE;
} else {
eContactType = ctUNKNOWN;
// Unknown contact point types will be treated as STRUCTURE.
eContactType = ctSTRUCTURE;
}
if (el->FindElement("spring_coeff"))
@ -125,7 +130,7 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
while (force_table) {
force_type = force_table->GetAttributeValue("type");
if (force_type == "CORNERING_COEFF") {
ForceY_Table = new FGTable(Exec->GetPropertyManager(), force_table);
ForceY_Table = new FGTable(fdmex->GetPropertyManager(), force_table);
} else {
cerr << "Undefined force table for " << name << " contact point" << endl;
}
@ -139,8 +144,37 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
else sSteerType = "STEERABLE";
Element* element = el->FindElement("location");
if (element) vXYZ = element->FindElementTripletConvertTo("IN");
if (element) vXYZn = element->FindElementTripletConvertTo("IN");
else {cerr << "No location given for contact " << name << endl; exit(-1);}
SetTransformType(FGForce::tCustom);
element = el->FindElement("orientation");
if (element && (eContactType == ctBOGEY)) {
vGearOrient = element->FindElementTripletConvertTo("RAD");
double cp,sp,cr,sr,cy,sy;
cp=cos(vGearOrient(ePitch)); sp=sin(vGearOrient(ePitch));
cr=cos(vGearOrient(eRoll)); sr=sin(vGearOrient(eRoll));
cy=cos(vGearOrient(eYaw)); sy=sin(vGearOrient(eYaw));
mTGear(1,1) = cp*cy;
mTGear(2,1) = cp*sy;
mTGear(3,1) = -sp;
mTGear(1,2) = sr*sp*cy - cr*sy;
mTGear(2,2) = sr*sp*sy + cr*cy;
mTGear(3,2) = sr*cp;
mTGear(1,3) = cr*sp*cy + sr*sy;
mTGear(2,3) = cr*sp*sy - sr*cy;
mTGear(3,3) = cr*cp;
}
else {
mTGear(1,1) = 1.;
mTGear(2,2) = 1.;
mTGear(3,3) = 1.;
}
if (sBrakeGroup == "LEFT" ) eBrakeGrp = bgLeft;
else if (sBrakeGroup == "RIGHT" ) eBrakeGrp = bgRight;
@ -178,7 +212,13 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
}
}
State = Exec->GetState();
State = fdmex->GetState();
Aircraft = fdmex->GetAircraft();
Propagate = fdmex->GetPropagate();
Auxiliary = fdmex->GetAuxiliary();
FCS = fdmex->GetFCS();
MassBalance = fdmex->GetMassBalance();
LongForceLagFilterCoeff = 1/State->Getdt(); // default longitudinal force filter coefficient
LatForceLagFilterCoeff = 1/State->Getdt(); // default lateral force filter coefficient
@ -213,13 +253,6 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
// Add some AI here to determine if gear is located properly according to its
// brake group type ??
State = Exec->GetState();
Aircraft = Exec->GetAircraft();
Propagate = Exec->GetPropagate();
Auxiliary = Exec->GetAuxiliary();
FCS = Exec->GetFCS();
MassBalance = Exec->GetMassBalance();
WOW = lastWOW = false;
ReportEnable = true;
FirstContact = false;
@ -229,11 +262,9 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
MaximumStrutForce = MaximumStrutTravel = 0.0;
SinkRate = GroundSpeed = 0.0;
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
vWhlBodyVec = MassBalance->StructuralToBody(vXYZn);
vLocalGear = Propagate->GetTb2l() * vWhlBodyVec;
vLocalWhlVel.InitMatrix();
vWhlVelVec.InitMatrix();
compressLength = 0.0;
compressSpeed = 0.0;
@ -263,36 +294,38 @@ FGLGear::~FGLGear()
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3& FGLGear::Force(void)
FGColumnVector3& FGLGear::GetBodyForces(void)
{
double t = Exec->GetState()->Getsim_time();
dT = State->Getdt()*Exec->GetGroundReactions()->GetRate();
double t = fdmex->GetState()->Getsim_time();
dT = State->Getdt()*fdmex->GetGroundReactions()->GetRate();
vForce.InitMatrix();
vLocalForce.InitMatrix();
vMoment.InitMatrix();
vFn.InitMatrix();
if (isRetractable) ComputeRetractionState();
if (GearDown) {
double verticalZProj = 0.;
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ); // Get wheel in body frame
vWhlBodyVec = MassBalance->StructuralToBody(vXYZn); // Get wheel in body frame
vLocalGear = Propagate->GetTb2l() * vWhlBodyVec; // Get local frame wheel location
gearLoc = Propagate->GetLocation().LocalToLocation(vLocalGear);
// Compute the height of the theoretical location of the wheel (if strut is not compressed) with
// respect to the ground level
double height = Exec->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel);
double height = fdmex->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel);
vGroundNormal = -1. * Propagate->GetTec2b() * normal;
// The height returned above is the AGL and is expressed in the Z direction of the local
// coordinate frame. We now need to transform this height in actual compression of the strut (BOGEY)
// of in the normal direction to the ground (STRUCTURE)
switch (eContactType) {
case ctBOGEY:
// Project the height in the local coordinate frame of the strut to compute the actual compression
// length. The strut is assumed to be parallel to Z in the body frame.
compressLength = vGroundNormal(eZ) < 0.0 ? height / vGroundNormal(eZ) : 0.0;
verticalZProj = (Propagate->GetTb2l()*mTGear*FGColumnVector3(0.,0.,1.))(eZ);
compressLength = verticalZProj > 0.0 ? -height / verticalZProj : 0.0;
break;
case ctSTRUCTURE:
compressLength = -height;
verticalZProj = (Propagate->GetTec2l()*normal)(eZ);
compressLength = fabs(verticalZProj) > 0.0 ? -height / verticalZProj : 0.0;
break;
}
@ -303,20 +336,28 @@ FGColumnVector3& FGLGear::Force(void)
// [The next equation should really use the vector to the contact patch of
// the tire including the strut compression and not the original vWhlBodyVec.]
FGColumnVector3 vWhlContactVec = vWhlBodyVec - FGColumnVector3(0., 0., compressLength);
vWhlVelVec = Propagate->GetPQR() * vWhlContactVec;
vWhlVelVec += Propagate->GetUVW() - Propagate->GetTec2b() * cvel;
FGColumnVector3 vWhlDisplVec = mTGear * FGColumnVector3(0., 0., compressLength);
FGColumnVector3 vWhlContactVec = vWhlBodyVec - vWhlDisplVec;
vActingXYZn = vXYZn - Tb2s * vWhlDisplVec;
FGColumnVector3 vBodyWhlVel = Propagate->GetPQR() * vWhlContactVec;
vBodyWhlVel += Propagate->GetUVW() - Propagate->GetTec2b() * cvel;
vWhlVelVec = mTGear.Transposed() * vBodyWhlVel;
InitializeReporting();
ComputeSteeringAngle();
ComputeGroundCoordSys();
vLocalWhlVel = Tb2g * vWhlVelVec;
vLocalWhlVel = Transform().Transposed() * vBodyWhlVel;
compressSpeed = -vLocalWhlVel(eZ);
if (eContactType == ctBOGEY)
// Project the compression speed in the local coordinate frame of the strut
compressSpeed /= -vGroundNormal(eZ);
switch (eContactType) {
case ctBOGEY:
// Compression speed along the strut
compressSpeed = -vWhlVelVec(eZ);
case ctSTRUCTURE:
// Compression speed along the ground normal
compressSpeed = -vLocalWhlVel(eX);
}
ComputeVerticalStrutForce();
@ -325,15 +366,15 @@ FGColumnVector3& FGLGear::Force(void)
ComputeSlipAngle();
ComputeBrakeForceCoefficient();
ComputeSideForceCoefficient();
double sign = vLocalWhlVel(eX)>0?1.0:(vLocalWhlVel(eX)<0?-1.0:0.0);
vLocalForce(eX) = - ((1.0 - TirePressureNorm) * 30 + vLocalForce(eZ) * BrakeFCoeff) * sign;
vLocalForce(eY) = vLocalForce(eZ) * FCoeff;
double sign = vLocalWhlVel(eY)>0?1.0:(vLocalWhlVel(eY)<0?-1.0:0.0);
vFn(eY) = - ((1.0 - TirePressureNorm) * 30 + vFn(eX) * BrakeFCoeff) * sign;
vFn(eZ) = vFn(eX) * FCoeff;
}
else if (eContactType == ctSTRUCTURE) {
FGColumnVector3 vSlipVec = vLocalWhlVel;
vSlipVec(eZ) = 0.;
vSlipVec(eX) = 0.;
vSlipVec.Normalize();
vLocalForce -= staticFCoeff * vLocalForce(eZ) * vSlipVec;
vFn -= staticFCoeff * vFn(eX) * vSlipVec;
}
// Lag and attenuate the XY-plane forces dependent on velocity. This code
@ -343,19 +384,14 @@ FGColumnVector3& FGLGear::Force(void)
// If a coefficient is set to something equal to or less than zero, the
// filter is bypassed.
if (LongForceLagFilterCoeff > 0) vLocalForce(eX) = LongForceFilter.execute(vLocalForce(eX));
if (LatForceLagFilterCoeff > 0) vLocalForce(eY) = LatForceFilter.execute(vLocalForce(eY));
if (LongForceLagFilterCoeff > 0) vFn(eY) = LongForceFilter.execute(vFn(eY));
if (LatForceLagFilterCoeff > 0) vFn(eZ) = LatForceFilter.execute(vFn(eZ));
if ((fabs(vLocalWhlVel(eX)) <= RFRV) && RFRV > 0) vLocalForce(eX) *= fabs(vLocalWhlVel(eX))/RFRV;
if ((fabs(vLocalWhlVel(eY)) <= SFRV) && SFRV > 0) vLocalForce(eY) *= fabs(vLocalWhlVel(eY))/SFRV;
if ((fabs(vLocalWhlVel(eY)) <= RFRV) && RFRV > 0) vFn(eY) *= fabs(vLocalWhlVel(eY))/RFRV;
if ((fabs(vLocalWhlVel(eZ)) <= SFRV) && SFRV > 0) vFn(eZ) *= fabs(vLocalWhlVel(eZ))/SFRV;
// End section for attenuating gear jitter
// Transform the forces back to the body frame and compute the moment.
vForce = Tg2b * vLocalForce;
vMoment = vWhlContactVec * vForce;
} else { // Gear is NOT compressed
WOW = false;
@ -363,8 +399,8 @@ FGColumnVector3& FGLGear::Force(void)
compressSpeed = 0.0;
// Let wheel spin down slowly
vLocalWhlVel(eX) -= 13.0*dT;
if (vLocalWhlVel(eX) < 0.0) vLocalWhlVel(eX) = 0.0;
vWhlVelVec(eX) -= 13.0*dT;
if (vWhlVelVec(eX) < 0.0) vWhlVelVec(eX) = 0.0;
// Return to neutral position between 1.0 and 0.8 gear pos.
SteerAngle *= max(GetGearUnitPos()-0.8, 0.0)/0.2;
@ -381,64 +417,46 @@ FGColumnVector3& FGLGear::Force(void)
lastWOW = WOW;
return vForce;
return FGForce::GetBodyForces();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Build a local "ground" coordinate system defined by
// eX : projection of the rolling direction on the ground
// eY : projection of the sliping direction on the ground
// eZ : normal to the ground
// eX : normal to the ground
// eY : projection of the rolling direction on the ground
// eZ : projection of the sliping direction on the ground
void FGLGear::ComputeGroundCoordSys(void)
{
FGColumnVector3 vRollingGroundVec;
// Euler angles are built up to create a local frame to describe the forces
// applied to the gear by the ground. Here pitch, yaw and roll do not have
// any physical meaning. It is just a convenient notation.
// First, "pitch" and "yaw" are determined in order to align eX with the
// ground normal.
if (vGroundNormal(eZ) < -1.0)
vOrient(ePitch) = 0.5*M_PI;
else if (1.0 < vGroundNormal(eZ))
vOrient(ePitch) = -0.5*M_PI;
else
vOrient(ePitch) = asin(-vGroundNormal(eZ));
if (fabs(vOrient(ePitch)) == 0.5*M_PI)
vOrient(eYaw) = 0.;
else
vOrient(eYaw) = atan2(vGroundNormal(eY), vGroundNormal(eX));
vOrient(eRoll) = 0.;
UpdateCustomTransformMatrix();
if (eContactType == ctBOGEY) {
// Compute the rolling direction projected on the ground
// It consists in finding a vector 'r' such that 'r' lies in the plane (w,z) and r.n = 0 (scalar
// product) where:
// 'n' is the normal to the ground,
// (x,y,z) are the directions defined in the body coord system
// and 'w' is 'x' rotated by the steering angle (SteerAngle) in the plane (x,y).
// r = u * w + v * z and r.n = 0 => v/u = -w.n/z.n = a
// We also want u**2+v**2=1 and u > 0 (i.e. r orientated in the same 'direction' than w)
// after some arithmetic, one finds that :
double a = -(vGroundNormal(eX)*cos(SteerAngle)+vGroundNormal(eY)*sin(SteerAngle)) / vGroundNormal(eZ);
double u = 1. / sqrt(1. + a*a);
double v = a * u;
vRollingGroundVec = FGColumnVector3(u * cos(SteerAngle), u * sin(SteerAngle), v);
// 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)

View file

@ -38,11 +38,11 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <FGJSBBase.h>
#include <FGFDMExec.h>
#include <input_output/FGXMLElement.h>
#include <math/FGColumnVector3.h>
#include <math/FGTable.h>
#include "FGFDMExec.h"
#include "models/propulsion/FGForce.h"
#include "input_output/FGXMLElement.h"
#include "math/FGColumnVector3.h"
#include "math/FGTable.h"
#include <string>
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -199,7 +199,7 @@ CLASS DOCUMENTATION
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGLGear : public FGJSBBase
class FGLGear : public FGForce
{
public:
/// Brake grouping enumerators
@ -207,7 +207,7 @@ public:
/// Steering group membership enumerators
enum SteerType {stSteer, stFixed, stCaster};
/// Contact point type
enum ContactType {ctBOGEY, ctSTRUCTURE, ctUNKNOWN};
enum ContactType {ctBOGEY, ctSTRUCTURE};
/// Report type enumerators
enum ReportType {erNone=0, erTakeoff, erLand};
/// Damping types
@ -222,9 +222,7 @@ public:
~FGLGear();
/// The Force vector for this gear
FGColumnVector3& Force(void);
/// The Moment vector for this gear
FGColumnVector3& Moment(void) {return vMoment;}
FGColumnVector3& GetBodyForces(void);
/// Gets the location of the gear in Body axes
FGColumnVector3& GetBodyLocation(void) { return vWhlBodyVec; }
@ -269,35 +267,34 @@ public:
int GetBrakeGroup(void) const { return (int)eBrakeGrp; }
int GetSteerType(void) const { return (int)eSteerType; }
double GetZPosition(void) const { return vXYZ(3); }
void SetZPosition(double z) { vXYZ(3) = z; }
bool GetSteerable(void) const { return eSteerType != stFixed; }
bool GetSteerable(void) const { return eSteerType != stFixed; }
bool GetRetractable(void) const { return isRetractable; }
bool GetGearUnitUp(void) const { return GearUp; }
bool GetGearUnitDown(void) const { return GearDown; }
double GetWheelSideForce(void) const { return vLocalForce(eY); }
double GetWheelRollForce(void) const { return vLocalForce(eX); }
double GetWheelSideVel(void) const { return vWhlVelVec(eY); }
double GetWheelRollVel(void) const { return vWhlVelVec(eX); }
double GetBodyXForce(void) const { return vForce(eX); }
double GetBodyYForce(void) const { return vForce(eY); }
double GetWheelRollForce(void) {
FGColumnVector3 vForce = mTGear.Transposed() * FGForce::GetBodyForces();
return vForce(eX)*cos(SteerAngle) + vForce(eY)*sin(SteerAngle); }
double GetWheelSideForce(void) {
FGColumnVector3 vForce = mTGear.Transposed() * FGForce::GetBodyForces();
return vForce(eY)*cos(SteerAngle) - vForce(eX)*sin(SteerAngle); }
double GetWheelRollVel(void) const { return vWhlVelVec(eX)*cos(SteerAngle)
+ vWhlVelVec(eY)*sin(SteerAngle); }
double GetWheelSideVel(void) const { return vWhlVelVec(eY)*cos(SteerAngle)
- vWhlVelVec(eX)*sin(SteerAngle); }
double GetWheelSlipAngle(void) const { return WheelSlip; }
double GetWheelVel(int axis) const { return vWhlVelVec(axis);}
bool IsBogey(void) const { return (eContactType == ctBOGEY);}
double GetWheelVel(int axis) const { return vWhlVelVec(axis);}
bool IsBogey(void) const { return (eContactType == ctBOGEY);}
double GetGearUnitPos(void);
void bind(void);
private:
int GearNumber;
FGMatrix33 Tg2b, Tb2g;
FGColumnVector3 vXYZ;
FGColumnVector3 vMoment;
static const FGMatrix33 Tb2s;
FGMatrix33 mTGear;
FGColumnVector3 vGearOrient;
FGColumnVector3 vWhlBodyVec;
FGColumnVector3 vLocalGear;
FGColumnVector3 vForce;
FGColumnVector3 vLocalForce;
FGColumnVector3 vWhlVelVec, vLocalWhlVel; // Velocity of this wheel
FGColumnVector3 normal, cvel, vGroundNormal;
FGLocation contact, gearLoc;
@ -358,7 +355,6 @@ private:
Filter LatForceFilter;
Filter WheelSlipFilter;
FGFDMExec* Exec;
FGState* State;
FGAircraft* Aircraft;
FGPropagate* Propagate;

View file

@ -41,7 +41,7 @@ INCLUDES
#include "FGMassBalance.h"
#include "FGPropulsion.h"
#include "FGBuoyantForces.h"
#include <input_output/FGPropertyManager.h>
#include "input_output/FGPropertyManager.h"
namespace JSBSim {

View file

@ -39,9 +39,9 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGModel.h"
#include <math/FGColumnVector3.h>
#include <math/FGMatrix33.h>
#include <input_output/FGXMLElement.h>
#include "math/FGColumnVector3.h"
#include "math/FGMatrix33.h"
#include "input_output/FGXMLElement.h"
#include <vector>
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -38,9 +38,9 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <FGJSBBase.h>
#include <input_output/FGPropertyManager.h>
#include <input_output/FGXMLElement.h>
#include "FGJSBBase.h"
#include "input_output/FGPropertyManager.h"
#include "input_output/FGXMLElement.h"
#include <iostream>
#include <string>

View file

@ -162,8 +162,8 @@ bool FGOutput::InitModel(void)
if (!FGModel::InitModel()) return false;
if (Filename.size() > 0 && StartNewFile) {
int idx = BaseFilename.find_last_of(".");
int len = BaseFilename.length();
size_t idx = BaseFilename.find_last_of(".");
size_t len = BaseFilename.length();
string extension = "";
if (idx != string::npos) {
extension = BaseFilename.substr(idx, len-idx);
@ -1084,6 +1084,7 @@ void FGOutput::Debug(int from)
cout << scratch << " in CSV format output at rate " << 1/(State->Getdt()*rate) << " Hz" << endl;
break;
case otNone:
default:
cout << " No log output" << endl;
break;
}

View file

@ -57,12 +57,12 @@ INCLUDES
#include <iomanip>
#include "FGPropagate.h"
#include <FGFDMExec.h>
#include <FGState.h>
#include "FGFDMExec.h"
#include "FGState.h"
#include "FGAircraft.h"
#include "FGMassBalance.h"
#include "FGInertial.h"
#include <input_output/FGPropertyManager.h>
#include "input_output/FGPropertyManager.h"
namespace JSBSim {

View file

@ -38,11 +38,11 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <models/FGModel.h>
#include <math/FGColumnVector3.h>
#include <math/FGLocation.h>
#include <math/FGQuaternion.h>
#include <math/FGMatrix33.h>
#include "models/FGModel.h"
#include "math/FGColumnVector3.h"
#include "math/FGLocation.h"
#include "math/FGQuaternion.h"
#include "math/FGMatrix33.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
@ -538,6 +538,6 @@ private:
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#include <initialization/FGInitialCondition.h>
#include "initialization/FGInitialCondition.h"
#endif

View file

@ -45,14 +45,14 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGPropulsion.h"
#include <models/propulsion/FGRocket.h>
#include <models/propulsion/FGTurbine.h>
#include <models/propulsion/FGPiston.h>
#include <models/propulsion/FGElectric.h>
#include <models/propulsion/FGTurboProp.h>
#include <input_output/FGPropertyManager.h>
#include <input_output/FGXMLParse.h>
#include <math/FGColumnVector3.h>
#include "models/propulsion/FGRocket.h"
#include "models/propulsion/FGTurbine.h"
#include "models/propulsion/FGPiston.h"
#include "models/propulsion/FGElectric.h"
#include "models/propulsion/FGTurboProp.h"
#include "input_output/FGPropertyManager.h"
#include "input_output/FGXMLParse.h"
#include "math/FGColumnVector3.h"
#include <sstream>
namespace JSBSim {
@ -255,6 +255,20 @@ bool FGPropulsion::Load(Element* el)
FGModel::Load(el); // Perform base class Load.
// Process tank definitions first to establish the number of fuel tanks
Element* tank_element = el->FindElement("tank");
while (tank_element) {
Tanks.push_back(new FGTank(FDMExec, tank_element, numTanks));
if (Tanks.back()->GetType() == FGTank::ttFUEL) numFuelTanks++;
else if (Tanks.back()->GetType() == FGTank::ttOXIDIZER) numOxiTanks++;
else {cerr << "Unknown tank type specified." << endl; return false;}
numTanks++;
tank_element = el->FindNextElement("tank");
}
numSelectedFuelTanks = numFuelTanks;
numSelectedOxiTanks = numOxiTanks;
Element* engine_element = el->FindElement("engine");
while (engine_element) {
engine_filename = engine_element->GetAttributeValue("file");
@ -303,20 +317,6 @@ bool FGPropulsion::Load(Element* el)
ResetParser();
}
// Process tank definitions
Element* tank_element = el->FindElement("tank");
while (tank_element) {
Tanks.push_back(new FGTank(FDMExec, tank_element, numTanks));
if (Tanks.back()->GetType() == FGTank::ttFUEL) numFuelTanks++;
else if (Tanks.back()->GetType() == FGTank::ttOXIDIZER) numOxiTanks++;
else {cerr << "Unknown tank type specified." << endl; return false;}
numTanks++;
tank_element = el->FindNextElement("tank");
}
numSelectedFuelTanks = numFuelTanks;
numSelectedOxiTanks = numOxiTanks;
CalculateTankInertias();
if (!ThrottleAdded) FCS->AddThrottle(); // need to have at least one throttle

View file

@ -42,10 +42,10 @@ INCLUDES
#include <fstream>
#include "FGModel.h"
#include <models/propulsion/FGEngine.h>
#include <models/propulsion/FGTank.h>
#include <math/FGMatrix33.h>
#include <input_output/FGXMLFileRead.h>
#include "models/propulsion/FGEngine.h"
#include "models/propulsion/FGTank.h"
#include "math/FGMatrix33.h"
#include "input_output/FGXMLFileRead.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -40,7 +40,7 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <models/FGAtmosphere.h>
#include "models/FGAtmosphere.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -38,7 +38,7 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <models/FGAtmosphere.h>
#include "models/FGAtmosphere.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -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

View file

@ -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);
};

View file

@ -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;

View file

@ -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;

View file

@ -144,7 +144,10 @@ void FGDeadBand::Debug(int from)
cout << " DEADBAND WIDTH: " << width << endl;
}
cout << " GAIN: " << gain << endl;
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
if (IsOutput) {
for (unsigned int i=0; i<OutputNodes.size(); i++)
cout << " OUTPUT: " << OutputNodes[i]->getName() << endl;
}
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification

View file

@ -38,7 +38,7 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFCSComponent.h"
#include <input_output/FGXMLElement.h>
#include "input_output/FGXMLElement.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -52,11 +52,13 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
{
Element *input_element, *clip_el;
Input = Output = clipmin = clipmax = 0.0;
OutputNode = treenode = 0;
treenode = 0;
delay = index = 0;
ClipMinPropertyNode = ClipMaxPropertyNode = 0;
clipMinSign = clipMaxSign = 1.0;
IsOutput = clip = false;
string input, clip_string;
dt = fcs->GetDt();
PropertyManager = fcs->GetPropertyManager();
if (element->GetName() == string("lag_filter")) {
@ -91,6 +93,8 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
Type = "SENSOR";
} else if (element->GetName() == string("accelerometer")) {
Type = "ACCELEROMETER";
} else if (element->GetName() == string("magnetometer")) {
Type = "MAGNETOMETER";
} else if (element->GetName() == string("gyro")) {
Type = "GYRO";
} else if (element->GetName() == string("actuator")) {
@ -123,13 +127,34 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
input_element = element->FindNextElement("input");
}
if (element->FindElement("output")) {
Element *out_elem = element->FindElement("output");
while (out_elem) {
IsOutput = true;
OutputNode = PropertyManager->GetNode( element->FindElementValue("output"), true );
string output_node_name = out_elem->GetDataLine();
FGPropertyManager* OutputNode = PropertyManager->GetNode( output_node_name, true );
OutputNodes.push_back(OutputNode);
if (!OutputNode) {
cerr << endl << " Unable to process property: " << element->FindElementValue("output") << endl;
cerr << endl << " Unable to process property: " << output_node_name << endl;
throw(string("Invalid output property name in flight control definition"));
}
out_elem = element->FindNextElement("output");
}
Element* delay_elem = element->FindElement("delay");
if ( delay_elem ) {
delay = (unsigned int)delay_elem->GetDataAsNumber();
string delayType = delay_elem->GetAttributeValue("type");
if (delayType.length() > 0) {
if (delayType == "time") {
delay = (int)(delay / dt);
} else {
cerr << "Unallowed delay type" << endl;
}
} else {
delay = (int)(delay / dt);
}
output_array.resize(delay);
for (int i=0; i<delay; i++) output_array[i] = 0.0;
}
clip_el = element->FindElement("clipto");
@ -171,7 +196,7 @@ FGFCSComponent::~FGFCSComponent()
void FGFCSComponent::SetOutput(void)
{
OutputNode->setDoubleValue(Output);
for (unsigned int i=0; i<OutputNodes.size(); i++) OutputNodes[i]->setDoubleValue(Output);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -183,6 +208,16 @@ bool FGFCSComponent::Run(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCSComponent::Delay(void)
{
output_array[index] = Output;
if (index == delay-1) index = 0;
else index++;
Output = output_array[index];
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCSComponent::Clip(void)
{
if (clip) {
@ -258,6 +293,8 @@ void FGFCSComponent::Debug(int from)
cout << " Maximum limit: " << clipmax << endl;
}
}
if (delay > 0) cout <<" Frame delay: " << delay
<< " frames (" << delay*dt << " sec)" << endl;
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification

View file

@ -37,9 +37,9 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <FGJSBBase.h>
#include <input_output/FGPropertyManager.h>
#include <input_output/FGXMLElement.h>
#include "FGJSBBase.h"
#include "input_output/FGPropertyManager.h"
#include "input_output/FGXMLElement.h"
#include <string>
#include <vector>
@ -101,30 +101,34 @@ public:
virtual bool Run(void);
virtual void SetOutput(void);
inline double GetOutput (void) const {return Output;}
inline FGPropertyManager* GetOutputNode(void) { return OutputNode; }
inline string GetName(void) const {return Name;}
inline string GetType(void) const { return Type; }
double GetOutput (void) const {return Output;}
string GetName(void) const {return Name;}
string GetType(void) const { return Type; }
virtual double GetOutputPct(void) const { return 0; }
protected:
FGFCS* fcs;
FGPropertyManager* PropertyManager;
FGPropertyManager* treenode;
FGPropertyManager* OutputNode;
vector <FGPropertyManager*> OutputNodes;
FGPropertyManager* ClipMinPropertyNode;
FGPropertyManager* ClipMaxPropertyNode;
vector <FGPropertyManager*> InputNodes;
vector <float> InputSigns;
vector <double> output_array;
string Type;
string Name;
double Input;
double Output;
double clipmax, clipmin;
int delay;
int index;
float clipMinSign, clipMaxSign;
double dt;
bool IsOutput;
bool clip;
void Delay(void);
void Clip(void);
virtual void bind();
virtual void Debug(int from);

View file

@ -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

View file

@ -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

View file

@ -50,7 +50,6 @@ CLASS IMPLEMENTATION
FGFilter::FGFilter(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
{
dt = fcs->GetState()->Getdt();
Trigger = 0;
DynamicFilter = false;
@ -323,8 +322,13 @@ void FGFilter::Debug(int from)
if (PropertyNode[1] == 0L) cout << " C[1]: " << C[1] << endl;
else cout << " C[1] is the value of property: " << sgn << PropertyNode[1]->GetName() << endl;
break;
case eUnknown:
break;
}
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
if (IsOutput) {
for (unsigned int i=0; i<OutputNodes.size(); i++)
cout << " OUTPUT: " << OutputNodes[i]->getName() << endl;
}
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification

View file

@ -38,7 +38,7 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFCSComponent.h"
#include <input_output/FGXMLElement.h>
#include "input_output/FGXMLElement.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
@ -249,7 +249,6 @@ public:
enum {eLag, eLeadLag, eOrder2, eWashout, eIntegrator, eUnknown} FilterType;
private:
double dt;
double ca;
double cb;
double cc;

View file

@ -212,7 +212,10 @@ void FGGain::Debug(int from)
} else {
cout << " GAIN: " << Gain << endl;
}
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
if (IsOutput) {
for (unsigned int i=0; i<OutputNodes.size(); i++)
cout << " OUTPUT: " << OutputNodes[i]->getName() << endl;
}
if (Type == "AEROSURFACE_SCALE") {
cout << " In/Out Mapping:" << endl;
cout << " Input MIN: " << InMin << endl;

View file

@ -39,8 +39,8 @@ INCLUDES
#include "FGFCSComponent.h"
#include <string>
#include <input_output/FGXMLElement.h>
#include <math/FGTable.h>
#include "input_output/FGXMLElement.h"
#include "math/FGTable.h"
using std::string;

View file

@ -38,7 +38,7 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFCSComponent.h"
#include <input_output/FGXMLElement.h>
#include "input_output/FGXMLElement.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -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

View file

@ -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);
};

View file

@ -98,13 +98,13 @@ FGKinemat::~FGKinemat()
bool FGKinemat::Run(void )
{
double dt = fcs->GetState()->Getdt();
double dt0 = dt;
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
if (DoScale) Input *= Detents[NumDetents-1];
if (IsOutput) Output = OutputNode->getDoubleValue();
if (IsOutput) Output = OutputNodes[0]->getDoubleValue();
if (Input < Detents[0])
Input = Detents[0];
@ -113,7 +113,7 @@ bool FGKinemat::Run(void )
// Process all detent intervals the movement traverses until either the
// final value is reached or the time interval has finished.
while ( 0.0 < dt && !EqualToRoundoff(Input, Output) ) {
while ( dt0 > 0.0 && !EqualToRoundoff(Input, Output) ) {
// Find the area where Output is in
int ind;
@ -137,8 +137,8 @@ bool FGKinemat::Run(void )
double ThisDt = fabs((ThisInput-Output)/Rate);
// and clip to the timestep size
if (dt < ThisDt) {
ThisDt = dt;
if (dt0 < ThisDt) {
ThisDt = dt0;
if (Output < Input)
Output += ThisDt*Rate;
else
@ -148,7 +148,7 @@ bool FGKinemat::Run(void )
// is met even in inexact arithmetics ...
Output = ThisInput;
dt -= ThisDt;
dt0 -= ThisDt;
}
}
@ -190,7 +190,10 @@ void FGKinemat::Debug(int from)
for (int i=0;i<NumDetents;i++) {
cout << " " << Detents[i] << " " << TransitionTimes[i] << endl;
}
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
if (IsOutput) {
for (unsigned int i=0; i<OutputNodes.size(); i++)
cout << " OUTPUT: " << OutputNodes[i]->getName() << endl;
}
if (!DoScale) cout << " NOSCALE" << endl;
}
}

View file

@ -38,7 +38,7 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFCSComponent.h"
#include <input_output/FGXMLElement.h>
#include "input_output/FGXMLElement.h"
#include <vector>
#include <string>

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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);

View 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

View file

@ -119,7 +119,10 @@ void FGSummer::Debug(int from)
cout << " " << InputNodes[i]->getName() << endl;
}
if (Bias != 0.0) cout << " Bias: " << Bias << endl;
if (IsOutput) cout << " OUTPUT: " <<OutputNode->getName() << endl;
if (IsOutput) {
for (unsigned int i=0; i<OutputNodes.size(); i++)
cout << " OUTPUT: " << OutputNodes[i]->getName() << endl;
}
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification

View file

@ -38,7 +38,7 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFCSComponent.h"
#include <input_output/FGXMLElement.h>
#include "input_output/FGXMLElement.h"
#include <vector>
#include <string>

View file

@ -261,7 +261,10 @@ void FGSwitch::Debug(int from)
}
cout << endl;
}
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
if (IsOutput) {
for (unsigned int i=0; i<OutputNodes.size(); i++)
cout << " OUTPUT: " << OutputNodes[i]->getName() << endl;
}
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification

View file

@ -38,8 +38,8 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFCSComponent.h"
#include <input_output/FGXMLElement.h>
#include <math/FGCondition.h>
#include "input_output/FGXMLElement.h"
#include "math/FGCondition.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -9,6 +9,7 @@ libFlightControl_a_SOURCES = \
noinst_HEADERS = \
FGPID.h FGDeadBand.h FGFCSComponent.h FGFilter.h \
FGGain.h FGGradient.h FGKinemat.h FGSummer.h FGSwitch.h FGFCSFunction.h\
FGSensor.h FGActuator.h FGAccelerometer.h FGGyro.h FGMagnetometer.h
FGSensor.h FGActuator.h FGAccelerometer.h FGGyro.h FGMagnetometer.h \
FGSensorOrientation.h
INCLUDES = -I$(top_srcdir)/src/FDM/JSBSim

View file

@ -40,7 +40,7 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGElectric.h"
#include <models/FGPropulsion.h>
#include "models/FGPropulsion.h"
namespace JSBSim {

View file

@ -39,7 +39,7 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGEngine.h"
#include <input_output/FGXMLElement.h>
#include "input_output/FGXMLElement.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS

View file

@ -41,8 +41,8 @@ INCLUDES
#include "FGTank.h"
#include "FGPropeller.h"
#include "FGNozzle.h"
#include <input_output/FGXMLParse.h>
#include <math/FGColumnVector3.h>
#include "input_output/FGXMLParse.h"
#include "math/FGColumnVector3.h"
#include <fstream>
namespace JSBSim {
@ -67,6 +67,7 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
SLFuelFlowMax = 0.0;
MaxThrottle = 1.0;
MinThrottle = 0.0;
unsigned int i;
ResetToIC(); // initialize dynamic terms
@ -104,11 +105,17 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
cerr << "No thruster definition supplied with engine definition." << endl;
}
// Build and initialize the feed tank vector.
for (i=0; i<(Propulsion->GetNumTanks()); i++) {
SourceTanks.push_back(0);
}
// Load feed tank[s] references
local_element = engine_element->GetParent()->FindElement("feed");
if (local_element) {
while (local_element) {
AddFeedTank((int)local_element->GetDataAsNumber());
int tankID = (int)local_element->GetDataAsNumber();
AddFeedTank( tankID , Propulsion->GetTank(tankID)->GetPriority());
local_element = engine_element->GetParent()->FindNextElement("feed");
}
} else {
@ -165,35 +172,55 @@ void FGEngine::ConsumeFuel(void)
if (TrimMode) return;
unsigned int i;
double Fshortage, TanksWithFuel;
double Fshortage, TanksWithFuel, FuelNeeded;
FGTank* Tank;
Fshortage = TanksWithFuel = 0.0;
Fshortage = TanksWithFuel = FuelNeeded = 0.0;
double FuelToBurn = CalcFuelNeed();
unsigned int CurrentPriority = 1;
vector <int> FeedList;
Starved = false;
// 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;

View 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

View file

@ -41,11 +41,11 @@ and the cg.
*/
#include "FGForce.h"
#include <FGFDMExec.h>
#include <models/FGAircraft.h>
#include <models/FGPropagate.h>
#include <models/FGMassBalance.h>
#include <models/FGAerodynamics.h>
#include "FGFDMExec.h"
#include "models/FGAircraft.h"
#include "models/FGPropagate.h"
#include "models/FGMassBalance.h"
#include "models/FGAerodynamics.h"
namespace JSBSim {
@ -55,8 +55,8 @@ static const char *IdHdr = ID_FORCE;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGForce::FGForce(FGFDMExec *FDMExec) :
ttype(tNone),
fdmex(FDMExec)
fdmex(FDMExec),
ttype(tNone)
{
mT(1,1) = 1; //identity matrix
mT(2,2) = 1;
@ -112,23 +112,27 @@ FGMatrix33 FGForce::Transform(void)
void FGForce::UpdateCustomTransformMatrix(void)
{
double cp,sp,cr,sr,cy,sy;
double srsp, crcy, crsy;
cp=cos(vOrient(ePitch)); sp=sin(vOrient(ePitch));
cr=cos(vOrient(eRoll)); sr=sin(vOrient(eRoll));
cy=cos(vOrient(eYaw)); sy=sin(vOrient(eYaw));
srsp = sr*sp;
crcy = cr*cy;
crsy = cr*sy;
mT(1,1) = cp*cy;
mT(1,2) = cp*sy;
mT(1,3) = -sp;
mT(2,1) = cp*sy;
mT(3,1) = -sp;
mT(2,1) = sr*sp*cy - cr*sy;
mT(2,2) = sr*sp*sy + cr*cy;
mT(2,3) = sr*cp;
mT(1,2) = srsp*cy - crsy;
mT(2,2) = srsp*sy + crcy;
mT(3,2) = sr*cp;
mT(3,1) = cr*sp*cy + sr*sy;
mT(3,2) = cr*sp*sy - sr*cy;
mT(1,3) = crcy*sp + sr*sy;
mT(2,3) = crsy*sp - sr*cy;
mT(3,3) = cr*cp;
mT = mT.Inverse();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -57,10 +57,10 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <FGFDMExec.h>
#include <FGJSBBase.h>
#include <math/FGMatrix33.h>
#include <math/FGColumnVector3.h>
#include "FGFDMExec.h"
#include "FGJSBBase.h"
#include "math/FGMatrix33.h"
#include "math/FGColumnVector3.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
@ -240,6 +240,9 @@ public:
virtual FGColumnVector3& GetBodyForces(void);
inline double GetBodyXForce(void) const { return vFb(eX); }
inline double GetBodyYForce(void) const { return vFb(eY); }
inline double GetBodyZForce(void) const { return vFb(eZ); }
inline FGColumnVector3& GetMoments(void) { return vM; }
// Normal point of application, JSBsim structural coords
@ -273,12 +276,12 @@ public:
inline void SetLocation(FGColumnVector3 vv) { vXYZn = vv; SetActingLocation(vv);}
inline void SetActingLocation(FGColumnVector3 vv) { vActingXYZn = vv; }
inline double GetLocationX( void ) { return vXYZn(eX);}
inline double GetLocationY( void ) { return vXYZn(eY);}
inline double GetLocationZ( void ) { return vXYZn(eZ);}
inline double GetActingLocationX( void ) { return vActingXYZn(eX);}
inline double GetActingLocationY( void ) { return vActingXYZn(eY);}
inline double GetActingLocationZ( void ) { return vActingXYZn(eZ);}
inline double GetLocationX( void ) const { return vXYZn(eX);}
inline double GetLocationY( void ) const { return vXYZn(eY);}
inline double GetLocationZ( void ) const { return vXYZn(eZ);}
inline double GetActingLocationX( void ) const { return vActingXYZn(eX);}
inline double GetActingLocationY( void ) const { return vActingXYZn(eY);}
inline double GetActingLocationZ( void ) const { return vActingXYZn(eZ);}
FGColumnVector3& GetLocation(void) { return vXYZn; }
FGColumnVector3& GetActingLocation(void) { return vActingXYZn; }
@ -302,10 +305,10 @@ public:
double GetYaw(void) const {return vOrient(eYaw);}
inline FGColumnVector3& GetAnglesToBody(void) {return vOrient;}
inline double GetAnglesToBody(int axis) {return vOrient(axis);}
inline double GetAnglesToBody(int axis) const {return vOrient(axis);}
inline void SetTransformType(TransformType ii) { ttype=ii; }
inline TransformType GetTransformType(void) { return ttype; }
inline TransformType GetTransformType(void) const { return ttype; }
FGMatrix33 Transform(void);

View file

@ -38,7 +38,7 @@ INCLUDES
#include <sstream>
#include "FGNozzle.h"
#include <models/FGAtmosphere.h>
#include "models/FGAtmosphere.h"
namespace JSBSim {

View file

@ -43,7 +43,7 @@ INCLUDES
#include <sstream>
#include "FGPiston.h"
#include <models/FGPropulsion.h>
#include "models/FGPropulsion.h"
#include "FGPropeller.h"
namespace JSBSim {
@ -61,7 +61,8 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
rho_fuel(800), // estimate
calorific_value_fuel(47.3e6),
Cp_air(1005), // Specific heat (constant pressure) J/Kg/K
Cp_fuel(1700)
Cp_fuel(1700),
standard_pressure(101320.73)
{
string token;
@ -87,6 +88,9 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
Stroke = 4.375;
Cylinders = 4;
CompressionRatio = 8.5;
Z_airbox = -999;
Ram_Air_Factor = 1;
PeakMeanPistonSpeed_fps = 100;
// These are internal program variables
@ -102,6 +106,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
BoostSpeed = 0;
Boosted = false;
BoostOverride = 0;
BoostManual = 0;
bBoostOverride = false;
bTakeoffBoost = false;
TakeoffBoost = 0.0; // Default to no extra takeoff-boost
@ -187,10 +192,18 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
Stroke = el->FindElementValueAsNumberConvertTo("stroke","IN");
if (el->FindElement("cylinders"))
Cylinders = el->FindElementValueAsNumber("cylinders");
if (el->FindElement("air-intake-impedance-factor"))
Z_airbox = el->FindElementValueAsNumber("air-intake-impedance-factor");
if (el->FindElement("ram-air-factor"))
Ram_Air_Factor = el->FindElementValueAsNumber("ram-air-factor");
if (el->FindElement("peak-piston-speed"))
PeakMeanPistonSpeed_fps = el->FindElementValueAsNumber("peak-piston-speed");
if (el->FindElement("numboostspeeds")) { // Turbo- and super-charging parameters
BoostSpeeds = (int)el->FindElementValueAsNumber("numboostspeeds");
if (el->FindElement("boostoverride"))
BoostOverride = (int)el->FindElementValueAsNumber("boostoverride");
if (el->FindElement("boostmanual"))
BoostManual = (int)el->FindElementValueAsNumber("boostmanual");
if (el->FindElement("takeoffboost"))
TakeoffBoost = el->FindElementValueAsNumberConvertTo("takeoffboost", "PSI");
if (el->FindElement("ratedboost1"))
@ -243,6 +256,14 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
minMAP = MinManifoldPressure_inHg * inhgtopa; // inHg to Pa
maxMAP = MaxManifoldPressure_inHg * inhgtopa;
// For throttle
RatedMeanPistonSpeed_fps = ( MaxRPM * Stroke) / (360); // AKA 2 * (RPM/60) * ( Stroke / 12) or 2NS
if(Z_airbox < 998){
double Ze=RatedMeanPistonSpeed_fps/PeakMeanPistonSpeed_fps; // engine impedence
Z_airbox = (standard_pressure *Ze / maxMAP) - Ze; // impedence of airbox
}
Z_throttle=(((MaxRPM * Stroke) / 360)/((IdleRPM * Stroke) / 360))*(standard_pressure/minMAP - 1) - Z_airbox; // Constant for Throttle impedence
string property_name, base_property_name;
base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
property_name = base_property_name + "/power-hp";
@ -255,6 +276,12 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
PropertyManager->Tie(property_name, &MAP);
property_name = base_property_name + "/map-inhg";
PropertyManager->Tie(property_name, &ManifoldPressure_inHg);
property_name = base_property_name + "/air-intake-impedance-factor";
PropertyManager->Tie(property_name, &Z_airbox);
property_name = base_property_name + "/ram-air-factor";
PropertyManager->Tie(property_name, &Ram_Air_Factor);
property_name = base_property_name + "/boost-speed";
PropertyManager->Tie(property_name, &BoostSpeed);
// Set up and sanity-check the turbo/supercharging configuration based on the input values.
if (TakeoffBoost > RatedBoost[0]) bTakeoffBoost = true;
@ -302,6 +329,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number)
BoostSpeed = 0;
}
bBoostOverride = (BoostOverride == 1 ? true : false);
bBoostManual = (BoostManual == 1 ? true : false);
Debug(0); // Call Debug() routine from constructor if needed
}
@ -349,6 +377,8 @@ double FGPiston::Calculate(void)
//
p_amb = Atmosphere->GetPressure() * psftopa;
double p = Auxiliary->GetTotalPressure() * psftopa;
p_ram = (p - p_amb) * Ram_Air_Factor + p_amb;
T_amb = RankineToKelvin(Atmosphere->GetTemperature());
RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
@ -488,15 +518,20 @@ void FGPiston::doEngineStartup(void)
void FGPiston::doBoostControl(void)
{
if(BoostSpeed < BoostSpeeds - 1) {
// Check if we need to change to a higher boost speed
if(p_amb < BoostSwitchPressure[BoostSpeed] - BoostSwitchHysteresis) {
BoostSpeed++;
}
} else if(BoostSpeed > 0) {
// Check if we need to change to a lower boost speed
if(p_amb > BoostSwitchPressure[BoostSpeed - 1] + BoostSwitchHysteresis) {
BoostSpeed--;
if(BoostManual) {
if(BoostSpeed > BoostSpeeds-1) BoostSpeed = BoostSpeeds-1;
if(BoostSpeed < 0) BoostSpeed = 0;
} else {
if(BoostSpeed < BoostSpeeds - 1) {
// Check if we need to change to a higher boost speed
if(p_amb < BoostSwitchPressure[BoostSpeed] - BoostSwitchHysteresis) {
BoostSpeed++;
}
} else if(BoostSpeed > 0) {
// Check if we need to change to a lower boost speed
if(p_amb > BoostSwitchPressure[BoostSpeed - 1] + BoostSwitchHysteresis) {
BoostSpeed--;
}
}
}
}
@ -518,15 +553,13 @@ void FGPiston::doBoostControl(void)
void FGPiston::doMAP(void)
{
// estimate throttle plate area.
double throttle_area = ThrottleAngle*ThrottleAngle;
// Internal Combustion Engine in Theory and Practice, Volume 2. Charles Fayette Taylor. Revised Edition, 1985 fig 6-13
double map_coefficient = 1-((MeanPistonSpeed_fps*MeanPistonSpeed_fps)/(24978*throttle_area));
double Zt =(1-Throttle)*(1-Throttle)*Z_throttle; // throttle impedence
double Ze= MeanPistonSpeed_fps > 0 ? PeakMeanPistonSpeed_fps/MeanPistonSpeed_fps : 999999; // engine impedence
if ( map_coefficient < 0.1 ) map_coefficient = 0.1;
double map_coefficient = Ze/(Ze+Z_airbox+Zt);
// Add a one second lag to manifold pressure changes
double dMAP = (TMAP - p_amb * map_coefficient) * dt;
double dMAP = (TMAP - p_ram * map_coefficient) * dt;
TMAP -=dMAP;
// Find the mean effective pressure required to achieve this manifold pressure
@ -548,8 +581,7 @@ void FGPiston::doMAP(void)
}
}
// Boost the manifold pressure.
double boost_factor = BoostMul[BoostSpeed] * RPM/RatedRPM[BoostSpeed];
if (boost_factor < 1.0) boost_factor = 1.0; // boost will never reduce the MAP
double boost_factor = (( BoostMul[BoostSpeed] - 1 ) / RatedRPM[BoostSpeed] ) * RPM + 1;
MAP = TMAP * boost_factor;
// Now clip the manifold pressure to BCV or Wastegate setting.
if (bTakeoffPos) {
@ -581,7 +613,7 @@ void FGPiston::doMAP(void)
void FGPiston::doAirFlow(void)
{
double gamma = 1.4; // specific heat constants
double gamma = 1.1; // specific heat constants
// loss of volumentric efficiency due to difference between MAP and exhaust pressure
double ve =((gamma-1)/gamma)+( CompressionRatio -(p_amb/MAP))/(gamma*( CompressionRatio - 1));
@ -872,6 +904,7 @@ void FGPiston::Debug(int from)
cout << " MaxHP: " << MaxHP << endl;
cout << " Cycles: " << Cycles << endl;
cout << " IdleRPM: " << IdleRPM << endl;
cout << " MaxRPM: " << MaxRPM << endl;
cout << " MaxThrottle: " << MaxThrottle << endl;
cout << " MinThrottle: " << MinThrottle << endl;
cout << " ISFC: " << ISFC << endl;

View file

@ -40,8 +40,8 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGEngine.h"
#include <math/FGTable.h>
#include <input_output/FGXMLElement.h>
#include "math/FGTable.h"
#include "input_output/FGXMLElement.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
@ -81,9 +81,10 @@ CLASS DOCUMENTATION
<maxthrottle> {number} </maxthrottle>
<minthrottle> {number} </minthrottle>
<bsfc unit="{LBS/HP*HR | "KG/KW*HR"}"> {number} </bsfc>
<volumetric_efficiency> {number} </volumetric_efficiency>
<volumetric-efficiency> {number} </volumetric-efficiency>
<numboostspeeds> {number} </numboostspeeds>
<boostoverride> {0 | 1} </boostoverride>
<boostmanual> {0 | 1} </boostmanual>
<ratedboost1 unit="{INHG | PA | ATM}"> {number} </ratedboost1>
<ratedpower1 unit="{HP | WATTS}"> {number} </ratedpower1>
<ratedrpm1> {number} </ratedrpm1>
@ -97,6 +98,8 @@ CLASS DOCUMENTATION
<ratedrpm3> {number} </ratedrpm3>
<ratedaltitude3 unit="{FT | M}"> {number} </ratedaltitude3>
<takeoffboost unit="{INHG | PA | ATM}"> {number} </takeoffboost>
<air-intake-impedance-factor> {number} </air-intake-impedance-factor>
<ram-air-factor> {number} </ram-air-factor>
</piston_engine>
@endcode
@ -120,6 +123,10 @@ CLASS DOCUMENTATION
some way of getting the boost control cutout lever position (on or off)
from FlightGear first.
- BOOSTMANUAL - whether a multispeed supercharger will manually or
automatically shift boost speeds. On manual shifting the boost speeds
is accomplished by controling propulsion/engine/boostspeed
- The next items are all appended with either 1, 2 or 3 depending on which
boost speed they refer to, eg RATEDBOOST1. The rated values seems to have
been a common convention at the time to express the maximum continuously
@ -247,6 +254,8 @@ private:
const double calorific_value_fuel; // W/Kg (approximate)
const double Cp_air; // J/KgK
const double Cp_fuel; // J/KgK
const double standard_pressure; //Pa
FGTable *Lookup_Combustion_Efficiency;
FGTable *Mixture_Efficiency_Correlation;
@ -267,12 +276,19 @@ private:
double Bore; // inches
double Stroke; // inches
double Cylinders; // number
double CompressionRatio; // number
double CompressionRatio; // number
double Z_airbox; // number representing intake impediance before the throttle
double Z_throttle; // number representing slope of throttle impediance
double PeakMeanPistonSpeed_fps; // ft/sec speed where intake valves begin to choke. Typically 33-50 fps
double RatedMeanPistonSpeed_fps; // ft/sec derived from MaxRPM and stroke.
double Ram_Air_Factor; // number
double StarterHP; // initial horsepower of starter motor
int BoostSpeeds; // Number of super/turbocharger boost speeds - zero implies no turbo/supercharging.
int BoostSpeed; // The current boost-speed (zero-based).
bool Boosted; // Set true for boosted engine.
int BoostManual; // The raw value read in from the config file - should be 1 or 0 - see description below.
bool bBoostManual; // Set true if pilot must manually control the boost speed.
int BoostOverride; // The raw value read in from the config file - should be 1 or 0 - see description below.
bool bBoostOverride; // Set true if pilot override of the boost regulator was fitted.
// (Typically called 'war emergency power').
@ -302,6 +318,7 @@ private:
// Inputs (in addition to those in FGEngine).
//
double p_amb; // Pascals
double p_ram; // Pascals
double T_amb; // degrees Kelvin
double RPM; // revolutions per minute
double IAS; // knots

View file

@ -38,9 +38,9 @@ INCLUDES
#include <sstream>
#include "FGPropeller.h"
#include <models/FGPropagate.h>
#include <models/FGAtmosphere.h>
#include <models/FGAuxiliary.h>
#include "models/FGPropagate.h"
#include "models/FGAtmosphere.h"
#include "models/FGAuxiliary.h"
namespace JSBSim {

View file

@ -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