1
0
Fork 0

Sync with JSBSim cvs + Anders' patch to get it working with FlightGear.

This commit is contained in:
Erik Hofman 2010-10-26 09:48:56 +02:00
parent 25b333c07d
commit 68f5429048
31 changed files with 407 additions and 589 deletions

View file

@ -71,16 +71,9 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.80 2010/08/21 22:56:10 jberndt Exp $"; static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.82 2010/10/07 03:17:29 jberndt Exp $";
static const char *IdHdr = ID_FDMEXEC; static const char *IdHdr = ID_FDMEXEC;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GLOBAL DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
unsigned int FGFDMExec::FDMctr = 0;
FGPropertyManager* FGFDMExec::master=0;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@ -102,11 +95,21 @@ void checkTied ( FGPropertyManager *node )
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Constructor // Constructors
FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root) FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root)
{ {
FDMctr = new unsigned int;
*FDMctr = 0;
Initialize();
}
FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root), FDMctr(fdmctr)
{
Initialize();
}
void FGFDMExec::Initialize()
{
Frame = 0; Frame = 0;
Error = 0; Error = 0;
GroundCallback = 0; GroundCallback = 0;
@ -138,22 +141,26 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root)
dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is
// run in standalone mode with no initialization file. // run in standalone mode with no initialization file.
IdFDM = FDMctr; // The main (parent) JSBSim instance is always the "zeroth"
FDMctr++; // instance. "child" instances are loaded last.
try { try {
char* num = getenv("JSBSIM_DEBUG"); char* num = getenv("JSBSIM_DEBUG");
if (num) debug_lvl = atoi(num); // set debug level if (num) debug_lvl = atoi(num); // set debug level
} catch (...) { // if error set to 1 } catch (...) { // if error set to 1
debug_lvl = 1; debug_lvl = 1;
} }
if (Root == 0) { if (Root == 0) { // Then this is the root FDM
if (master == 0) Root = new FGPropertyManager; // Create the property manager
master = new FGPropertyManager;
Root = master; FDMctr = new unsigned int; // Create and initialize the child FDM counter
(*FDMctr) = 0;
} }
// Store this FDM's ID
IdFDM = (*FDMctr); // The main (parent) JSBSim instance is always the "zeroth"
// Prepare FDMctr for the next child FDM id
(*FDMctr)++; // instance. "child" instances are loaded last.
instance = Root->GetNode("/fdm/jsbsim",IdFDM,true); instance = Root->GetNode("/fdm/jsbsim",IdFDM,true);
Debug(0); Debug(0);
// this is to catch errors in binding member functions to the property tree. // this is to catch errors in binding member functions to the property tree.
@ -186,7 +193,17 @@ FGFDMExec::~FGFDMExec()
try { try {
checkTied( instance ); checkTied( instance );
DeAllocate(); DeAllocate();
if (Root == 0) delete master;
if (IdFDM == 0) { // Meaning this is no child FDM
if(Root != 0) {
delete Root;
Root = 0;
}
if(FDMctr != 0) {
delete FDMctr;
FDMctr = 0;
}
}
} catch ( string msg ) { } catch ( string msg ) {
cout << "Caught error: " << msg << endl; cout << "Caught error: " << msg << endl;
} }
@ -439,7 +456,7 @@ vector <string> FGFDMExec::EnumerateFDMs(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGFDMExec::LoadScript(string script, double deltaT) bool FGFDMExec::LoadScript(const string& script, double deltaT)
{ {
bool result; bool result;
@ -451,8 +468,8 @@ bool FGFDMExec::LoadScript(string script, double deltaT)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string SystemsPath, bool FGFDMExec::LoadModel(const string& AircraftPath, const string& EnginePath, const string& SystemsPath,
string model, bool addModelToPath) const string& model, bool addModelToPath)
{ {
FGFDMExec::AircraftPath = RootDir + AircraftPath; FGFDMExec::AircraftPath = RootDir + AircraftPath;
FGFDMExec::EnginePath = RootDir + EnginePath; FGFDMExec::EnginePath = RootDir + EnginePath;
@ -463,7 +480,7 @@ bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string Systems
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGFDMExec::LoadModel(string model, bool addModelToPath) bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
{ {
string token; string token;
string aircraftCfgFileName; string aircraftCfgFileName;
@ -730,7 +747,7 @@ void FGFDMExec::BuildPropertyCatalog(struct PropertyCatalogStructure* pcs)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGFDMExec::QueryPropertyCatalog(string in) string FGFDMExec::QueryPropertyCatalog(const string& in)
{ {
string results=""; string results="";
for (unsigned i=0; i<PropertyCatalog.size(); i++) { for (unsigned i=0; i<PropertyCatalog.size(); i++) {
@ -852,7 +869,7 @@ bool FGFDMExec::ReadChild(Element* el)
struct childData* child = new childData; struct childData* child = new childData;
child->exec = new FGFDMExec(); child->exec = new FGFDMExec(Root, FDMctr);
child->exec->SetChild(true); child->exec->SetChild(true);
string childAircraft = el->GetAttributeValue("name"); string childAircraft = el->GetAttributeValue("name");
@ -922,7 +939,7 @@ void FGFDMExec::EnableOutput(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGFDMExec::SetOutputDirectives(string fname) bool FGFDMExec::SetOutputDirectives(const string& fname)
{ {
bool result; bool result;

View file

@ -60,7 +60,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.52 2010/07/04 13:50:21 jberndt Exp $" #define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.54 2010/10/07 03:17:29 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -169,7 +169,7 @@ CLASS DOCUMENTATION
property actually maps toa function call of DoTrim(). property actually maps toa function call of DoTrim().
@author Jon S. Berndt @author Jon S. Berndt
@version $Revision: 1.52 $ @version $Revision: 1.54 $
*/ */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -206,8 +206,9 @@ class FGFDMExec : public FGJSBBase, public FGXMLFileRead
public: public:
/// Default constructor /// Default constructors
FGFDMExec(FGPropertyManager* root = 0); FGFDMExec(FGPropertyManager* root = 0);
FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr);
/// Default destructor /// Default destructor
~FGFDMExec(); ~FGFDMExec();
@ -252,8 +253,8 @@ public:
@param addModelToPath set to true to add the model name to the @param addModelToPath set to true to add the model name to the
AircraftPath, defaults to true AircraftPath, defaults to true
@return true if successful */ @return true if successful */
bool LoadModel(string AircraftPath, string EnginePath, string SystemsPath, bool LoadModel(const string& AircraftPath, const string& EnginePath, const string& SystemsPath,
string model, bool addModelToPath = true); const string& model, bool addModelToPath = true);
/** Loads an aircraft model. The paths to the aircraft and engine /** Loads an aircraft model. The paths to the aircraft and engine
config file directories must be set prior to calling this. See config file directories must be set prior to calling this. See
@ -265,28 +266,28 @@ public:
@param addModelToPath set to true to add the model name to the @param addModelToPath set to true to add the model name to the
AircraftPath, defaults to true AircraftPath, defaults to true
@return true if successful*/ @return true if successful*/
bool LoadModel(string model, bool addModelToPath = true); bool LoadModel(const string& model, bool addModelToPath = true);
/** Loads a script /** Loads a script
@param Script the full path name and file name for the script to be loaded. @param Script the full path name and file name for the script to be loaded.
@return true if successfully loadsd; false otherwise. */ @return true if successfully loadsd; false otherwise. */
bool LoadScript(string Script, double deltaT); bool LoadScript(const string& Script, double deltaT);
/** Sets the path to the engine config file directories. /** Sets the path to the engine config file directories.
@param path path to the directory under which engine config @param path path to the directory under which engine config
files are kept, for instance "engine" */ files are kept, for instance "engine" */
bool SetEnginePath(string path) { EnginePath = RootDir + path; return true; } bool SetEnginePath(const string& path) { EnginePath = RootDir + path; return true; }
/** Sets the path to the aircraft config file directories. /** Sets the path to the aircraft config file directories.
@param path path to the aircraft directory. For instance: @param path path to the aircraft directory. For instance:
"aircraft". Under aircraft, then, would be directories for various "aircraft". Under aircraft, then, would be directories for various
modeled aircraft such as C172/, x15/, etc. */ modeled aircraft such as C172/, x15/, etc. */
bool SetAircraftPath(string path) { AircraftPath = RootDir + path; return true; } bool SetAircraftPath(const string& path) { AircraftPath = RootDir + path; return true; }
/** Sets the path to the systems config file directories. /** Sets the path to the systems config file directories.
@param path path to the directory under which systems config @param path path to the directory under which systems config
files are kept, for instance "systems" */ files are kept, for instance "systems" */
bool SetSystemsPath(string path) { SystemsPath = RootDir + path; return true; } bool SetSystemsPath(const string& path) { SystemsPath = RootDir + path; return true; }
/// @name Top-level executive State and Model retrieval mechanism /// @name Top-level executive State and Model retrieval mechanism
//@{ //@{
@ -327,28 +328,28 @@ public:
//@} //@}
/// Retrieves the engine path. /// Retrieves the engine path.
inline string GetEnginePath(void) {return EnginePath;} inline const string& GetEnginePath(void) {return EnginePath;}
/// Retrieves the aircraft path. /// Retrieves the aircraft path.
inline string GetAircraftPath(void) {return AircraftPath;} inline const string& GetAircraftPath(void) {return AircraftPath;}
/// Retrieves the systems path. /// Retrieves the systems path.
inline string GetSystemsPath(void) {return SystemsPath;} inline const string& GetSystemsPath(void) {return SystemsPath;}
/// Retrieves the full aircraft path name. /// Retrieves the full aircraft path name.
inline string GetFullAircraftPath(void) {return FullAircraftPath;} inline const string& GetFullAircraftPath(void) {return FullAircraftPath;}
/** Retrieves the value of a property. /** Retrieves the value of a property.
@param property the name of the property @param property the name of the property
@result the value of the specified property */ @result the value of the specified property */
inline double GetPropertyValue(string property) {return instance->GetDouble(property);} inline double GetPropertyValue(const string& property) {return instance->GetDouble(property);}
/** Sets a property value. /** Sets a property value.
@param property the property to be set @param property the property to be set
@param value the value to set the property to */ @param value the value to set the property to */
inline void SetPropertyValue(string property, double value) { inline void SetPropertyValue(const string& property, double value) {
instance->SetDouble(property, value); instance->SetDouble(property, value);
} }
/// Returns the model name. /// Returns the model name.
string GetModelName(void) { return modelName; } const string& GetModelName(void) { return modelName; }
/* /*
/// Returns the current time. /// Returns the current time.
double GetSimTime(void); double GetSimTime(void);
@ -382,12 +383,12 @@ public:
be logged. be logged.
@param fname the filename of an output directives file. @param fname the filename of an output directives file.
*/ */
bool SetOutputDirectives(string fname); bool SetOutputDirectives(const string& fname);
/** Sets (or overrides) the output filename /** Sets (or overrides) the output filename
@param fname the name of the file to output data to @param fname the name of the file to output data to
@return true if successful, false if there is no output specified for the flight model */ @return true if successful, false if there is no output specified for the flight model */
bool SetOutputFileName(string fname) { bool SetOutputFileName(const string& fname) {
if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname); if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname);
else return false; else return false;
return true; return true;
@ -447,7 +448,7 @@ public:
* @param check The string to search for in the property catalog. * @param check The string to search for in the property catalog.
* @return the carriage-return-delimited string containing all matching strings * @return the carriage-return-delimited string containing all matching strings
* in the catalog. */ * in the catalog. */
string QueryPropertyCatalog(string check); string QueryPropertyCatalog(const string& check);
// Print the contents of the property catalog for the loaded aircraft. // Print the contents of the property catalog for the loaded aircraft.
void PrintPropertyCatalog(void); void PrintPropertyCatalog(void);
@ -495,11 +496,11 @@ public:
/** Sets the root directory where JSBSim starts looking for its system directories. /** Sets the root directory where JSBSim starts looking for its system directories.
@param rootDir the string containing the root directory. */ @param rootDir the string containing the root directory. */
void SetRootDir(string rootDir) {RootDir = rootDir;} void SetRootDir(const string& rootDir) {RootDir = rootDir;}
/** Retrieves teh Root Directory. /** Retrieves teh Root Directory.
@return the string representing the root (base) JSBSim directory. */ @return the string representing the root (base) JSBSim directory. */
string GetRootDir(void) const {return RootDir;} const string& GetRootDir(void) const {return RootDir;}
/** Increments the simulation time. /** Increments the simulation time.
@return the new simulation time. */ @return the new simulation time. */
@ -512,7 +513,6 @@ public:
int GetDebugLevel(void) const {return debug_lvl;}; int GetDebugLevel(void) const {return debug_lvl;};
private: private:
static unsigned int FDMctr;
int Error; int Error;
unsigned int Frame; unsigned int Frame;
unsigned int IdFDM; unsigned int IdFDM;
@ -536,8 +536,6 @@ private:
bool trim_status; bool trim_status;
int ta_mode; int ta_mode;
static FGPropertyManager *master;
FGGroundCallback* GroundCallback; FGGroundCallback* GroundCallback;
FGAtmosphere* Atmosphere; FGAtmosphere* Atmosphere;
FGFCS* FCS; FGFCS* FCS;
@ -558,12 +556,16 @@ private:
FGPropertyManager* Root; FGPropertyManager* Root;
FGPropertyManager* instance; FGPropertyManager* instance;
// The FDM counter is used to give each child FDM an unique ID. The root FDM has the ID 0
unsigned int* FDMctr;
vector <string> PropertyCatalog; vector <string> PropertyCatalog;
vector <FGOutput*> Outputs; vector <FGOutput*> Outputs;
vector <childData*> ChildFDMList; vector <childData*> ChildFDMList;
vector <FGModel*> Models; vector <FGModel*> Models;
void Initialize();
bool ReadFileHeader(Element*); bool ReadFileHeader(Element*);
bool ReadChild(Element*); bool ReadChild(Element*);
bool ReadPrologue(Element*); bool ReadPrologue(Element*);

View file

@ -1,178 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGState.cpp
Author: Jon Berndt
Date started: 11/17/98
Called by: FGFDMExec and accessed by all models.
------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU Lesser General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
See header file.
HISTORY
--------------------------------------------------------------------------------
11/17/98 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <cmath>
#include <iostream>
#include "FGState.h"
using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGState.cpp,v 1.15 2009/10/24 22:59:30 jberndt Exp $";
static const char *IdHdr = ID_STATE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
MACROS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGState::FGState(FGFDMExec* fdex)
{
FDMExec = fdex;
sim_time = 0.0;
dt = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is
// run in standalone mode with no initialization file.
Aircraft = FDMExec->GetAircraft();
Propagate = FDMExec->GetPropagate();
Auxiliary = FDMExec->GetAuxiliary();
FCS = FDMExec->GetFCS();
Atmosphere = FDMExec->GetAtmosphere();
Aerodynamics = FDMExec->GetAerodynamics();
GroundReactions = FDMExec->GetGroundReactions();
Propulsion = FDMExec->GetPropulsion();
PropertyManager = FDMExec->GetPropertyManager();
bind();
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGState::~FGState()
{
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGState::Initialize(FGInitialCondition *FGIC)
{
sim_time = 0.0;
Propagate->SetInitialState( FGIC );
Atmosphere->Run();
Atmosphere->SetWindNED( FGIC->GetWindNFpsIC(),
FGIC->GetWindEFpsIC(),
FGIC->GetWindDFpsIC() );
FGColumnVector3 vAeroUVW;
vAeroUVW = Propagate->GetUVW() + Propagate->GetTl2b()*Atmosphere->GetTotalWindNED();
double alpha, beta;
if (vAeroUVW(eW) != 0.0)
alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
else
alpha = 0.0;
if (vAeroUVW(eV) != 0.0)
beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV), (fabs(vAeroUVW(eU))/vAeroUVW(eU))*sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;
else
beta = 0.0;
Auxiliary->SetAB(alpha, beta);
double Vt = vAeroUVW.Magnitude();
Auxiliary->SetVt(Vt);
Auxiliary->SetMach(Vt/Atmosphere->GetSoundSpeed());
double qbar = 0.5*Vt*Vt*Atmosphere->GetDensity();
Auxiliary->Setqbar(qbar);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGState::bind(void)
{
PropertyManager->Tie("sim-time-sec", this, &FGState::Getsim_time);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGState::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGState" << endl;
if (from == 1) cout << "Destroyed: FGState" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
}

View file

@ -1,166 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGState.h
Author: Jon S. Berndt
Date started: 11/17/98
------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU Lesser General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
11/17/98 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGSTATE_H
#define FGSTATE_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <fstream>
#include <string>
#include <map>
#include "FGJSBBase.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"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_STATE "$Id: FGState.h,v 1.15 2009/10/02 10:30:07 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Encapsulates the calculation of aircraft state.
<h3>Properties</h3>
@property sim-time-sec (read only) cumulative simulation in seconds.
@author Jon S. Berndt
@version $Revision: 1.15 $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGState : public FGJSBBase
{
public:
/** Constructor
@param Executive a pointer to the parent executive object */
FGState(FGFDMExec*);
/// Destructor
~FGState();
/** Initializes the simulation state based on parameters from an Initial Conditions object.
@param FGIC pointer to an initial conditions object.
@see FGInitialConditions. */
void Initialize(FGInitialCondition *FGIC);
/// Returns the cumulative simulation time in seconds.
inline double Getsim_time(void) const { return sim_time; }
/// Returns the simulation delta T.
inline double Getdt(void) {return dt;}
/// Suspends the simulation and sets the delta T to zero.
inline void SuspendIntegration(void) {saved_dt = dt; dt = 0.0;}
/// Resumes the simulation by resetting delta T to the correct value.
inline void ResumeIntegration(void) {dt = saved_dt;}
/** Returns the simulation suspension state.
@return true if suspended, false if executing */
bool IntegrationSuspended(void) {return dt == 0.0;}
/** Sets the current sim time.
@param cur_time the current time
@return the current simulation time. */
inline double Setsim_time(double cur_time) {
sim_time = cur_time;
return sim_time;
}
/** Sets the integration time step for the simulation executive.
@param delta_t the time step in seconds. */
inline void Setdt(double delta_t) { dt = delta_t; }
/** Increments the simulation time.
@return the new simulation time. */
inline double IncrTime(void) {
sim_time+=dt;
return sim_time;
}
/** Prints a summary of simulator state (speed, altitude,
configuration, etc.) */
// void ReportState(void);
private:
double sim_time, dt;
double saved_dt;
FGFDMExec* FDMExec;
FGAircraft* Aircraft;
FGPropagate* Propagate;
FGAtmosphere* Atmosphere;
FGFCS* FCS;
FGAerodynamics* Aerodynamics;
FGGroundReactions* GroundReactions;
FGPropulsion* Propulsion;
FGAuxiliary* Auxiliary;
FGPropertyManager* PropertyManager;
void bind();
void Debug(int from);
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -18,7 +18,7 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
// $Id: JSBSim.cxx,v 1.62 2010/07/14 05:50:40 ehofman Exp $ // $Id: JSBSim.cxx,v 1.63 2010/10/07 03:45:40 jberndt Exp $
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -97,14 +97,15 @@ public:
/** Compute the altitude above ground. */ /** Compute the altitude above ground. */
virtual double GetAGLevel(double t, const FGLocation& l, virtual double GetAGLevel(double t, const FGLocation& l,
FGLocation& cont, FGLocation& cont, FGColumnVector3& n,
FGColumnVector3& n, FGColumnVector3& v) const { FGColumnVector3& v, FGColumnVector3& w) const {
double loc_cart[3] = { l(eX), l(eY), l(eZ) }; double loc_cart[3] = { l(eX), l(eY), l(eZ) };
double contact[3], normal[3], vel[3], agl = 0; double contact[3], normal[3], vel[3], angularVel[3], agl = 0;
mInterface->get_agl_ft(t, loc_cart, SG_METER_TO_FEET*2, contact, normal, mInterface->get_agl_ft(t, loc_cart, SG_METER_TO_FEET*2, contact, normal,
vel, &agl); vel, angularVel, &agl);
n = FGColumnVector3( normal[0], normal[1], normal[2] ); n = FGColumnVector3( normal[0], normal[1], normal[2] );
v = FGColumnVector3( vel[0], vel[1], vel[2] ); v = FGColumnVector3( vel[0], vel[1], vel[2] );
w = FGColumnVector3( angularVel[0], angularVel[1], angularVel[2] );
cont = FGColumnVector3( contact[0], contact[1], contact[2] ); cont = FGColumnVector3( contact[0], contact[1], contact[2] );
return agl; return agl;
} }
@ -489,7 +490,7 @@ void FGJSBsim::update( double dt )
if ( startup_trim->getBoolValue() ) { if ( startup_trim->getBoolValue() ) {
double contact[3], d[3], agl; double contact[3], d[3], agl;
get_agl_ft(fdmex->GetSimTime(), cart_pos, SG_METER_TO_FEET*2, contact, get_agl_ft(fdmex->GetSimTime(), cart_pos, SG_METER_TO_FEET*2, contact,
d, d, &agl); d, d, d, &agl);
double terrain_alt = sqrt(contact[0]*contact[0] + contact[1]*contact[1] double terrain_alt = sqrt(contact[0]*contact[0] + contact[1]*contact[1]
+ contact[2]*contact[2]) - fgic->GetSeaLevelRadiusFtIC(); + contact[2]*contact[2]) - fgic->GetSeaLevelRadiusFtIC();
@ -743,7 +744,7 @@ bool FGJSBsim::copy_from_JSBsim()
double loc_cart[3] = { l(FGJSBBase::eX), l(FGJSBBase::eY), l(FGJSBBase::eZ) }; double loc_cart[3] = { l(FGJSBBase::eX), l(FGJSBBase::eY), l(FGJSBBase::eZ) };
double contact[3], d[3], sd, t; double contact[3], d[3], sd, t;
is_valid_m(&t, d, &sd); is_valid_m(&t, d, &sd);
get_agl_ft(t, loc_cart, SG_METER_TO_FEET*2, contact, d, d, &sd); get_agl_ft(t, loc_cart, SG_METER_TO_FEET*2, contact, d, d, d, &sd);
double rwrad double rwrad
= FGColumnVector3( contact[0], contact[1], contact[2] ).Magnitude(); = FGColumnVector3( contact[0], contact[1], contact[2] ).Magnitude();
_set_Runway_altitude( rwrad - get_Sea_level_radius() ); _set_Runway_altitude( rwrad - get_Sea_level_radius() );
@ -1204,9 +1205,8 @@ void FGJSBsim::update_ic(void)
bool bool
FGJSBsim::get_agl_ft(double t, const double pt[3], double alt_off, FGJSBsim::get_agl_ft(double t, const double pt[3], double alt_off,
double contact[3], double normal[3], double vel[3], double contact[3], double normal[3], double vel[3],
double *agl) double angularVel[3], double *agl)
{ {
double angularVel[3];
const SGMaterial* material; const SGMaterial* material;
simgear::BVHNode::Id id; simgear::BVHNode::Id id;
if (!FGInterface::get_agl_ft(t, pt, alt_off, contact, normal, vel, if (!FGInterface::get_agl_ft(t, pt, alt_off, contact, normal, vel,
@ -1289,10 +1289,12 @@ void FGJSBsim::update_external_forces(double t_off)
double contact[3]; double contact[3];
double ground_normal[3]; double ground_normal[3];
double ground_vel[3]; double ground_vel[3];
double ground_angular_vel[3];
double root_agl_ft; double root_agl_ft;
if (!got_wire) { if (!got_wire) {
bool got = get_agl_ft(t_off, hook_area[1], 0, contact, ground_normal, ground_vel, &root_agl_ft); bool got = get_agl_ft(t_off, hook_area[1], 0, contact, ground_normal,
ground_vel, ground_angular_vel, &root_agl_ft);
if (got && root_agl_ft > 0 && root_agl_ft < hook_length) { if (got && root_agl_ft > 0 && root_agl_ft < hook_length) {
FGColumnVector3 ground_normal_body = Tl2b * (Tec2l * FGColumnVector3(ground_normal[0], ground_normal[1], ground_normal[2])); FGColumnVector3 ground_normal_body = Tl2b * (Tec2l * FGColumnVector3(ground_normal[0], ground_normal[1], ground_normal[2]));
FGColumnVector3 contact_body = Tl2b * Location.LocationToLocal(FGColumnVector3(contact[0], contact[1], contact[2])); FGColumnVector3 contact_body = Tl2b * Location.LocationToLocal(FGColumnVector3(contact[0], contact[1], contact[2]));

View file

@ -58,7 +58,6 @@ FORWARD DECLARATIONS
#include <FDM/JSBSim/FGFDMExec.h> #include <FDM/JSBSim/FGFDMExec.h>
namespace JSBSim { namespace JSBSim {
class FGState;
class FGAtmosphere; class FGAtmosphere;
class FGFCS; class FGFCS;
class FGPropulsion; class FGPropulsion;
@ -86,7 +85,7 @@ CLASS DOCUMENTATION
documentation for main for direction on running JSBSim apart from FlightGear. documentation for main for direction on running JSBSim apart from FlightGear.
@author Curtis L. Olson (original) @author Curtis L. Olson (original)
@author Tony Peden (Maintained and refined) @author Tony Peden (Maintained and refined)
@version $Id: JSBSim.hxx,v 1.13 2010/07/07 20:46:36 andgi Exp $ @version $Id: JSBSim.hxx,v 1.15 2010/10/07 03:45:40 jberndt Exp $
@see main in file JSBSim.cpp (use main() wrapper for standalone usage) @see main in file JSBSim.cpp (use main() wrapper for standalone usage)
*/ */
@ -208,13 +207,12 @@ public:
bool get_agl_ft(double t, const double pt[3], double alt_off, bool get_agl_ft(double t, const double pt[3], double alt_off,
double contact[3], double normal[3], double vel[3], double contact[3], double normal[3], double vel[3],
double *agl); double angularVel[3], double *agl);
private: private:
JSBSim::FGFDMExec *fdmex; JSBSim::FGFDMExec *fdmex;
JSBSim::FGInitialCondition *fgic; JSBSim::FGInitialCondition *fgic;
bool needTrim; bool needTrim;
JSBSim::FGState* State;
JSBSim::FGAtmosphere* Atmosphere; JSBSim::FGAtmosphere* Atmosphere;
JSBSim::FGFCS* FCS; JSBSim::FGFCS* FCS;
JSBSim::FGPropulsion* Propulsion; JSBSim::FGPropulsion* Propulsion;

View file

@ -2,8 +2,8 @@ SUBDIRS = initialization models input_output math
noinst_LIBRARIES = libJSBSim.a noinst_LIBRARIES = libJSBSim.a
libJSBSim_a_SOURCES = FGFDMExec.cpp FGJSBBase.cpp FGState.cpp JSBSim.cxx libJSBSim_a_SOURCES = FGFDMExec.cpp FGJSBBase.cpp JSBSim.cxx
noinst_HEADERS = FGFDMExec.h FGJSBBase.h FGState.h JSBSim.hxx noinst_HEADERS = FGFDMExec.h FGJSBBase.h JSBSim.hxx
INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/FDM/JSBSim INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/FDM/JSBSim

View file

@ -62,7 +62,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.44 2010/09/18 22:48:12 jberndt Exp $"; static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.46 2010/09/29 02:19:05 jberndt Exp $";
static const char *IdHdr = ID_INITIALCONDITION; static const char *IdHdr = ID_INITIALCONDITION;
//****************************************************************************** //******************************************************************************
@ -120,7 +120,7 @@ void FGInitialCondition::ResetIC(double u0, double v0, double w0,
FGQuaternion Quat( phi, theta, psi ); FGQuaternion Quat( phi, theta, psi );
Quat.Normalize(); Quat.Normalize();
const FGMatrix33& _Tl2b = Quat.GetT(); // local to body frame // const FGMatrix33& _Tl2b = Quat.GetT(); // local to body frame
const FGMatrix33& _Tb2l = Quat.GetTInv(); // body to local const FGMatrix33& _Tb2l = Quat.GetTInv(); // body to local
FGColumnVector3 _vUVW_BODY(u,v,w); FGColumnVector3 _vUVW_BODY(u,v,w);
@ -863,17 +863,22 @@ bool FGInitialCondition::Load(string rstfile, bool useStoredPath)
} }
double version = document->GetAttributeValueAsNumber("version"); double version = document->GetAttributeValueAsNumber("version");
bool result = false;
if (version == HUGE_VAL) { if (version == HUGE_VAL) {
return Load_v1(); // Default to the old version result = Load_v1(); // Default to the old version
} else if (version >= 3.0) { } else if (version >= 3.0) {
cerr << "Only initialization file formats 1 and 2 are currently supported" << endl; cerr << "Only initialization file formats 1 and 2 are currently supported" << endl;
exit (-1); exit (-1);
} else if (version >= 2.0) { } else if (version >= 2.0) {
return Load_v2(); result = Load_v2();
} else if (version >= 1.0) { } else if (version >= 1.0) {
return Load_v1(); result = Load_v1();
} }
fdmex->GetPropagate()->DumpState();
return result;
} }
//****************************************************************************** //******************************************************************************
@ -962,6 +967,7 @@ bool FGInitialCondition::Load_v1(void)
bool FGInitialCondition::Load_v2(void) bool FGInitialCondition::Load_v2(void)
{ {
int n; int n;
double epa = 0.0;
FGColumnVector3 vLoc, vOrient; FGColumnVector3 vLoc, vOrient;
bool result = true; bool result = true;
FGInertial* Inertial = fdmex->GetInertial(); FGInertial* Inertial = fdmex->GetInertial();
@ -969,10 +975,10 @@ bool FGInitialCondition::Load_v2(void)
FGColumnVector3 vOmegaEarth = FGColumnVector3(0.0, 0.0, Inertial->omega()); FGColumnVector3 vOmegaEarth = FGColumnVector3(0.0, 0.0, Inertial->omega());
if (document->FindElement("earth_position_angle")) { if (document->FindElement("earth_position_angle")) {
double epa = document->FindElementValueAsNumberConvertTo("earth_position_angle", "RAD"); epa = document->FindElementValueAsNumberConvertTo("earth_position_angle", "RAD");
}
Inertial->SetEarthPositionAngle(epa); Inertial->SetEarthPositionAngle(epa);
Propagate->GetVState()->vLocation.SetEarthPositionAngle(epa); Propagate->GetVState()->vLocation.SetEarthPositionAngle(epa);
}
Propagate->SetSeaLevelRadius(GetSeaLevelRadiusFtIC()); Propagate->SetSeaLevelRadius(GetSeaLevelRadiusFtIC());
@ -989,15 +995,15 @@ bool FGInitialCondition::Load_v2(void)
Element* position = document->FindElement("position"); Element* position = document->FindElement("position");
if (position) { if (position) {
vLoc = position->FindElementTripletConvertTo("FT");
string frame = position->GetAttributeValue("frame"); string frame = position->GetAttributeValue("frame");
frame = to_lower(frame); frame = to_lower(frame);
if (frame == "eci") { // Need to transform vLoc to ECEF for storage and use in FGLocation. if (frame == "eci") { // Need to transform vLoc to ECEF for storage and use in FGLocation.
vLoc = position->FindElementTripletConvertTo("FT");
vLoc = Propagate->GetTi2ec()*vLoc; vLoc = Propagate->GetTi2ec()*vLoc;
Propagate->SetLocation(vLoc); Propagate->SetLocation(vLoc);
} else if (frame == "ecef") { } else if (frame == "ecef") {
double AltitudeASL = 0.0; double AltitudeASL = 0.0;
if (vLoc.Magnitude() == 0.0) { if (!position->FindElement("x") && !position->FindElement("y") && !position->FindElement("z")) {
if (position->FindElement("radius")) { if (position->FindElement("radius")) {
AltitudeASL = position->FindElementValueAsNumberConvertTo("radius", "FT") - sea_level_radius; AltitudeASL = position->FindElementValueAsNumberConvertTo("radius", "FT") - sea_level_radius;
} else if (position->FindElement("altitudeAGL")) { } else if (position->FindElement("altitudeAGL")) {
@ -1008,11 +1014,15 @@ bool FGInitialCondition::Load_v2(void)
cerr << endl << " No altitude or radius initial condition is given." << endl; cerr << endl << " No altitude or radius initial condition is given." << endl;
result = false; result = false;
} }
Propagate->SetPosition( double lat_rad=0.0;
position->FindElementValueAsNumberConvertTo("longitude", "RAD"), double long_rad = 0.0;
position->FindElementValueAsNumberConvertTo("latitude", "RAD"), if (position->FindElement("longitude"))
AltitudeASL + GetSeaLevelRadiusFtIC()); long_rad = position->FindElementValueAsNumberConvertTo("longitude", "RAD");
if (position->FindElement("latitude"))
lat_rad = position->FindElementValueAsNumberConvertTo("latitude", "RAD");
Propagate->SetPosition(long_rad, lat_rad, AltitudeASL + GetSeaLevelRadiusFtIC());
} else { } else {
vLoc = position->FindElementTripletConvertTo("FT");
Propagate->SetLocation(vLoc); Propagate->SetLocation(vLoc);
} }
} else { } else {
@ -1072,7 +1082,9 @@ bool FGInitialCondition::Load_v2(void)
// Q_b/i = Q_e/i * Q_b/e // Q_b/i = Q_e/i * Q_b/e
FGQuaternion QuatEC2Body(vOrient); // Store relationship of Body frame wrt ECEF frame, Q_b/e FGQuaternion QuatEC2Body(vOrient); // Store relationship of Body frame wrt ECEF frame, Q_b/e
QuatEC2Body.Normalize();
FGQuaternion QuatI2EC = Propagate->GetTi2ec(); // Get Q_e/i from matrix FGQuaternion QuatI2EC = Propagate->GetTi2ec(); // Get Q_e/i from matrix
QuatI2EC.Normalize();
QuatI2Body = QuatI2EC * QuatEC2Body; // Q_b/i = Q_e/i * Q_b/e QuatI2Body = QuatI2EC * QuatEC2Body; // Q_b/i = Q_e/i * Q_b/e
} else if (frame == "local") { } else if (frame == "local") {
@ -1089,8 +1101,11 @@ bool FGInitialCondition::Load_v2(void)
// Q_b/i = Q_e/i * Q_n/e * Q_b/n // Q_b/i = Q_e/i * Q_n/e * Q_b/n
FGQuaternion QuatLocal2Body = FGQuaternion(vOrient); // Store relationship of Body frame wrt local (NED) frame, Q_b/n FGQuaternion QuatLocal2Body = FGQuaternion(vOrient); // Store relationship of Body frame wrt local (NED) frame, Q_b/n
QuatLocal2Body.Normalize();
FGQuaternion QuatEC2Local = Propagate->GetTec2l(); // Get Q_n/e from matrix FGQuaternion QuatEC2Local = Propagate->GetTec2l(); // Get Q_n/e from matrix
QuatEC2Local.Normalize();
FGQuaternion QuatI2EC = Propagate->GetTi2ec(); // Get Q_e/i from matrix FGQuaternion QuatI2EC = Propagate->GetTi2ec(); // Get Q_e/i from matrix
QuatI2EC.Normalize();
QuatI2Body = QuatI2EC * QuatEC2Local * QuatLocal2Body; // Q_b/i = Q_e/i * Q_n/e * Q_b/n QuatI2Body = QuatI2EC * QuatEC2Local * QuatLocal2Body; // Q_b/i = Q_e/i * Q_n/e * Q_b/n
} else { } else {
@ -1102,6 +1117,7 @@ bool FGInitialCondition::Load_v2(void)
} }
} }
QuatI2Body.Normalize();
Propagate->SetInertialOrientation(QuatI2Body); Propagate->SetInertialOrientation(QuatI2Body);
// Initialize vehicle velocity // Initialize vehicle velocity
@ -1201,7 +1217,9 @@ bool FGInitialCondition::Load_v2(void)
running_elements = document->FindNextElement("running"); running_elements = document->FindNextElement("running");
} }
// fdmex->RunIC(); fdmex->SuspendIntegration(); // saves the integration rate, dt, then sets it to 0.0.
fdmex->Run();
fdmex->ResumeIntegration(); // Restores the integration rate to what it was.
return result; return result;
} }

View file

@ -68,9 +68,10 @@ double FGGroundCallback::GetAltitude(const FGLocation& loc) const
double FGGroundCallback::GetAGLevel(double t, const FGLocation& loc, double FGGroundCallback::GetAGLevel(double t, const FGLocation& loc,
FGLocation& contact, FGColumnVector3& normal, FGLocation& contact, FGColumnVector3& normal,
FGColumnVector3& vel) const FGColumnVector3& vel, FGColumnVector3& angularVel) const
{ {
vel = FGColumnVector3(0.0, 0.0, 0.0); vel = FGColumnVector3(0.0, 0.0, 0.0);
angularVel = FGColumnVector3(0.0, 0.0, 0.0);
normal = FGColumnVector3(loc).Normalize(); normal = FGColumnVector3(loc).Normalize();
double loc_radius = loc.GetRadius(); // Get the radius of the given location double loc_radius = loc.GetRadius(); // Get the radius of the given location
// (e.g. the CG) // (e.g. the CG)

View file

@ -45,7 +45,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_GROUNDCALLBACK "$Id: FGGroundCallback.h,v 1.8 2009/10/02 10:30:09 jberndt Exp $" #define ID_GROUNDCALLBACK "$Id: FGGroundCallback.h,v 1.9 2010/10/07 03:45:40 jberndt Exp $"
namespace JSBSim { namespace JSBSim {
@ -59,7 +59,7 @@ CLASS DOCUMENTATION
ball formed earth. ball formed earth.
@author Mathias Froehlich @author Mathias Froehlich
@version $Id: FGGroundCallback.h,v 1.8 2009/10/02 10:30:09 jberndt Exp $ @version $Id: FGGroundCallback.h,v 1.9 2010/10/07 03:45:40 jberndt Exp $
*/ */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -85,7 +85,8 @@ public:
virtual double GetAltitude(const FGLocation& l) const; virtual double GetAltitude(const FGLocation& l) const;
/** Compute the altitude above ground. Defaults to sealevel altitude. */ /** Compute the altitude above ground. Defaults to sealevel altitude. */
virtual double GetAGLevel(double t, const FGLocation& l, FGLocation& cont, virtual double GetAGLevel(double t, const FGLocation& l, FGLocation& cont,
FGColumnVector3& n, FGColumnVector3& v) const; FGColumnVector3& n, FGColumnVector3& v,
FGColumnVector3& w) const;
virtual void SetTerrainGeoCentRadius(double radius) {mReferenceRadius = radius;} virtual void SetTerrainGeoCentRadius(double radius) {mReferenceRadius = radius;}
virtual double GetTerrainGeoCentRadius(void) const {return mReferenceRadius;} virtual double GetTerrainGeoCentRadius(void) const {return mReferenceRadius;}
private: private:

View file

@ -42,7 +42,7 @@ FORWARD DECLARATIONS
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.30 2010/09/04 14:15:15 jberndt Exp $"; static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.31 2010/09/29 02:22:03 jberndt Exp $";
static const char *IdHdr = ID_XMLELEMENT; static const char *IdHdr = ID_XMLELEMENT;
bool Element::converterIsInitialized = false; bool Element::converterIsInitialized = false;
@ -93,10 +93,10 @@ Element::Element(const string& nm)
convert["SLUG*FT2"]["KG*M2"] = 1.35594; convert["SLUG*FT2"]["KG*M2"] = 1.35594;
convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"]; convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"];
// Angles // Angles
convert["RAD"]["DEG"] = 360.0/(2.0*3.1415926); convert["RAD"]["DEG"] = 180.0/M_PI;
convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"]; convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"];
// Angular rates // Angular rates
convert["RAD/SEC"]["DEG/SEC"] = 360.0/(2.0*3.1415926); convert["RAD/SEC"]["DEG/SEC"] = convert["RAD"]["DEG"];
convert["DEG/SEC"]["RAD/SEC"] = 1.0/convert["RAD/SEC"]["DEG/SEC"]; convert["DEG/SEC"]["RAD/SEC"] = 1.0/convert["RAD/SEC"]["DEG/SEC"];
// Spring force // Spring force
convert["LBS/FT"]["N/M"] = 14.5939; convert["LBS/FT"]["N/M"] = 14.5939;
@ -478,7 +478,6 @@ FGColumnVector3 Element::FindElementTripletConvertTo( const string& target_units
if (!supplied_units.empty()) value *= convert[supplied_units][target_units]; if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
} else { } else {
value = 0.0; value = 0.0;
cerr << "Could not find an X triplet item for this column vector." << endl;
} }
triplet(1) = value; triplet(1) = value;
@ -489,7 +488,6 @@ FGColumnVector3 Element::FindElementTripletConvertTo( const string& target_units
if (!supplied_units.empty()) value *= convert[supplied_units][target_units]; if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
} else { } else {
value = 0.0; value = 0.0;
cerr << "Could not find a Y triplet item for this column vector." << endl;
} }
triplet(2) = value; triplet(2) = value;
@ -500,7 +498,6 @@ FGColumnVector3 Element::FindElementTripletConvertTo( const string& target_units
if (!supplied_units.empty()) value *= convert[supplied_units][target_units]; if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
} else { } else {
value = 0.0; value = 0.0;
cerr << "Could not find a Z triplet item for this column vector." << endl;
} }
triplet(3) = value; triplet(3) = value;

View file

@ -40,7 +40,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGXMLParse.cpp,v 1.10 2009/10/24 22:59:30 jberndt Exp $"; static const char *IdSrc = "$Id: FGXMLParse.cpp,v 1.11 2010/09/28 02:54:03 jberndt Exp $";
static const char *IdHdr = ID_XMLPARSE; static const char *IdHdr = ID_XMLPARSE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -122,7 +122,7 @@ void FGXMLParse::endElement (const char * name)
{ {
if (!working_string.empty()) { if (!working_string.empty()) {
vector <string> work_strings = split(working_string, '\n'); vector <string> work_strings = split(working_string, '\n');
for (int i=0; i<work_strings.size(); i++) current_element->AddData(work_strings[i]); for (unsigned int i=0; i<work_strings.size(); i++) current_element->AddData(work_strings[i]);
} }
current_element = current_element->GetParent(); current_element = current_element->GetParent();

View file

@ -65,7 +65,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FDMSOCKET "$Id: FGfdmSocket.h,v 1.19 2010/05/13 03:07:59 jberndt Exp $" #define ID_FDMSOCKET "$Id: FGfdmSocket.h,v 1.20 2010/10/15 11:30:28 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -107,7 +107,7 @@ public:
void Close(void); void Close(void);
bool GetConnectStatus(void) {return connected;} bool GetConnectStatus(void) {return connected;}
enum {ptUDP, ptTCP}; enum ProtocolType {ptUDP, ptTCP} ;
private: private:
int sckt; int sckt;

View file

@ -45,7 +45,7 @@ INCLUDES
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGLocation.cpp,v 1.22 2010/09/18 22:47:17 jberndt Exp $"; static const char *IdSrc = "$Id: FGLocation.cpp,v 1.23 2010/09/22 11:34:09 jberndt Exp $";
static const char *IdHdr = ID_LOCATION; static const char *IdHdr = ID_LOCATION;
using std::cerr; using std::cerr;
using std::endl; using std::endl;
@ -319,7 +319,7 @@ void FGLocation::ComputeDerivedUnconditional(void) const
if (a != 0.0 && b != 0.0) { if (a != 0.0 && b != 0.0) {
double c, p, q, s, t, u, v, w, z, p2, u2, r0; double c, p, q, s, t, u, v, w, z, p2, u2, r0;
double Ne, P, Q0, Q, signz0, sqrt_q; double Ne, P, Q0, Q, signz0, sqrt_q, z_term;
p = fabs(mECLoc(eZ))/eps2; p = fabs(mECLoc(eZ))/eps2;
s = r02/(e2*eps2); s = r02/(e2*eps2);
p2 = p*p; p2 = p*p;
@ -328,8 +328,7 @@ void FGLocation::ComputeDerivedUnconditional(void) const
if (q>0) if (q>0)
{ {
u = p/sqrt_q; u = p/sqrt_q;
// u2 = p2/q; u2 = p2/q;
u2 = u*u;
v = b2*u2/q; v = b2*u2/q;
P = 27.0*v*s/q; P = 27.0*v*s/q;
Q0 = sqrt(P+1) + sqrt(P); Q0 = sqrt(P+1) + sqrt(P);
@ -338,10 +337,11 @@ void FGLocation::ComputeDerivedUnconditional(void) const
c = sqrt(u2 - 1 + 2.0*t); c = sqrt(u2 - 1 + 2.0*t);
w = (c - u)/2.0; w = (c - u)/2.0;
signz0 = mECLoc(eZ)>=0?1.0:-1.0; signz0 = mECLoc(eZ)>=0?1.0:-1.0;
if ((sqrt(t*t+v)-u*w-0.5*t-0.25) < 0.0) { z_term = sqrt(t*t+v)-u*w-0.5*t-0.25;
if (z_term < 0.0) {
z = 0.0; z = 0.0;
} else { } else {
z = signz0*sqrt_q*(w+sqrt(sqrt(t*t+v)-u*w-0.5*t-0.25)); z = signz0*sqrt_q*(w+sqrt(z_term));
} }
Ne = a*sqrt(1+eps2*z*z/b2); Ne = a*sqrt(1+eps2*z*z/b2);
mGeodLat = asin((eps2+1.0)*(z/Ne)); mGeodLat = asin((eps2+1.0)*(z/Ne));

View file

@ -47,7 +47,7 @@ SENTRY
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_QUATERNION "$Id: FGQuaternion.h,v 1.17 2010/06/30 03:13:40 jberndt Exp $" #define ID_QUATERNION "$Id: FGQuaternion.h,v 1.18 2010/09/29 02:19:05 jberndt Exp $"
namespace JSBSim { namespace JSBSim {
@ -177,7 +177,7 @@ public:
const FGMatrix33& GetTInv(void) const { ComputeDerived(); return mTInv; } const FGMatrix33& GetTInv(void) const { ComputeDerived(); return mTInv; }
/** Retrieves the Euler angles. /** Retrieves the Euler angles.
@return a reference to the triad of euler angles corresponding @return a reference to the triad of Euler angles corresponding
to this quaternion rotation. to this quaternion rotation.
units radians */ units radians */
const FGColumnVector3& GetEuler(void) const { const FGColumnVector3& GetEuler(void) const {
@ -186,7 +186,7 @@ public:
} }
/** Retrieves the Euler angles. /** Retrieves the Euler angles.
@param i the euler angle index. @param i the Euler angle index.
units radians. units radians.
@return a reference to the i-th euler angles corresponding @return a reference to the i-th euler angles corresponding
to this quaternion rotation. to this quaternion rotation.
@ -197,7 +197,7 @@ public:
} }
/** Retrieves the Euler angles. /** Retrieves the Euler angles.
@param i the euler angle index. @param i the Euler angle index.
@return a reference to the i-th euler angles corresponding @return a reference to the i-th euler angles corresponding
to this quaternion rotation. to this quaternion rotation.
units degrees */ units degrees */
@ -206,6 +206,15 @@ public:
return radtodeg*mEulerAngles(i); return radtodeg*mEulerAngles(i);
} }
/** Retrieves the Euler angle vector.
@return an Euler angle column vector corresponding
to this quaternion rotation.
units degrees */
FGColumnVector3 const GetEulerDeg(void) const {
ComputeDerived();
return radtodeg*mEulerAngles;
}
/** Retrieves sine of the given euler angle. /** Retrieves sine of the given euler angle.
@return the sine of the Euler angle theta (pitch attitude) corresponding @return the sine of the Euler angle theta (pitch attitude) corresponding
to this quaternion rotation. */ to this quaternion rotation. */

View file

@ -47,7 +47,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGTable.cpp,v 1.23 2010/09/16 11:01:24 jberndt Exp $"; static const char *IdSrc = "$Id: FGTable.cpp,v 1.27 2010/10/21 11:09:56 jberndt Exp $";
static const char *IdHdr = ID_TABLE; static const char *IdHdr = ID_TABLE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -143,13 +143,12 @@ FGTable::FGTable(FGPropertyManager* propMan, Element* el) : PropertyManager(prop
internal = true; internal = true;
} else { } else {
// internal table is a child element of a restricted type // internal table is a child element of a restricted type
cerr << endl << fgred << " An internal table cannot be nested within another type," << endl; throw(" An internal table cannot be nested within another type,"
cerr << " such as a function. The 'internal' keyword is ignored." << fgdef << endl << endl; " such as a function. The 'internal' keyword is ignored.");
} }
} else if (!call_type.empty()) { } else if (!call_type.empty()) {
cerr << endl << fgred << " An unknown table type attribute is listed: " << call_type throw(" An unknown table type attribute is listed: "
<< ". Execution cannot continue." << fgdef << endl << endl; ". Execution cannot continue.");
abort();
} }
// Determine and store the lookup properties for this table unless this table // Determine and store the lookup properties for this table unless this table
@ -218,8 +217,7 @@ FGTable::FGTable(FGPropertyManager* propMan, Element* el) : PropertyManager(prop
brkpt_string = el->GetAttributeValue("breakPoint"); brkpt_string = el->GetAttributeValue("breakPoint");
if (brkpt_string.empty()) { if (brkpt_string.empty()) {
// no independentVars found, and table is not marked as internal, nor is it a 3D table // no independentVars found, and table is not marked as internal, nor is it a 3D table
cerr << endl << fgred << "No independent variable found for table." << fgdef << endl << endl; throw("No independent variable found for table.");
abort();
} }
} }
// end lookup property code // end lookup property code
@ -249,10 +247,11 @@ FGTable::FGTable(FGPropertyManager* propMan, Element* el) : PropertyManager(prop
case 2: case 2:
nRows = tableData->GetNumDataLines()-1; nRows = tableData->GetNumDataLines()-1;
if (nRows >= 2) nCols = FindNumColumns(tableData->GetDataLine(0)); if (nRows >= 2) {
else { nCols = FindNumColumns(tableData->GetDataLine(0));
cerr << endl << fgred << "Not enough rows in this table." << fgdef << endl; if (nCols < 2) throw(string("Not enough columns in table data."));
abort(); } else {
throw(string("Not enough rows in the table data."));
} }
Type = tt2D; Type = tt2D;
@ -290,6 +289,63 @@ FGTable::FGTable(FGPropertyManager* propMan, Element* el) : PropertyManager(prop
break; break;
} }
// Sanity checks: lookup indices must be increasing monotonically
unsigned int r,c,b;
// find next xml element containing a name attribute
// to indicate where the error occured
Element* nameel = el;
while (nameel != 0 && nameel->GetAttributeValue("name") == "")
nameel=nameel->GetParent();
// check breakpoints, if applicable
if (dimension > 2) {
for (b=2; b<=nTables; ++b) {
if (Data[b][1] <= Data[b-1][1]) {
stringstream errormsg;
errormsg << fgred << highint << endl
<< " FGTable: breakpoint lookup is not monotonically increasing" << endl
<< " in breakpoint " << b;
if (nameel != 0) errormsg << " of table in " << nameel->GetAttributeValue("name");
errormsg << ":" << reset << endl
<< " " << Data[b][1] << "<=" << Data[b-1][1] << endl;
throw(errormsg.str());
}
}
}
// check columns, if applicable
if (dimension > 1) {
for (c=2; c<=nCols; ++c) {
if (Data[0][c] <= Data[0][c-1]) {
stringstream errormsg;
errormsg << fgred << highint << endl
<< " FGTable: column lookup is not monotonically increasing" << endl
<< " in column " << c;
if (nameel != 0) errormsg << " of table in " << nameel->GetAttributeValue("name");
errormsg << ":" << reset << endl
<< " " << Data[0][c] << "<=" << Data[0][c-1] << endl;
throw(errormsg.str());
}
}
}
// check rows
if (dimension < 3) { // in 3D tables, check only rows of subtables
for (r=2; r<=nRows; ++r) {
if (Data[r][0]<=Data[r-1][0]) {
stringstream errormsg;
errormsg << fgred << highint << endl
<< " FGTable: row lookup is not monotonically increasing" << endl
<< " in row " << r;
if (nameel != 0) errormsg << " of table in " << nameel->GetAttributeValue("name");
errormsg << ":" << reset << endl
<< " " << Data[r][0] << "<=" << Data[r-1][0] << endl;
throw(errormsg.str());
}
}
}
bind(); bind();
if (debug_lvl & 1) Print(); if (debug_lvl & 1) Print();

View file

@ -52,7 +52,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.32 2010/09/07 00:40:03 jberndt Exp $"; static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.34 2010/10/15 11:32:41 jberndt Exp $";
static const char *IdHdr = ID_AERODYNAMICS; static const char *IdHdr = ID_AERODYNAMICS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -349,7 +349,14 @@ bool FGAerodynamics::Load(Element *element)
axis = axis_element->GetAttributeValue("name"); axis = axis_element->GetAttributeValue("name");
function_element = axis_element->FindElement("function"); function_element = axis_element->FindElement("function");
while (function_element) { while (function_element) {
ca.push_back( new FGFunction(PropertyManager, function_element) ); string current_func_name = function_element->GetAttributeValue("name");
try {
ca.push_back( new FGFunction(PropertyManager, function_element) );
} catch (string const str) {
cerr << endl << fgred << "Error loading aerodynamic function in "
<< current_func_name << ":" << str << " Aborting." << reset << endl;
return false;
}
function_element = axis_element->FindNextElement("function"); function_element = axis_element->FindNextElement("function");
} }
Coeff[AxisIdx[axis]] = ca; Coeff[AxisIdx[axis]] = ca;

View file

@ -59,7 +59,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.42 2010/07/27 23:18:19 jberndt Exp $"; static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.44 2010/10/10 15:10:15 jberndt Exp $";
static const char *IdHdr = ID_AUXILIARY; static const char *IdHdr = ID_AUXILIARY;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -173,7 +173,7 @@ bool FGAuxiliary::Run()
vAeroUVW = vUVW - wind; vAeroUVW = vUVW - wind;
Vt = vAeroUVW.Magnitude(); Vt = vAeroUVW.Magnitude();
if ( Vt > 0.05) { if ( Vt > 1.0 ) {
if (vAeroUVW(eW) != 0.0) if (vAeroUVW(eW) != 0.0)
alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0; alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
if (vAeroUVW(eV) != 0.0) if (vAeroUVW(eV) != 0.0)
@ -182,10 +182,9 @@ bool FGAuxiliary::Run()
double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW)); double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
double signU=1; double signU=1;
if (vAeroUVW(eU) != 0.0) if (vAeroUVW(eU) < 0.0) signU=-1;
signU = vAeroUVW(eU)/fabs(vAeroUVW(eU));
if ( (mUW == 0.0) || (Vt == 0.0) ) { if ( mUW < 1.0 ) {
adot = 0.0; adot = 0.0;
bdot = 0.0; bdot = 0.0;
} else { } else {

View file

@ -63,7 +63,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGFCS.cpp,v 1.70 2010/08/21 22:56:11 jberndt Exp $"; static const char *IdSrc = "$Id: FGFCS.cpp,v 1.71 2010/09/28 02:54:03 jberndt Exp $";
static const char *IdHdr = ID_FCS; static const char *IdHdr = ID_FCS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -187,7 +187,7 @@ bool FGFCS::InitModel(void)
void FGFCS::LateBind(void) void FGFCS::LateBind(void)
{ {
int i; unsigned int i;
for (i=0; i<Systems.size(); i++) Systems[i]->LateBind(); for (i=0; i<Systems.size(); i++) Systems[i]->LateBind();
for (i=0; i<APComponents.size(); i++) APComponents[i]->LateBind(); for (i=0; i<APComponents.size(); i++) APComponents[i]->LateBind();

View file

@ -51,7 +51,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FCS "$Id: FGFCS.h,v 1.30 2010/09/05 17:31:40 jberndt Exp $" #define ID_FCS "$Id: FGFCS.h,v 1.31 2010/09/22 11:33:40 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -168,7 +168,7 @@ CLASS DOCUMENTATION
@property gear/tailhook-pos-norm @property gear/tailhook-pos-norm
@author Jon S. Berndt @author Jon S. Berndt
@version $Revision: 1.30 $ @version $Revision: 1.31 $
@see FGActuator @see FGActuator
@see FGDeadBand @see FGDeadBand
@see FGFCSFunction @see FGFCSFunction
@ -345,11 +345,6 @@ public:
bool GetPropFeather(int engine) const { return PropFeather[engine]; } bool GetPropFeather(int engine) const { return PropFeather[engine]; }
//@} //@}
/** Retrieves the State object pointer.
This is used by the FGFCS-owned components.
@return pointer to the State object */
FGState* GetState(void) { return State; }
/** Retrieves all component names for inclusion in output stream /** Retrieves all component names for inclusion in output stream
@param delimiter either a tab or comma string depending on output type @param delimiter either a tab or comma string depending on output type
@return a string containing the descriptive names for all components */ @return a string containing the descriptive names for all components */

View file

@ -45,7 +45,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGInertial.cpp,v 1.18 2010/03/28 05:57:00 jberndt Exp $"; static const char *IdSrc = "$Id: FGInertial.cpp,v 1.19 2010/10/10 15:06:38 jberndt Exp $";
static const char *IdHdr = ID_INERTIAL; static const char *IdHdr = ID_INERTIAL;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -148,7 +148,8 @@ FGColumnVector3 FGInertial::GetGravityJ2(FGColumnVector3 position) const
double lat = Propagate->GetLatitude(); double lat = Propagate->GetLatitude();
double sinLat = sin(lat); double sinLat = sin(lat);
double preCommon = 1.5*J2*(a/r)*(a/r); double adivr = a/r;
double preCommon = 1.5*J2*adivr*adivr;
double xy = 1.0 - 5.0*(sinLat*sinLat); double xy = 1.0 - 5.0*(sinLat*sinLat);
double z = 3.0 - 5.0*(sinLat*sinLat); double z = 3.0 - 5.0*(sinLat*sinLat);
double GMOverr2 = GM/(r*r); double GMOverr2 = GM/(r*r);

View file

@ -48,6 +48,7 @@ INCLUDES
#include "FGMassBalance.h" #include "FGMassBalance.h"
#include "math/FGTable.h" #include "math/FGTable.h"
#include <cstdlib> #include <cstdlib>
#include <cstring>
using namespace std; using namespace std;
@ -61,7 +62,7 @@ DEFINITIONS
GLOBAL DATA GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
static const char *IdSrc = "$Id: FGLGear.cpp,v 1.76 2010/07/30 11:50:01 jberndt Exp $"; static const char *IdSrc = "$Id: FGLGear.cpp,v 1.78 2010/10/07 03:45:40 jberndt Exp $";
static const char *IdHdr = ID_LGEAR; static const char *IdHdr = ID_LGEAR;
// Body To Structural (body frame is rotated 180 deg about Y and lengths are given in // Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
@ -76,7 +77,8 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
FGForce(fdmex), FGForce(fdmex),
GearNumber(number), GearNumber(number),
SteerAngle(0.0), SteerAngle(0.0),
Castered(false) Castered(false),
StaticFriction(false)
{ {
Element *force_table=0; Element *force_table=0;
Element *dampCoeff=0; Element *dampCoeff=0;
@ -254,9 +256,7 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
Curvature = 1.03; Curvature = 1.03;
// Initialize Lagrange multipliers // Initialize Lagrange multipliers
LMultiplier[ftRoll].value = 0.; memset(LMultiplier, 0, sizeof(LMultiplier));
LMultiplier[ftSide].value = 0.;
LMultiplier[ftRoll].value = 0.;
Debug(0); Debug(0);
} }
@ -281,13 +281,15 @@ FGColumnVector3& FGLGear::GetBodyForces(void)
if (isRetractable) ComputeRetractionState(); if (isRetractable) ComputeRetractionState();
if (GearDown) { if (GearDown) {
FGColumnVector3 angularVel;
vWhlBodyVec = MassBalance->StructuralToBody(vXYZn); // Get wheel in body frame vWhlBodyVec = MassBalance->StructuralToBody(vXYZn); // Get wheel in body frame
vLocalGear = Propagate->GetTb2l() * vWhlBodyVec; // Get local frame wheel location vLocalGear = Propagate->GetTb2l() * vWhlBodyVec; // Get local frame wheel location
gearLoc = Propagate->GetLocation().LocalToLocation(vLocalGear); gearLoc = Propagate->GetLocation().LocalToLocation(vLocalGear);
// Compute the height of the theoretical location of the wheel (if strut is // Compute the height of the theoretical location of the wheel (if strut is
// not compressed) with respect to the ground level // not compressed) with respect to the ground level
double height = fdmex->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel); double height = fdmex->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel, angularVel);
vGroundNormal = Propagate->GetTec2b() * normal; vGroundNormal = Propagate->GetTec2b() * normal;
// The height returned above is the AGL and is expressed in the Z direction // The height returned above is the AGL and is expressed in the Z direction

View file

@ -47,7 +47,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_LGEAR "$Id: FGLGear.h,v 1.40 2010/07/30 11:50:01 jberndt Exp $" #define ID_LGEAR "$Id: FGLGear.h,v 1.41 2010/09/22 11:33:40 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -58,7 +58,6 @@ namespace JSBSim {
class FGAircraft; class FGAircraft;
class FGPropagate; class FGPropagate;
class FGFCS; class FGFCS;
class FGState;
class FGMassBalance; class FGMassBalance;
class FGAuxiliary; class FGAuxiliary;
class FGTable; class FGTable;
@ -181,7 +180,7 @@ CLASS DOCUMENTATION
</contact> </contact>
@endcode @endcode
@author Jon S. Berndt @author Jon S. Berndt
@version $Id: FGLGear.h,v 1.40 2010/07/30 11:50:01 jberndt Exp $ @version $Id: FGLGear.h,v 1.41 2010/09/22 11:33:40 jberndt Exp $
@see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at @see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
NASA-Ames", NASA CR-2497, January 1975 NASA-Ames", NASA CR-2497, January 1975
@see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics", @see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",

View file

@ -48,7 +48,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_MODEL "$Id: FGModel.h,v 1.15 2010/09/07 00:19:46 jberndt Exp $" #define ID_MODEL "$Id: FGModel.h,v 1.16 2010/09/22 11:33:40 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -57,7 +57,6 @@ FORWARD DECLARATIONS
namespace JSBSim { namespace JSBSim {
class FGFDMExec; class FGFDMExec;
class FGState;
class FGAtmosphere; class FGAtmosphere;
class FGFCS; class FGFCS;
class FGPropulsion; class FGPropulsion;
@ -119,7 +118,6 @@ protected:
virtual void Debug(int from); virtual void Debug(int from);
FGFDMExec* FDMExec; FGFDMExec* FDMExec;
FGState* State;
FGAtmosphere* Atmosphere; FGAtmosphere* Atmosphere;
FGFCS* FCS; FGFCS* FCS;
FGPropulsion* Propulsion; FGPropulsion* Propulsion;

View file

@ -61,9 +61,6 @@ INCLUDES
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
#include "input_output/net_fdm.hxx"
#include "input_output/FGfdmSocket.h"
#if defined(WIN32) && !defined(__CYGWIN__) #if defined(WIN32) && !defined(__CYGWIN__)
# include <windows.h> # include <windows.h>
#else #else
@ -77,7 +74,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGOutput.cpp,v 1.48 2010/04/12 12:25:19 jberndt Exp $"; static const char *IdSrc = "$Id: FGOutput.cpp,v 1.49 2010/10/15 11:30:29 jberndt Exp $";
static const char *IdHdr = ID_OUTPUT; static const char *IdHdr = ID_OUTPUT;
// (stolen from FGFS native_fdm.cxx) // (stolen from FGFS native_fdm.cxx)
@ -132,7 +129,6 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
Name = "FGOutput"; Name = "FGOutput";
sFirstPass = dFirstPass = true; sFirstPass = dFirstPass = true;
socket = 0; socket = 0;
flightGearSocket = 0;
runID_postfix = 0; runID_postfix = 0;
Type = otNone; Type = otNone;
SubSystems = 0; SubSystems = 0;
@ -153,7 +149,6 @@ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
FGOutput::~FGOutput() FGOutput::~FGOutput()
{ {
delete socket; delete socket;
delete flightGearSocket;
OutputProperties.clear(); OutputProperties.clear();
Debug(1); Debug(1);
} }
@ -231,6 +226,15 @@ void FGOutput::SetType(const string& type)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGOutput::SetProtocol(const string& protocol)
{
if (protocol == "UDP") Protocol = FGfdmSocket::ptUDP;
else if (protocol == "TCP") Protocol = FGfdmSocket::ptTCP;
else Protocol = FGfdmSocket::ptTCP; // Default to TCP
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGOutput::DelimitedOutput(const string& fname) void FGOutput::DelimitedOutput(const string& fname)
{ {
streambuf* buffer; streambuf* buffer;
@ -566,7 +570,6 @@ void FGOutput::SocketDataFill(FGNetFDM* net)
} }
} }
// Consumables // Consumables
net->num_tanks = Propulsion->GetNumTanks(); // Max number of fuel tanks net->num_tanks = Propulsion->GetNumTanks(); // Max number of fuel tanks
@ -574,7 +577,6 @@ void FGOutput::SocketDataFill(FGNetFDM* net)
net->fuel_quantity[i] = (float)(((FGTank *)Propulsion->GetTank(i))->GetContents()); net->fuel_quantity[i] = (float)(((FGTank *)Propulsion->GetTank(i))->GetContents());
} }
// Gear status // Gear status
net->num_wheels = GroundReactions->GetNumGearUnits(); net->num_wheels = GroundReactions->GetNumGearUnits();
@ -588,13 +590,11 @@ void FGOutput::SocketDataFill(FGNetFDM* net)
net->gear_compression[i] = (float)(GroundReactions->GetGearUnit(i)->GetCompLen()); net->gear_compression[i] = (float)(GroundReactions->GetGearUnit(i)->GetCompLen());
} }
// Environment // Environment
net->cur_time = (long int)1234567890; // Friday, Feb 13, 2009, 23:31:30 UTC (not processed by FGFS anyway) net->cur_time = (long int)1234567890; // Friday, Feb 13, 2009, 23:31:30 UTC (not processed by FGFS anyway)
net->warp = 0; // offset in seconds to unix time net->warp = 0; // offset in seconds to unix time
net->visibility = 25000.0; // visibility in meters (for env. effects) net->visibility = 25000.0; // visibility in meters (for env. effects)
// Control surface positions (normalized values) // Control surface positions (normalized values)
net->elevator = (float)(FCS->GetDePos(ofNorm)); // Norm Elevator Pos, -- net->elevator = (float)(FCS->GetDePos(ofNorm)); // Norm Elevator Pos, --
net->elevator_trim_tab = (float)(FCS->GetPitchTrimCmd()); // Norm Elev Trim Tab Pos, -- net->elevator_trim_tab = (float)(FCS->GetPitchTrimCmd()); // Norm Elev Trim Tab Pos, --
@ -607,7 +607,6 @@ void FGOutput::SocketDataFill(FGNetFDM* net)
net->speedbrake = (float)(FCS->GetDsbPos(ofNorm)); // Norm Speedbrake Pos, -- net->speedbrake = (float)(FCS->GetDsbPos(ofNorm)); // Norm Speedbrake Pos, --
net->spoilers = (float)(FCS->GetDspPos(ofNorm)); // Norm Spoiler Pos, -- net->spoilers = (float)(FCS->GetDspPos(ofNorm)); // Norm Spoiler Pos, --
// Convert the net buffer to network format // Convert the net buffer to network format
if ( isLittleEndian ) { if ( isLittleEndian ) {
net->version = htonl(net->version); net->version = htonl(net->version);
@ -691,12 +690,11 @@ void FGOutput::FlightGearSocketOutput(void)
{ {
int length = sizeof(fgSockBuf); int length = sizeof(fgSockBuf);
if (socket == NULL) return;
if (flightGearSocket == NULL) return; if (!socket->GetConnectStatus()) return;
if (!flightGearSocket->GetConnectStatus()) return;
SocketDataFill(&fgSockBuf); SocketDataFill(&fgSockBuf);
flightGearSocket->Send((char *)&fgSockBuf, length); socket->Send((char *)&fgSockBuf, length);
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -944,11 +942,9 @@ void FGOutput::SocketStatusOutput(const string& out_str)
bool FGOutput::Load(Element* element) bool FGOutput::Load(Element* element)
{ {
string type="", parameter=""; string parameter="";
string name=""; string name="";
string protocol="tcp";
int OutRate = 0; int OutRate = 0;
string property;
unsigned int port; unsigned int port;
Element *property_element; Element *property_element;
@ -967,19 +963,12 @@ bool FGOutput::Load(Element* element)
if (!document) return false; if (!document) return false;
name = FDMExec->GetRootDir() + document->GetAttributeValue("name"); name = FDMExec->GetRootDir() + document->GetAttributeValue("name");
type = document->GetAttributeValue("type"); SetType(document->GetAttributeValue("type"));
SetType(type); Port = document->GetAttributeValue("port");
if (!document->GetAttributeValue("port").empty() && type == string("SOCKET")) { if (!Port.empty() && (Type == otSocket || Type == otFlightGear)) {
port = atoi(document->GetAttributeValue("port").c_str()); port = atoi(Port.c_str());
socket = new FGfdmSocket(name, port); SetProtocol(document->GetAttributeValue("protocol"));
} else if (!document->GetAttributeValue("port").empty() && type == string("FLIGHTGEAR")) { socket = new FGfdmSocket(name, port, Protocol);
port = atoi(document->GetAttributeValue("port").c_str());
if (!document->GetAttributeValue("protocol").empty())
protocol = document->GetAttributeValue("protocol");
if (protocol == "udp")
flightGearSocket = new FGfdmSocket(name, port, FGfdmSocket::ptUDP); // create udp socket
else
flightGearSocket = new FGfdmSocket(name, port, FGfdmSocket::ptTCP); // create tcp socket (default)
} else { } else {
BaseFilename = Filename = name; BaseFilename = Filename = name;
} }

View file

@ -45,12 +45,13 @@ INCLUDES
#include "input_output/FGXMLFileRead.h" #include "input_output/FGXMLFileRead.h"
#include "input_output/net_fdm.hxx" #include "input_output/net_fdm.hxx"
#include "input_output/FGfdmSocket.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_OUTPUT "$Id: FGOutput.h,v 1.17 2009/10/24 22:59:30 jberndt Exp $" #define ID_OUTPUT "$Id: FGOutput.h,v 1.18 2010/10/15 11:30:29 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -123,7 +124,7 @@ CLASS DOCUMENTATION
propulsion ON|OFF propulsion ON|OFF
</pre> </pre>
NOTE that Time is always output with the data. NOTE that Time is always output with the data.
@version $Id: FGOutput.h,v 1.17 2009/10/24 22:59:30 jberndt Exp $ @version $Id: FGOutput.h,v 1.18 2010/10/15 11:30:29 jberndt Exp $
*/ */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -145,17 +146,19 @@ public:
void SocketStatusOutput(const std::string&); void SocketStatusOutput(const std::string&);
void SocketDataFill(FGNetFDM* net); void SocketDataFill(FGNetFDM* net);
void SetType(const std::string& type); void SetType(const std::string& type);
void SetProtocol(const std::string& protocol);
void SetPort(const std::string& port);
void SetStartNewFile(bool tt) {StartNewFile = tt;} void SetStartNewFile(bool tt) {StartNewFile = tt;}
void SetSubsystems(int tt) {SubSystems = tt;} void SetSubsystems(int tt) {SubSystems = tt;}
void Enable(void) { enabled = true; }
void Disable(void) { enabled = false; }
bool Toggle(void) {enabled = !enabled; return enabled;}
bool Load(Element* el);
void SetOutputFileName(const std::string& fname) {Filename = fname;} void SetOutputFileName(const std::string& fname) {Filename = fname;}
void SetDirectivesFile(const std::string& fname) {DirectivesFile = fname;} void SetDirectivesFile(const std::string& fname) {DirectivesFile = fname;}
void SetRate(int rt); void SetRate(int rt);
void Enable(void) { enabled = true; }
void Disable(void) { enabled = false; }
bool Toggle(void) {enabled = !enabled; return enabled;}
bool Load(Element* el);
string GetOutputFileName(void) const {return Filename;} string GetOutputFileName(void) const {return Filename;}
/// Subsystem types for specifying which will be output in the FDM data logging /// Subsystem types for specifying which will be output in the FDM data logging
@ -180,14 +183,15 @@ public:
private: private:
enum {otNone, otCSV, otTab, otSocket, otTerminal, otFlightGear, otUnknown} Type; enum {otNone, otCSV, otTab, otSocket, otTerminal, otFlightGear, otUnknown} Type;
FGfdmSocket::ProtocolType Protocol;
bool sFirstPass, dFirstPass, enabled; bool sFirstPass, dFirstPass, enabled;
int SubSystems; int SubSystems;
int runID_postfix; int runID_postfix;
bool StartNewFile; bool StartNewFile;
std::string output_file_name, delimeter, BaseFilename, Filename, DirectivesFile; std::string output_file_name, delimeter, BaseFilename, Filename, DirectivesFile;
std::string Port;
std::ofstream datafile; std::ofstream datafile;
FGfdmSocket* socket; FGfdmSocket* socket;
FGfdmSocket* flightGearSocket;
std::vector <FGPropertyManager*> OutputProperties; std::vector <FGPropertyManager*> OutputProperties;
void Debug(int from); void Debug(int from);

View file

@ -71,7 +71,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.65 2010/09/18 22:48:12 jberndt Exp $"; static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.71 2010/10/15 11:34:09 jberndt Exp $";
static const char *IdHdr = ID_PROPAGATE; static const char *IdHdr = ID_PROPAGATE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -82,7 +82,7 @@ FGPropagate::FGPropagate(FGFDMExec* fdmex) : FGModel(fdmex)
{ {
Debug(0); Debug(0);
Name = "FGPropagate"; Name = "FGPropagate";
gravType = gtStandard; gravType = gtWGS84;
vPQRdot.InitMatrix(); vPQRdot.InitMatrix();
vQtrndot = FGQuaternion(0,0,0); vQtrndot = FGQuaternion(0,0,0);
@ -95,6 +95,7 @@ FGPropagate::FGPropagate(FGFDMExec* fdmex) : FGModel(fdmex)
integrator_translational_position = eTrapezoidal; integrator_translational_position = eTrapezoidal;
VState.dqPQRdot.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqPQRdot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqQtrndot.resize(4, FGQuaternion(0.0,0.0,0.0)); VState.dqQtrndot.resize(4, FGQuaternion(0.0,0.0,0.0));
@ -129,6 +130,7 @@ bool FGPropagate::InitModel(void)
vInertialVelocity.InitMatrix(); vInertialVelocity.InitMatrix();
VState.dqPQRdot.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqPQRdot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqPQRidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqUVWidot.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0));
VState.dqQtrndot.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqQtrndot.resize(4, FGColumnVector3(0.0,0.0,0.0));
@ -204,6 +206,7 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
FGIC->GetRRadpsIC() ) + Tl2b*vOmegaLocal; FGIC->GetRRadpsIC() ) + Tl2b*vOmegaLocal;
VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth; VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth;
VState.vPQRi_i = Tb2i * VState.vPQRi;
// Make an initial run and set past values // Make an initial run and set past values
InitializeDerivatives(); InitializeDerivatives();
@ -246,10 +249,11 @@ bool FGPropagate::Run(void)
CalculateUVW(); // Translational position derivative (velocities are integrated in the inertial frame) CalculateUVW(); // Translational position derivative (velocities are integrated in the inertial frame)
// Propagate rotational / translational velocity, angular /translational position, respectively. // Propagate rotational / translational velocity, angular /translational position, respectively.
Integrate(VState.vPQRi, vPQRdot, VState.dqPQRdot, dt, integrator_rotational_rate);
Integrate(VState.vInertialVelocity, vUVWidot, VState.dqUVWidot, dt, integrator_translational_rate); Integrate(VState.vPQRi_i, vPQRidot, VState.dqPQRidot, dt, integrator_rotational_rate); // ECI integration
Integrate(VState.qAttitudeECI, vQtrndot, VState.dqQtrndot, dt, integrator_rotational_position); Integrate(VState.qAttitudeECI, vQtrndot, VState.dqQtrndot, dt, integrator_rotational_position);
Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position); Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position);
Integrate(VState.vInertialVelocity, vUVWidot, VState.dqUVWidot, dt, integrator_translational_rate);
// CAUTION : the order of the operations below is very important to get transformation // CAUTION : the order of the operations below is very important to get transformation
// matrices that are consistent with the new state of the vehicle // matrices that are consistent with the new state of the vehicle
@ -280,6 +284,7 @@ bool FGPropagate::Run(void)
VehicleRadius = GetRadius(); // Calculate current aircraft radius from center of planet VehicleRadius = GetRadius(); // Calculate current aircraft radius from center of planet
VState.vPQRi = Ti2b * VState.vPQRi_i;
VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth; VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
VState.qAttitudeLocal = Tl2b.GetQuaternion(); VState.qAttitudeLocal = Tl2b.GetQuaternion();
@ -318,6 +323,7 @@ void FGPropagate::CalculatePQRdot(void)
// frame. // frame.
vPQRdot = Jinv*(vMoments - VState.vPQRi*(J*VState.vPQRi)); vPQRdot = Jinv*(vMoments - VState.vPQRi*(J*VState.vPQRi));
vPQRidot = Tb2i * vPQRdot;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -502,7 +508,7 @@ void FGPropagate::ResolveFrictionForces(double dt)
// Instruct the algorithm to zero out the relative movement between the // Instruct the algorithm to zero out the relative movement between the
// aircraft and the ground. // aircraft and the ground.
vdot += (VState.vUVW - Tec2b * LocalTerrainVelocity) / dt; vdot += (VState.vUVW - Tec2b * LocalTerrainVelocity) / dt;
wdot += VState.vPQR / dt; wdot += (VState.vPQR - Tec2b * LocalTerrainAngularVelocity) / dt;
} }
// Assemble the linear system of equations // Assemble the linear system of equations
@ -557,6 +563,7 @@ void FGPropagate::ResolveFrictionForces(double dt)
vUVWdot += invMass * Fc; vUVWdot += invMass * Fc;
vUVWidot += invMass * Tb2i * Fc; vUVWidot += invMass * Tb2i * Fc;
vPQRdot += Jinv * Mc; vPQRdot += Jinv * Mc;
vPQRidot += Tb2i* Jinv * Mc;
// Save the value of the Lagrange multipliers to accelerate the convergence // Save the value of the Lagrange multipliers to accelerate the convergence
// of the Gauss-Seidel algorithm at next iteration. // of the Gauss-Seidel algorithm at next iteration.
@ -609,7 +616,8 @@ void FGPropagate::SetInertialVelocity(FGColumnVector3 Vi) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::SetInertialRates(FGColumnVector3 vRates) { void FGPropagate::SetInertialRates(FGColumnVector3 vRates) {
VState.vPQRi = Ti2b * vRates; VState.vPQRi_i = vRates;
VState.vPQRi = Ti2b * VState.vPQRi_i;
VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth; VState.vPQR = VState.vPQRi - Ti2b * vOmegaEarth;
} }
@ -626,11 +634,13 @@ void FGPropagate::InitializeDerivatives(void)
// Initialize past values deques // Initialize past values deques
VState.dqPQRdot.clear(); VState.dqPQRdot.clear();
VState.dqPQRidot.clear();
VState.dqUVWidot.clear(); VState.dqUVWidot.clear();
VState.dqInertialVelocity.clear(); VState.dqInertialVelocity.clear();
VState.dqQtrndot.clear(); VState.dqQtrndot.clear();
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
VState.dqPQRdot.push_front(vPQRdot); VState.dqPQRdot.push_front(vPQRdot);
VState.dqPQRidot.push_front(vPQRidot);
VState.dqUVWidot.push_front(vUVWdot); VState.dqUVWidot.push_front(vUVWdot);
VState.dqInertialVelocity.push_front(VState.vInertialVelocity); VState.dqInertialVelocity.push_front(VState.vInertialVelocity);
VState.dqQtrndot.push_front(vQtrndot); VState.dqQtrndot.push_front(vQtrndot);
@ -647,7 +657,7 @@ void FGPropagate::RecomputeLocalTerrainRadius(void)
// Get the LocalTerrain radius. // Get the LocalTerrain radius.
FDMExec->GetGroundCallback()->GetAGLevel(t, VState.vLocation, contactloc, dv, FDMExec->GetGroundCallback()->GetAGLevel(t, VState.vLocation, contactloc, dv,
LocalTerrainVelocity); LocalTerrainVelocity, LocalTerrainAngularVelocity);
LocalTerrainRadius = contactloc.GetRadius(); LocalTerrainRadius = contactloc.GetRadius();
} }
@ -712,6 +722,41 @@ void FGPropagate::SetDistanceAGL(double tt)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::DumpState(void)
{
cout << endl;
cout << fgblue
<< "------------------------------------------------------------------" << reset << endl;
cout << highint
<< "State Report at sim time: " << FDMExec->GetSimTime() << " seconds" << reset << endl;
cout << " " << underon
<< "Position" << underoff << endl;
cout << " ECI: " << VState.vInertialPosition.Dump(", ") << " (x,y,z, in ft)" << endl;
cout << " ECEF: " << VState.vLocation << " (x,y,z, in ft)" << endl;
cout << " Local: " << VState.vLocation.GetLatitudeDeg()
<< ", " << VState.vLocation.GetLongitudeDeg()
<< ", " << GetAltitudeASL() << " (lat, lon, alt in deg and ft)" << endl;
cout << endl << " " << underon
<< "Orientation" << underoff << endl;
cout << " ECI: " << VState.qAttitudeECI.GetEulerDeg().Dump(", ") << " (phi, theta, psi in deg)" << endl;
cout << " Local: " << VState.qAttitudeLocal.GetEulerDeg().Dump(", ") << " (phi, theta, psi in deg)" << endl;
cout << endl << " " << underon
<< "Velocity" << underoff << endl;
cout << " ECI: " << VState.vInertialVelocity.Dump(", ") << " (x,y,z in ft/s)" << endl;
cout << " ECEF: " << (GetTb2ec() * VState.vUVW).Dump(", ") << " (x,y,z in ft/s)" << endl;
cout << " Local: " << GetVel() << " (n,e,d in ft/sec)" << endl;
cout << " Body: " << GetUVW() << " (u,v,w in ft/sec)" << endl;
cout << endl << " " << underon
<< "Body Rates (relative to given frame, expressed in body frame)" << underoff << endl;
cout << " ECI: " << (VState.vPQRi*radtodeg).Dump(", ") << " (p,q,r in deg/s)" << endl;
cout << " ECEF: " << (VState.vPQR*radtodeg).Dump(", ") << " (p,q,r in deg/s)" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::bind(void) void FGPropagate::bind(void)
{ {
typedef double (FGPropagate::*PMF)(int) const; typedef double (FGPropagate::*PMF)(int) const;

View file

@ -49,7 +49,7 @@ INCLUDES
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.48 2010/09/18 22:48:12 jberndt Exp $" #define ID_PROPAGATE "$Id: FGPropagate.h,v 1.51 2010/10/07 03:45:40 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
@ -102,7 +102,7 @@ CLASS DOCUMENTATION
@endcode @endcode
@author Jon S. Berndt, Mathias Froehlich @author Jon S. Berndt, Mathias Froehlich
@version $Id: FGPropagate.h,v 1.48 2010/09/18 22:48:12 jberndt Exp $ @version $Id: FGPropagate.h,v 1.51 2010/10/07 03:45:40 jberndt Exp $
*/ */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -135,6 +135,11 @@ public:
units rad/sec */ units rad/sec */
FGColumnVector3 vPQRi; FGColumnVector3 vPQRi;
/** The angular velocity vector for the vehicle body frame relative to the
ECI frame, expressed in the ECI frame.
units rad/sec */
FGColumnVector3 vPQRi_i;
/** The current orientation of the vehicle, that is, the orientation of the /** The current orientation of the vehicle, that is, the orientation of the
body frame relative to the local, NED frame. */ body frame relative to the local, NED frame. */
FGQuaternion qAttitudeLocal; FGQuaternion qAttitudeLocal;
@ -148,6 +153,7 @@ public:
FGColumnVector3 vInertialPosition; FGColumnVector3 vInertialPosition;
deque <FGColumnVector3> dqPQRdot; deque <FGColumnVector3> dqPQRdot;
deque <FGColumnVector3> dqPQRidot;
deque <FGColumnVector3> dqUVWidot; deque <FGColumnVector3> dqUVWidot;
deque <FGColumnVector3> dqInertialVelocity; deque <FGColumnVector3> dqInertialVelocity;
deque <FGQuaternion> dqQtrndot; deque <FGQuaternion> dqQtrndot;
@ -566,16 +572,6 @@ public:
VState.vInertialPosition = GetTec2i() * VState.vLocation; VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices(); UpdateLocationMatrices();
} }
void SetLocation(const FGLocation& l) {
VState.vLocation = l;
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
}
void SetLocation(const FGColumnVector3& l) {
VState.vLocation = l;
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
}
void SetAltitudeASL(double altASL); void SetAltitudeASL(double altASL);
void SetAltitudeASLmeters(double altASL) {SetAltitudeASL(altASL/fttom);} void SetAltitudeASLmeters(double altASL) {SetAltitudeASL(altASL/fttom);}
void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; } void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; }
@ -588,6 +584,16 @@ public:
VehicleRadius = GetRadius(); VehicleRadius = GetRadius();
UpdateLocationMatrices(); UpdateLocationMatrices();
} }
void SetLocation(const FGLocation& l) {
VState.vLocation = l;
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
}
void SetLocation(const FGColumnVector3& l) {
VState.vLocation = l;
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
}
void RecomputeLocalTerrainRadius(void); void RecomputeLocalTerrainRadius(void);
@ -604,6 +610,8 @@ public:
double value; double value;
}; };
void DumpState(void);
private: private:
// state vector // state vector
@ -612,6 +620,7 @@ private:
FGColumnVector3 vVel; FGColumnVector3 vVel;
FGColumnVector3 vPQRdot; FGColumnVector3 vPQRdot;
FGColumnVector3 vPQRidot;
FGColumnVector3 vUVWdot, vUVWidot; FGColumnVector3 vUVWdot, vUVWidot;
FGColumnVector3 vInertialVelocity; FGColumnVector3 vInertialVelocity;
FGColumnVector3 vLocation; FGColumnVector3 vLocation;
@ -633,7 +642,7 @@ private:
FGMatrix33 Tl2i; FGMatrix33 Tl2i;
double LocalTerrainRadius, SeaLevelRadius, VehicleRadius; double LocalTerrainRadius, SeaLevelRadius, VehicleRadius;
FGColumnVector3 LocalTerrainVelocity; FGColumnVector3 LocalTerrainVelocity, LocalTerrainAngularVelocity;
eIntegrateType integrator_rotational_rate; eIntegrateType integrator_rotational_rate;
eIntegrateType integrator_translational_rate; eIntegrateType integrator_translational_rate;
eIntegrateType integrator_rotational_position; eIntegrateType integrator_rotational_position;

View file

@ -65,7 +65,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.40 2010/09/07 00:40:03 jberndt Exp $"; static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.41 2010/10/15 11:32:41 jberndt Exp $";
static const char *IdHdr = ID_PROPULSION; static const char *IdHdr = ID_PROPULSION;
extern short debug_lvl; extern short debug_lvl;
@ -295,29 +295,34 @@ bool FGPropulsion::Load(Element* el)
document->SetParent(engine_element); document->SetParent(engine_element);
type = document->GetName(); type = document->GetName();
if (type == "piston_engine") { try {
HavePistonEngine = true; if (type == "piston_engine") {
if (!IsBound) bind(); HavePistonEngine = true;
Engines.push_back(new FGPiston(FDMExec, document, numEngines)); if (!IsBound) bind();
} else if (type == "turbine_engine") { Engines.push_back(new FGPiston(FDMExec, document, numEngines));
HaveTurbineEngine = true; } else if (type == "turbine_engine") {
if (!IsBound) bind(); HaveTurbineEngine = true;
Engines.push_back(new FGTurbine(FDMExec, document, numEngines)); if (!IsBound) bind();
} else if (type == "turboprop_engine") { Engines.push_back(new FGTurbine(FDMExec, document, numEngines));
HaveTurboPropEngine = true; } else if (type == "turboprop_engine") {
if (!IsBound) bind(); HaveTurboPropEngine = true;
Engines.push_back(new FGTurboProp(FDMExec, document, numEngines)); if (!IsBound) bind();
} else if (type == "rocket_engine") { Engines.push_back(new FGTurboProp(FDMExec, document, numEngines));
HaveRocketEngine = true; } else if (type == "rocket_engine") {
if (!IsBound) bind(); HaveRocketEngine = true;
Engines.push_back(new FGRocket(FDMExec, document, numEngines)); if (!IsBound) bind();
} else if (type == "electric_engine") { Engines.push_back(new FGRocket(FDMExec, document, numEngines));
HaveElectricEngine = true; } else if (type == "electric_engine") {
if (!IsBound) bind(); HaveElectricEngine = true;
Engines.push_back(new FGElectric(FDMExec, document, numEngines)); if (!IsBound) bind();
} else { Engines.push_back(new FGElectric(FDMExec, document, numEngines));
cerr << "Unknown engine type: " << type << endl; } else {
exit(-5); cerr << "Unknown engine type: " << type << endl;
exit(-5);
}
} catch (std::string str) {
cerr << endl << fgred << str << reset << endl;
return false;
} }
FCS->AddThrottle(); FCS->AddThrottle();

View file

@ -54,7 +54,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGEngine.cpp,v 1.39 2010/08/21 17:13:48 jberndt Exp $"; static const char *IdSrc = "$Id: FGEngine.cpp,v 1.40 2010/10/15 11:32:41 jberndt Exp $";
static const char *IdHdr = ID_ENGINE; static const char *IdHdr = ID_ENGINE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -109,7 +109,11 @@ FGEngine::FGEngine(FGFDMExec* exec, Element* engine_element, int engine_number)
// Load thruster // Load thruster
local_element = engine_element->GetParent()->FindElement("thruster"); local_element = engine_element->GetParent()->FindElement("thruster");
if (local_element) { if (local_element) {
if (!LoadThruster(local_element)) exit(-1); try {
if (!LoadThruster(local_element)) exit(-1);
} catch (std::string str) {
throw("Error loading engine " + Name + ". " + str);
}
} else { } else {
cerr << "No thruster definition supplied with engine definition." << endl; cerr << "No thruster definition supplied with engine definition." << endl;
} }

View file

@ -48,7 +48,7 @@ using namespace std;
namespace JSBSim { namespace JSBSim {
static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.30 2010/05/02 15:10:07 jberndt Exp $"; static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.32 2010/10/21 03:27:40 jberndt Exp $";
static const char *IdHdr = ID_PROPELLER; static const char *IdHdr = ID_PROPELLER;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -105,16 +105,20 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num)
for (int i=0; i<2; i++) { for (int i=0; i<2; i++) {
table_element = prop_element->FindNextElement("table"); table_element = prop_element->FindNextElement("table");
name = table_element->GetAttributeValue("name"); name = table_element->GetAttributeValue("name");
if (name == "C_THRUST") { try {
cThrust = new FGTable(PropertyManager, table_element); if (name == "C_THRUST") {
} else if (name == "C_POWER") { cThrust = new FGTable(PropertyManager, table_element);
cPower = new FGTable(PropertyManager, table_element); } else if (name == "C_POWER") {
} else if (name == "CT_MACH") { cPower = new FGTable(PropertyManager, table_element);
CtMach = new FGTable(PropertyManager, table_element); } else if (name == "CT_MACH") {
} else if (name == "CP_MACH") { CtMach = new FGTable(PropertyManager, table_element);
CpMach = new FGTable(PropertyManager, table_element); } else if (name == "CP_MACH") {
} else { CpMach = new FGTable(PropertyManager, table_element);
cerr << "Unknown table type: " << name << " in propeller definition." << endl; } else {
cerr << "Unknown table type: " << name << " in propeller definition." << endl;
}
} catch (std::string str) {
throw("Error loading propeller table:" + name + ". " + str);
} }
} }
@ -334,7 +338,7 @@ double FGPropeller::GetPowerRequired(void)
if (CL > 1.5) CL = 1.5; if (CL > 1.5) CL = 1.5;
double BladeArea = Diameter * Diameter / 32.0 * numBlades; double BladeArea = Diameter * Diameter / 32.0 * numBlades;
vTorque(eX) = -Sense*BladeArea*Diameter*Vel*Vel*rho*0.19*CL; vTorque(eX) = -Sense*BladeArea*Diameter*Vel*Vel*rho*0.19*CL;
PowerRequired = vTorque(eX)*0.2*M_PI; PowerRequired = fabs(vTorque(eX))*0.2*M_PI;
} }
return PowerRequired; return PowerRequired;