1
0
Fork 0

Sync. with JSBSim CVS

This commit is contained in:
Erik Hofman 2011-01-23 15:14:01 +01:00
parent 58550d9e70
commit 4a817a6307
20 changed files with 1800 additions and 2207 deletions

View file

@ -71,7 +71,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.83 2010/11/07 13:30:54 jberndt Exp $";
static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.84 2011/01/16 16:26:14 bcoconni Exp $";
static const char *IdHdr = ID_FDMEXEC;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -700,7 +700,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
FCS->LateBind();
} catch (string prop) {
cerr << endl << fgred << " Could not late bind property " << prop
<< ". Aborting." << endl;
<< ". Aborting." << reset << endl;
result = false;
}

View file

@ -143,8 +143,6 @@ FGJSBsim::FGJSBsim( double dt )
break;
}
}
resetPropertyState();
fdmex = new FGFDMExec( (FGPropertyManager*)globals->get_props() );
@ -1413,22 +1411,3 @@ void FGJSBsim::update_external_forces(double t_off)
fgSetDouble("/fdm/jsbsim/systems/hook/tailhook-pos-deg", fi);
}
void FGJSBsim::resetPropertyState()
{
// this code works-around bug #222:
// http://code.google.com/p/flightgear-bugs/issues/detail?id=222
// for whatever reason, having an existing value for the WOW
// property causes the NaNs. Should that be fixed, this code can die
SGPropertyNode* gear = fgGetNode("/fdm/jsbsim/gear", false);
if (!gear) {
return;
}
int index = 0;
SGPropertyNode* unitNode = NULL;
for (; (unitNode = gear->getChild("unit", index)) != NULL; ++index) {
unitNode->removeChild("WOW", 0, false);
}
}

View file

@ -284,7 +284,6 @@ private:
void update_external_forces(double t_off);
void resetPropertyState();
};

File diff suppressed because it is too large Load diff

View file

@ -47,16 +47,14 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFDMExec.h"
#include "FGJSBBase.h"
#include "math/FGColumnVector3.h"
#include "input_output/FGXMLFileRead.h"
#include "math/FGLocation.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.22 2010/11/20 16:38:43 bcoconni Exp $"
#define ID_INITIALCONDITION "$Id: FGInitialCondition.h,v 1.26 2011/01/16 16:10:59 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -64,8 +62,11 @@ FORWARD DECLARATIONS
namespace JSBSim {
class FGFDMExec;
class FGMatrix33;
class FGColumnVector3;
typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
typedef enum { setwned, setwmd, setwhc } windset;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
@ -83,17 +84,27 @@ CLASS DOCUMENTATION
With a valid object of FGFDMExec and an aircraft model loaded:
@code
FGInitialCondition fgic=new FGInitialCondition(FDMExec);
fgic->SetVcalibratedKtsIC()
fgic->SetAltitudeAGLFtIC();
FGInitialCondition* fgic = FDMExec->GetIC();
// Reset the initial conditions and set VCAS and altitude
fgic->InitializeIC();
fgic->SetVcalibratedKtsIC(vcas);
fgic->SetAltitudeAGLFtIC(altitude);
// directly into Run
FDMExec->GetState()->Initialize(fgic)
FDMExec->GetPropagate()->SetInitialState(fgic);
delete fgic;
FDMExec->Run()
FDMExec->Run();
//or to loop the sim w/o integrating
FDMExec->RunIC(fgic)
FDMExec->RunIC();
@endcode
Alternatively, you can load initial conditions from an XML file:
@code
FGInitialCondition* fgic = FDMExec->GetIC();
fgic->Load(IC_file);
@endcode
<h3>Speed</h3>
@ -202,7 +213,7 @@ CLASS DOCUMENTATION
@property ic/r-rad_sec (read/write) Yaw rate initial condition in radians/second
@author Tony Peden
@version "$Id: FGInitialCondition.h,v 1.22 2010/11/20 16:38:43 bcoconni Exp $"
@version "$Id: FGInitialCondition.h,v 1.26 2011/01/16 16:10:59 bcoconni Exp $"
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -227,11 +238,11 @@ public:
/** Set true airspeed initial condition in knots.
@param vt True airspeed in knots */
inline void SetVtrueKtsIC(double vt) { SetVtrueFpsIC(vt*ktstofps); }
void SetVtrueKtsIC(double vtrue) { SetVtrueFpsIC(vtrue*ktstofps); }
/** Set ground speed initial condition in knots.
@param vg Ground speed in knots */
inline void SetVgroundKtsIC(double vg) { SetVgroundFpsIC(vg*ktstofps); }
void SetVgroundKtsIC(double vg) { SetVgroundFpsIC(vg*ktstofps); }
/** Set mach initial condition.
@param mach Mach number */
@ -239,15 +250,15 @@ public:
/** Sets angle of attack initial condition in degrees.
@param a Alpha in degrees */
inline void SetAlphaDegIC(double a) { SetAlphaRadIC(a*degtorad); }
void SetAlphaDegIC(double a) { SetAlphaRadIC(a*degtorad); }
/** Sets angle of sideslip initial condition in degrees.
@param B Beta in degrees */
inline void SetBetaDegIC(double B) { SetBetaRadIC(B*degtorad);}
void SetBetaDegIC(double b) { SetBetaRadIC(b*degtorad);}
/** Sets pitch angle initial condition in degrees.
@param theta Theta (pitch) angle in degrees */
inline void SetThetaDegIC(double theta) { SetThetaRadIC(theta*degtorad); }
void SetThetaDegIC(double theta) { SetThetaRadIC(theta*degtorad); }
/** Resets the IC data structure to new values
@param u, v, w, ... **/
@ -258,19 +269,20 @@ public:
/** Sets the roll angle initial condition in degrees.
@param phi roll angle in degrees */
inline void SetPhiDegIC(double phi) { SetPhiRadIC(phi*degtorad);}
void SetPhiDegIC(double phi) { SetPhiRadIC(phi*degtorad);}
/** Sets the heading angle initial condition in degrees.
@param psi Heading angle in degrees */
inline void SetPsiDegIC(double psi){ SetPsiRadIC(psi*degtorad); }
void SetPsiDegIC(double psi){ SetPsiRadIC(psi*degtorad); }
/** Sets the climb rate initial condition in feet/minute.
@param roc Rate of Climb in feet/minute */
void SetClimbRateFpmIC(double roc);
void SetClimbRateFpmIC(double roc) { SetClimbRateFpsIC(roc/60.0); }
/** Sets the flight path angle initial condition in degrees.
@param gamma Flight path angle in degrees */
inline void SetFlightPathAngleDegIC(double gamma) { SetFlightPathAngleRadIC(gamma*degtorad); }
void SetFlightPathAngleDegIC(double gamma)
{ SetClimbRateFpsIC(vt*sin(gamma*degtorad)); }
/** Sets the altitude above sea level initial condition in feet.
@param altitudeASL Altitude above sea level in feet */
@ -278,95 +290,98 @@ public:
/** Sets the initial Altitude above ground level.
@param agl Altitude above ground level in feet */
void SetAltitudeAGLFtIC(double agl);
void SetAltitudeAGLFtIC(double agl)
{ SetAltitudeASLFtIC(terrain_elevation + agl); }
/** Sets the initial sea level radius from planet center
@param sl_rad sea level radius in feet */
void SetSeaLevelRadiusFtIC(double sl_rad);
void SetSeaLevelRadiusFtIC(double sl_rad) { sea_level_radius = sl_rad; }
/** Sets the initial terrain elevation.
@param elev Initial terrain elevation in feet */
void SetTerrainElevationFtIC(double elev);
void SetTerrainElevationFtIC(double elev) { terrain_elevation = elev; }
/** Sets the initial latitude.
@param lat Initial latitude in degrees */
inline void SetLatitudeDegIC(double lat) { latitude=lat*degtorad; }
void SetLatitudeDegIC(double lat) { position.SetLatitude(lat*degtorad); }
/** Sets the initial longitude.
@param lon Initial longitude in degrees */
inline void SetLongitudeDegIC(double lon) { longitude=lon*degtorad; }
void SetLongitudeDegIC(double lon) { position.SetLongitude(lon*degtorad); }
/** Gets the initial calibrated airspeed.
@return Initial calibrated airspeed in knots */
inline double GetVcalibratedKtsIC(void) const { return vc*fpstokts; }
double GetVcalibratedKtsIC(void) const;
/** Gets the initial equivalent airspeed.
@return Initial equivalent airspeed in knots */
inline double GetVequivalentKtsIC(void) const { return ve*fpstokts; }
double GetVequivalentKtsIC(void) const;
/** Gets the initial ground speed.
@return Initial ground speed in knots */
inline double GetVgroundKtsIC(void) const { return vg*fpstokts; }
double GetVgroundKtsIC(void) const { return GetVgroundFpsIC() * fpstokts; }
/** Gets the initial true velocity.
@return Initial true airspeed in knots. */
inline double GetVtrueKtsIC(void) const { return vt*fpstokts; }
double GetVtrueKtsIC(void) const { return vt*fpstokts; }
/** Gets the initial mach.
@return Initial mach number */
inline double GetMachIC(void) const { return mach; }
double GetMachIC(void) const;
/** Gets the initial climb rate.
@return Initial climb rate in feet/minute */
inline double GetClimbRateFpmIC(void) const { return hdot*60; }
double GetClimbRateFpmIC(void) const
{ return GetClimbRateFpsIC()*60; }
/** Gets the initial flight path angle.
@return Initial flight path angle in degrees */
inline double GetFlightPathAngleDegIC(void)const { return gamma*radtodeg; }
double GetFlightPathAngleDegIC(void) const
{ return GetFlightPathAngleRadIC()*radtodeg; }
/** Gets the initial angle of attack.
@return Initial alpha in degrees */
inline double GetAlphaDegIC(void) const { return alpha*radtodeg; }
double GetAlphaDegIC(void) const { return alpha*radtodeg; }
/** Gets the initial sideslip angle.
@return Initial beta in degrees */
inline double GetBetaDegIC(void) const { return beta*radtodeg; }
double GetBetaDegIC(void) const { return beta*radtodeg; }
/** Gets the initial pitch angle.
@return Initial pitch angle in degrees */
inline double GetThetaDegIC(void) const { return theta*radtodeg; }
double GetThetaDegIC(void) const { return theta*radtodeg; }
/** Gets the initial roll angle.
@return Initial phi in degrees */
inline double GetPhiDegIC(void) const { return phi*radtodeg; }
double GetPhiDegIC(void) const { return phi*radtodeg; }
/** Gets the initial heading angle.
@return Initial psi in degrees */
inline double GetPsiDegIC(void) const { return psi*radtodeg; }
double GetPsiDegIC(void) const { return psi*radtodeg; }
/** Gets the initial latitude.
@return Initial geocentric latitude in degrees */
inline double GetLatitudeDegIC(void) const { return latitude*radtodeg; }
double GetLatitudeDegIC(void) const { return position.GetLatitudeDeg(); }
/** Gets the initial longitude.
@return Initial longitude in degrees */
inline double GetLongitudeDegIC(void) const { return longitude*radtodeg; }
double GetLongitudeDegIC(void) const { return position.GetLongitudeDeg(); }
/** Gets the initial altitude above sea level.
@return Initial altitude in feet. */
inline double GetAltitudeASLFtIC(void) const { return altitudeASL; }
double GetAltitudeASLFtIC(void) const { return position.GetRadius() - sea_level_radius; }
/** Gets the initial altitude above ground level.
@return Initial altitude AGL in feet */
inline double GetAltitudeAGLFtIC(void) const { return altitudeASL - terrain_elevation; }
double GetAltitudeAGLFtIC(void) const { return position.GetRadius() - sea_level_radius - terrain_elevation; }
/** Gets the initial sea level radius.
@return Initial sea level radius */
inline double GetSeaLevelRadiusFtIC(void) const { return sea_level_radius; }
double GetSeaLevelRadiusFtIC(void) const { return sea_level_radius; }
/** Gets the initial terrain elevation.
@return Initial terrain elevation in feet */
inline double GetTerrainElevationFtIC(void) const { return terrain_elevation; }
double GetTerrainElevationFtIC(void) const { return terrain_elevation; }
/** Sets the initial ground speed.
@param vg Initial ground speed in feet/second */
@ -378,27 +393,27 @@ public:
/** Sets the initial body axis X velocity.
@param ubody Initial X velocity in feet/second */
void SetUBodyFpsIC(double ubody);
void SetUBodyFpsIC(double ubody) { SetBodyVelFpsIC(eU, ubody); }
/** Sets the initial body axis Y velocity.
@param vbody Initial Y velocity in feet/second */
void SetVBodyFpsIC(double vbody);
void SetVBodyFpsIC(double vbody) { SetBodyVelFpsIC(eV, vbody); }
/** Sets the initial body axis Z velocity.
@param wbody Initial Z velocity in feet/second */
void SetWBodyFpsIC(double wbody);
void SetWBodyFpsIC(double wbody) { SetBodyVelFpsIC(eW, wbody); }
/** Sets the initial local axis north velocity.
@param vn Initial north velocity in feet/second */
void SetVNorthFpsIC(double vn);
void SetVNorthFpsIC(double vn) { SetNEDVelFpsIC(eU, vn); }
/** Sets the initial local axis east velocity.
@param ve Initial east velocity in feet/second */
void SetVEastFpsIC(double ve);
void SetVEastFpsIC(double ve) { SetNEDVelFpsIC(eV, ve); }
/** Sets the initial local axis down velocity.
@param vd Initial down velocity in feet/second */
void SetVDownFpsIC(double vd);
void SetVDownFpsIC(double vd) { SetNEDVelFpsIC(eW, vd); }
/** Sets the initial roll rate.
@param P Initial roll rate in radians/second */
@ -444,39 +459,39 @@ public:
/** Gets the initial ground velocity.
@return Initial ground velocity in feet/second */
inline double GetVgroundFpsIC(void) const { return vg; }
double GetVgroundFpsIC(void) const { return vUVW_NED.Magnitude(eU, eV); }
/** Gets the initial true velocity.
@return Initial true velocity in feet/second */
inline double GetVtrueFpsIC(void) const { return vt; }
double GetVtrueFpsIC(void) const { return vt; }
/** Gets the initial body axis X wind velocity.
@return Initial body axis X wind velocity in feet/second */
inline double GetWindUFpsIC(void) const { return uw; }
double GetWindUFpsIC(void) const { return GetBodyWindFpsIC(eU); }
/** Gets the initial body axis Y wind velocity.
@return Initial body axis Y wind velocity in feet/second */
inline double GetWindVFpsIC(void) const { return vw; }
double GetWindVFpsIC(void) const { return GetBodyWindFpsIC(eV); }
/** Gets the initial body axis Z wind velocity.
@return Initial body axis Z wind velocity in feet/second */
inline double GetWindWFpsIC(void) const { return ww; }
double GetWindWFpsIC(void) const { return GetBodyWindFpsIC(eW); }
/** Gets the initial wind velocity in local frame.
@return Initial wind velocity toward north in feet/second */
inline double GetWindNFpsIC(void) const { return wnorth; }
double GetWindNFpsIC(void) const { return GetNEDWindFpsIC(eX); }
/** Gets the initial wind velocity in local frame.
@return Initial wind velocity eastwards in feet/second */
inline double GetWindEFpsIC(void) const { return weast; }
double GetWindEFpsIC(void) const { return GetNEDWindFpsIC(eY); }
/** Gets the initial wind velocity in local frame.
@return Initial wind velocity downwards in feet/second */
inline double GetWindDFpsIC(void) const { return wdown; }
double GetWindDFpsIC(void) const { return GetNEDWindFpsIC(eZ); }
/** Gets the initial total wind velocity in feet/sec.
@return Initial wind velocity in feet/second */
inline double GetWindFpsIC(void) const { return sqrt(wnorth*wnorth + weast*weast); }
double GetWindFpsIC(void) const;
/** Gets the initial wind direction.
@return Initial wind direction in feet/second */
@ -484,31 +499,35 @@ public:
/** Gets the initial climb rate.
@return Initial rate of climb in feet/second */
inline double GetClimbRateFpsIC(void) const { return hdot; }
double GetClimbRateFpsIC(void) const
{
FGColumnVector3 _vt_NED = Tb2l * Tw2b * FGColumnVector3(vt, 0., 0.);
return _vt_NED(eW);
}
/** Gets the initial body axis X velocity.
@return Initial body axis X velocity in feet/second. */
double GetUBodyFpsIC(void) const;
double GetUBodyFpsIC(void) const { return GetBodyVelFpsIC(eU); }
/** Gets the initial body axis Y velocity.
@return Initial body axis Y velocity in feet/second. */
double GetVBodyFpsIC(void) const;
double GetVBodyFpsIC(void) const { return GetBodyVelFpsIC(eV); }
/** Gets the initial body axis Z velocity.
@return Initial body axis Z velocity in feet/second. */
double GetWBodyFpsIC(void) const;
double GetWBodyFpsIC(void) const { return GetBodyVelFpsIC(eW); }
/** Gets the initial local frame X (North) velocity.
@return Initial local frame X (North) axis velocity in feet/second. */
double GetVNorthFpsIC(void) const {return vnorth;};
double GetVNorthFpsIC(void) const { return vUVW_NED(eU); }
/** Gets the initial local frame Y (East) velocity.
@return Initial local frame Y (East) axis velocity in feet/second. */
double GetVEastFpsIC(void) const {return veast;};
double GetVEastFpsIC(void) const { return vUVW_NED(eV); }
/** Gets the initial local frame Z (Down) velocity.
@return Initial local frame Z (Down) axis velocity in feet/second. */
double GetVDownFpsIC(void) const {return vdown;};
double GetVDownFpsIC(void) const { return vUVW_NED(eW); }
/** Gets the initial body axis roll rate.
@return Initial body axis roll rate in radians/second */
@ -524,7 +543,8 @@ public:
/** Sets the initial flight path angle.
@param gamma Initial flight path angle in radians */
void SetFlightPathAngleRadIC(double gamma);
void SetFlightPathAngleRadIC(double gamma)
{ SetClimbRateFpsIC(vt*sin(gamma)); }
/** Sets the initial angle of attack.
@param alpha Initial angle of attack in radians */
@ -548,59 +568,57 @@ public:
/** Sets the initial latitude.
@param lat Initial latitude in radians */
inline void SetLatitudeRadIC(double lat) { latitude=lat; }
void SetLatitudeRadIC(double lat) { position.SetLatitude(lat); }
/** Sets the initial longitude.
@param lon Initial longitude in radians */
inline void SetLongitudeRadIC(double lon) { longitude=lon; }
void SetLongitudeRadIC(double lon) { position.SetLongitude(lon); }
/** Sets the target normal load factor.
@param nlf Normal load factor*/
inline void SetTargetNlfIC(double nlf) { targetNlfIC=nlf; }
void SetTargetNlfIC(double nlf) { targetNlfIC=nlf; }
/** Gets the initial flight path angle.
If total velocity is zero, this function returns zero.
@return Initial flight path angle in radians */
inline double GetFlightPathAngleRadIC(void) const { return gamma; }
double GetFlightPathAngleRadIC(void) const
{ return (vt == 0.0)?0.0:asin(GetClimbRateFpsIC() / vt); }
/** Gets the initial angle of attack.
@return Initial alpha in radians */
inline double GetAlphaRadIC(void) const { return alpha; }
double GetAlphaRadIC(void) const { return alpha; }
/** Gets the initial angle of sideslip.
@return Initial sideslip angle in radians */
inline double GetBetaRadIC(void) const { return beta; }
double GetBetaRadIC(void) const { return beta; }
/** Gets the initial roll angle.
@return Initial roll angle in radians */
inline double GetPhiRadIC(void) const { return phi; }
double GetPhiRadIC(void) const { return phi; }
/** Gets the initial latitude.
@return Initial latitude in radians */
inline double GetLatitudeRadIC(void) const { return latitude; }
double GetLatitudeRadIC(void) const { return position.GetLatitude(); }
/** Gets the initial longitude.
@return Initial longitude in radians */
inline double GetLongitudeRadIC(void) const { return longitude; }
double GetLongitudeRadIC(void) const { return position.GetLongitude(); }
/** Gets the initial pitch angle.
@return Initial pitch angle in radians */
inline double GetThetaRadIC(void) const { return theta; }
double GetThetaRadIC(void) const { return theta; }
/** Gets the initial heading angle.
@return Initial heading angle in radians */
inline double GetPsiRadIC(void) const { return psi; }
double GetPsiRadIC(void) const { return psi; }
/** Gets the initial speedset.
@return Initial speedset */
inline speedset GetSpeedSet(void) { return lastSpeedSet; }
/** Gets the initial windset.
@return Initial windset */
inline windset GetWindSet(void) { return lastWindSet; }
speedset GetSpeedSet(void) const { return lastSpeedSet; }
/** Gets the target normal load factor set from IC.
@return target normal load factor set from IC*/
inline double GetTargetNlfIC(void) { return targetNlfIC; }
double GetTargetNlfIC(void) const { return targetNlfIC; }
/** Loads the initial conditions.
@param rstname The name of an initial conditions file
@ -610,39 +628,26 @@ public:
/** Get init-file name
*/
string GetInitFile(void) {return init_file_name;}
string GetInitFile(void) const {return init_file_name;}
/** Set init-file name
*/
void SetInitFile(string f) { init_file_name = f;}
void WriteStateFile(int num);
private:
double vt,vc,ve,vg;
double mach;
double altitudeASL,hdot;
double latitude,longitude;
double u,v,w;
FGColumnVector3 vUVW_NED;
FGLocation position;
double vt;
double p,q,r;
double uw,vw,ww;
double vnorth,veast,vdown;
double wnorth,weast,wdown;
double whead, wcross, wdir, wmag;
double sea_level_radius;
double terrain_elevation;
double radius_to_vehicle;
double targetNlfIC;
double alpha, beta, theta, phi, psi, gamma;
double salpha,sbeta,stheta,sphi,spsi,sgamma;
double calpha,cbeta,ctheta,cphi,cpsi,cgamma;
double xlo, xhi,xmin,xmax;
typedef double (FGInitialCondition::*fp)(double x);
fp sfunc;
FGMatrix33 Tw2b, Tb2w;
FGMatrix33 Tl2b, Tb2l;
double alpha, beta, theta, phi, psi;
speedset lastSpeedSet;
windset lastWindSet;
FGFDMExec *fdmex;
FGPropertyManager *PropertyManager;
@ -651,20 +656,16 @@ private:
bool Load_v2(void);
bool Constructing;
bool getAlpha(void);
bool getTheta(void);
bool getMachFromVcas(double *Mach,double vcas);
double GammaEqOfTheta(double Theta);
void InitializeIC(void);
double GammaEqOfAlpha(double Alpha);
double calcVcas(double Mach);
void calcUVWfromNED(void);
void calcWindUVW(void);
void calcAeroEuler(void);
bool findInterval(double x,double guess);
bool solve(double *y, double x);
void SetBodyVelFpsIC(int idx, double vel);
void SetNEDVelFpsIC(int idx, double vel);
double GetBodyWindFpsIC(int idx) const;
double GetNEDWindFpsIC(int idx) const;
double GetBodyVelFpsIC(int idx) const;
double getMachFromVcas(double vcas);
double calcVcas(double Mach) const;
void calcAeroAngles(const FGColumnVector3& _vt_BODY);
void bind(void);
void Debug(int from);

View file

@ -54,7 +54,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGScript.cpp,v 1.42 2010/11/24 12:58:39 jberndt Exp $";
static const char *IdSrc = "$Id: FGScript.cpp,v 1.43 2011/01/16 15:27:34 jberndt Exp $";
static const char *IdHdr = ID_FGSCRIPT;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -266,8 +266,9 @@ bool FGScript::LoadScript(string script, double deltaT)
} else {
cout << endl << fgred << " Could not find the property named "
<< notifyPropertyName << " in script" << endl << " \""
<< ScriptName << "\". This unknown property will not be "
<< "echoed for notification." << reset << endl;
<< ScriptName << "\". Execution is aborted. Please recheck "
<< "your input files and scripts." << reset << endl;
return false;
}
notify_property_element = notify_element->FindNextElement("property");
}

View file

@ -47,7 +47,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGColumnVector3.cpp,v 1.13 2010/08/08 00:19:21 jberndt Exp $";
static const char *IdSrc = "$Id: FGColumnVector3.cpp,v 1.14 2010/12/07 12:57:14 jberndt Exp $";
static const char *IdHdr = ID_COLUMNVECTOR3;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -125,47 +125,11 @@ FGColumnVector3& FGColumnVector3::Normalize(void)
return *this;
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
// 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 FGColumnVector3::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGColumnVector3" << endl;
if (from == 1) cout << "Destroyed: FGColumnVector3" << 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;
}
}
double FGColumnVector3::Magnitude(const int idx1, const int idx2) const {
return sqrt( data[idx1-1]*data[idx1-1] + data[idx2-1]*data[idx2-1] );
}
} // namespace JSBSim

View file

@ -41,13 +41,12 @@ INCLUDES
#include <iosfwd>
#include <string>
#include "FGJSBBase.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_COLUMNVECTOR3 "$Id: FGColumnVector3.h,v 1.12 2010/06/30 03:13:40 jberndt Exp $"
#define ID_COLUMNVECTOR3 "$Id: FGColumnVector3.h,v 1.16 2010/12/07 12:57:14 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -61,14 +60,14 @@ CLASS DOCUMENTATION
/** This class implements a 3 element column vector.
@author Jon S. Berndt, Tony Peden, et. al.
@version $Id: FGColumnVector3.h,v 1.12 2010/06/30 03:13:40 jberndt Exp $
@version $Id: FGColumnVector3.h,v 1.16 2010/12/07 12:57:14 jberndt Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGColumnVector3 : public FGJSBBase
class FGColumnVector3
{
public:
/** Default initializer.
@ -80,11 +79,10 @@ public:
@param Y value of the y-conponent.
@param Z value of the z-conponent.
Create a vector from the doubles given in the arguments. */
FGColumnVector3(double X, double Y, double Z) {
FGColumnVector3(const double X, const double Y, const double Z) {
data[0] = X;
data[1] = Y;
data[2] = Z;
// Debug(0);
}
/** Copy constructor.
@ -94,25 +92,24 @@ public:
data[0] = v.data[0];
data[1] = v.data[1];
data[2] = v.data[2];
// Debug(0);
}
/// Destructor.
~FGColumnVector3(void) { /* Debug(1); */ }
~FGColumnVector3(void) { }
/** Read access the entries of the vector.
@param idx the component index.
Return the value of the matrix entry at the given index.
Indices are counted starting with 1.
Note that the index given in the argument is unchecked. */
double operator()(unsigned int idx) const { return data[idx-1]; }
double operator()(const unsigned int idx) const { return data[idx-1]; }
/** Write access the entries of the vector.
@param idx the component index.
Return a reference to the vector entry at the given index.
Indices are counted starting with 1.
Note that the index given in the argument is unchecked. */
double& operator()(unsigned int idx) { return data[idx-1]; }
double& operator()(const unsigned int idx) { return data[idx-1]; }
/** Read access the entries of the vector.
@param idx the component index.
@ -122,7 +119,7 @@ public:
operator()(unsigned int idx) const</tt> function. It is
used internally to access the elements in a more convenient way.
Note that the index given in the argument is unchecked. */
double Entry(unsigned int idx) const { return data[idx-1]; }
double Entry(const unsigned int idx) const { return data[idx-1]; }
/** Write access the entries of the vector.
@param idx the component index.
@ -132,7 +129,7 @@ public:
operator()(unsigned int idx)</tt> function. It is
used internally to access the elements in a more convenient way.
Note that the index given in the argument is unchecked. */
double& Entry(unsigned int idx) { return data[idx-1]; }
double& Entry(const unsigned int idx) { return data[idx-1]; }
/** Prints the contents of the vector
@param delimeter the item separator (tab or comma)
@ -181,34 +178,34 @@ public:
Compute and return the cross product of the current vector with
the given argument. */
FGColumnVector3 operator*(const FGColumnVector3& V) const {
return FGColumnVector3( data[1] * V(3) - data[2] * V(2),
data[2] * V(1) - data[0] * V(3),
data[0] * V(2) - data[1] * V(1) );
return FGColumnVector3( data[1] * V.data[2] - data[2] * V.data[1],
data[2] * V.data[0] - data[0] * V.data[2],
data[0] * V.data[1] - data[1] * V.data[0] );
}
/// Addition operator.
FGColumnVector3 operator+(const FGColumnVector3& B) const {
return FGColumnVector3( data[0] + B(1), data[1] + B(2), data[2] + B(3) );
return FGColumnVector3( data[0] + B.data[0], data[1] + B.data[1], data[2] + B.data[2] );
}
/// Subtraction operator.
FGColumnVector3 operator-(const FGColumnVector3& B) const {
return FGColumnVector3( data[0] - B(1), data[1] - B(2), data[2] - B(3) );
return FGColumnVector3( data[0] - B.data[0], data[1] - B.data[1], data[2] - B.data[2] );
}
/// Subtract an other vector.
FGColumnVector3& operator-=(const FGColumnVector3 &B) {
data[0] -= B(1);
data[1] -= B(2);
data[2] -= B(3);
data[0] -= B.data[0];
data[1] -= B.data[1];
data[2] -= B.data[2];
return *this;
}
/// Add an other vector.
FGColumnVector3& operator+=(const FGColumnVector3 &B) {
data[0] += B(1);
data[1] += B(2);
data[2] += B(3);
data[0] += B.data[0];
data[1] += B.data[1];
data[2] += B.data[2];
return *this;
}
@ -224,8 +221,8 @@ public:
FGColumnVector3& operator/=(const double scalar);
void InitMatrix(void) { data[0] = data[1] = data[2] = 0.0; }
void InitMatrix(double a) { data[0] = data[1] = data[2] = a; }
void InitMatrix(double a, double b, double c) {
void InitMatrix(const double a) { data[0] = data[1] = data[2] = a; }
void InitMatrix(const double a, const double b, const double c) {
data[0]=a; data[1]=b; data[2]=c;
}
@ -236,9 +233,7 @@ public:
/** Length of the vector in a coordinate axis plane.
Compute and return the euclidean norm of this vector projected into
the coordinate axis plane idx1-idx2. */
double Magnitude(int idx1, int idx2) const {
return sqrt( data[idx1-1]*data[idx1-1] + data[idx2-1]*data[idx2-1] );
}
double Magnitude(const int idx1, const int idx2) const;
/** Normalize.
Normalize the vector to have the Magnitude() == 1.0. If the vector
@ -249,19 +244,18 @@ public:
Compute and return the euclidean dot (or scalar) product of two vectors
v1 and v2 */
friend inline double DotProduct(const FGColumnVector3& v1, const FGColumnVector3& v2) {
return v1(1)*v2(1) + v1(2)*v2(2) + v1(3)*v2(3);
return v1.data[0]*v2.data[0] + v1.data[1]*v2.data[1] + v1.data[2]*v2.data[2];
}
private:
double data[3];
void Debug(int from);
};
/** Scalar multiplication.
@param scalar scalar value to multiply with.
@param A Vector to multiply.
Multiply the Vector with a scalar value.*/
Multiply the Vector with a scalar value. Note: At this time, this
operator MUST be inlined, or a multiple definition link error will occur.*/
inline FGColumnVector3 operator*(double scalar, const FGColumnVector3& A) {
// use already defined operation.
return A*scalar;
@ -269,8 +263,8 @@ inline FGColumnVector3 operator*(double scalar, const FGColumnVector3& A) {
/** Write vector to a stream.
@param os Stream to write to.
@param M Matrix to write.
Write the matrix to a stream.*/
@param col vector to write.
Write the vector to a stream.*/
std::ostream& operator<<(std::ostream& os, const FGColumnVector3& col);
} // namespace JSBSim

View file

@ -48,7 +48,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGMatrix33.cpp,v 1.10 2010/07/01 23:13:19 jberndt Exp $";
static const char *IdSrc = "$Id: FGMatrix33.cpp,v 1.11 2010/12/07 12:57:14 jberndt Exp $";
static const char *IdHdr = ID_MATRIX33;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -61,8 +61,6 @@ FGMatrix33::FGMatrix33(void)
{
data[0] = data[1] = data[2] = data[3] = data[4] = data[5] =
data[6] = data[7] = data[8] = 0.0;
// Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -476,49 +474,4 @@ FGColumnVector3 FGMatrix33::operator*(const FGColumnVector3& v) const
return FGColumnVector3( tmp1, tmp2, tmp3 );
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// 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 FGMatrix33::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: FGMatrix33" << endl;
if (from == 1) cout << "Destroyed: FGMatrix33" << 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

@ -44,13 +44,12 @@ INCLUDES
#include <iosfwd>
#include "FGColumnVector3.h"
#include "FGJSBBase.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_MATRIX33 "$Id: FGMatrix33.h,v 1.12 2010/08/21 17:13:47 jberndt Exp $"
#define ID_MATRIX33 "$Id: FGMatrix33.h,v 1.14 2010/12/07 12:57:14 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -72,7 +71,7 @@ CLASS DOCUMENTATION
DECLARATION: MatrixException
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class MatrixException : public FGJSBBase
class MatrixException //: public FGJSBBase
{
public:
std::string Message;
@ -90,7 +89,7 @@ CLASS DOCUMENTATION
DECLARATION: FGMatrix33
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGMatrix33 : public FGJSBBase
class FGMatrix33
{
public:
@ -122,8 +121,6 @@ public:
data[6] = M.data[6];
data[7] = M.data[7];
data[8] = M.data[8];
// Debug(0);
}
/** Initialization by given values.
@ -140,9 +137,10 @@ public:
Create a matrix from the doubles given in the arguments.
*/
FGMatrix33(double m11, double m12, double m13,
double m21, double m22, double m23,
double m31, double m32, double m33) {
FGMatrix33(const double m11, const double m12, const double m13,
const double m21, const double m22, const double m23,
const double m31, const double m32, const double m33)
{
data[0] = m11;
data[1] = m21;
data[2] = m31;
@ -152,13 +150,11 @@ public:
data[6] = m13;
data[7] = m23;
data[8] = m33;
// Debug(0);
}
/** Destructor.
*/
~FGMatrix33(void) { /* Debug(1); */ }
~FGMatrix33(void) {}
/** Prints the contents of the matrix.
@param delimeter the item separator (tab or comma)
@ -263,9 +259,10 @@ public:
/** Initialize the matrix.
This function initializes a matrix to user specified values.
*/
void InitMatrix(double m11, double m12, double m13,
double m21, double m22, double m23,
double m31, double m32, double m33) {
void InitMatrix(const double m11, const double m12, const double m13,
const double m21, const double m22, const double m23,
const double m31, const double m32, const double m33)
{
data[0] = m11;
data[1] = m21;
data[2] = m31;
@ -309,7 +306,8 @@ public:
Copy the content of the matrix given in the argument into *this.
*/
FGMatrix33& operator=(const FGMatrix33& A) {
FGMatrix33& operator=(const FGMatrix33& A)
{
data[0] = A.data[0];
data[1] = A.data[1];
data[2] = A.data[2];
@ -434,8 +432,6 @@ public:
private:
double data[eRows*eColumns];
void Debug(int from);
};
/** Scalar multiplication.

View file

@ -57,7 +57,7 @@ using std::endl;
namespace JSBSim {
static const char *IdSrc = "$Id: FGQuaternion.cpp,v 1.17 2010/11/28 13:15:26 bcoconni Exp $";
static const char *IdSrc = "$Id: FGQuaternion.cpp,v 1.19 2010/12/07 12:57:14 jberndt Exp $";
static const char *IdHdr = ID_QUATERNION;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -254,55 +254,14 @@ void FGQuaternion::ComputeDerivedUnconditional(void) const
mEulerCosines(ePhi) = cos(mEulerAngles(ePhi));
mEulerCosines(eTht) = cos(mEulerAngles(eTht));
mEulerCosines(ePsi) = cos(mEulerAngles(ePsi));
// Debug(2);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// 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 FGQuaternion::Debug(int from) const
std::ostream& operator<<(std::ostream& os, const FGQuaternion& q)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGQuaternion" << endl;
if (from == 1) cout << "Destroyed: FGQuaternion" << 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 (!EqualToRoundoff(Magnitude(), 1.0)) {
cout << "Quaternion magnitude differs from 1.0 !" << endl;
cout << "\tdelta from 1.0: " << std::scientific << Magnitude()-1.0 << endl;
}
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
os << q(1) << " , " << q(2) << " , " << q(3) << " , " << q(4);
return os;
}
} // namespace JSBSim

View file

@ -47,7 +47,7 @@ SENTRY
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_QUATERNION "$Id: FGQuaternion.h,v 1.18 2010/09/29 02:19:05 jberndt Exp $"
#define ID_QUATERNION "$Id: FGQuaternion.h,v 1.22 2010/12/07 12:57:14 jberndt Exp $"
namespace JSBSim {
@ -88,7 +88,7 @@ class FGMatrix33;
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGQuaternion : virtual FGJSBBase {
class FGQuaternion : public FGJSBBase {
public:
/** Default initializer.
Default initializer, initializes the class with the identity rotation. */
@ -293,10 +293,10 @@ public:
@return reference to a quaternion object */
const FGQuaternion& operator=(const FGQuaternion& q) {
// Copy the master values ...
data[0] = q(1);
data[1] = q(2);
data[2] = q(3);
data[3] = q(4);
data[0] = q.data[0];
data[1] = q.data[1];
data[2] = q.data[2];
data[3] = q.data[3];
ComputeDerived();
// .. and copy the derived values if they are valid
mCacheValid = q.mCacheValid;
@ -317,8 +317,8 @@ public:
@param q a quaternion reference
@return true if both quaternions represent the same rotation. */
bool operator==(const FGQuaternion& q) const {
return data[0] == q(1) && data[1] == q(2)
&& data[2] == q(3) && data[3] == q(4);
return data[0] == q.data[0] && data[1] == q.data[1]
&& data[2] == q.data[2] && data[3] == q.data[3];
}
/** Comparison operator "!=".
@ -327,10 +327,10 @@ public:
bool operator!=(const FGQuaternion& q) const { return ! operator==(q); }
const FGQuaternion& operator+=(const FGQuaternion& q) {
// Copy the master values ...
data[0] += q(1);
data[1] += q(2);
data[2] += q(3);
data[3] += q(4);
data[0] += q.data[0];
data[1] += q.data[1];
data[2] += q.data[2];
data[3] += q.data[3];
mCacheValid = false;
return *this;
}
@ -340,10 +340,10 @@ public:
@return a quaternion reference representing Q, where Q = Q - q. */
const FGQuaternion& operator-=(const FGQuaternion& q) {
// Copy the master values ...
data[0] -= q(1);
data[1] -= q(2);
data[2] -= q(3);
data[3] -= q(4);
data[0] -= q.data[0];
data[1] -= q.data[1];
data[2] -= q.data[2];
data[3] -= q.data[3];
mCacheValid = false;
return *this;
}
@ -371,16 +371,16 @@ public:
@param q a quaternion to be summed.
@return a quaternion representing Q, where Q = Q + q. */
FGQuaternion operator+(const FGQuaternion& q) const {
return FGQuaternion(data[0]+q(1), data[1]+q(2),
data[2]+q(3), data[3]+q(4));
return FGQuaternion(data[0]+q.data[0], data[1]+q.data[1],
data[2]+q.data[2], data[3]+q.data[3]);
}
/** Arithmetic operator "-".
@param q a quaternion to be subtracted.
@return a quaternion representing Q, where Q = Q - q. */
FGQuaternion operator-(const FGQuaternion& q) const {
return FGQuaternion(data[0]-q(1), data[1]-q(2),
data[2]-q(3), data[3]-q(4));
return FGQuaternion(data[0]-q.data[0], data[1]-q.data[1],
data[2]-q.data[2], data[3]-q.data[3]);
}
/** Arithmetic operator "*".
@ -388,10 +388,10 @@ public:
@param q a quaternion to be multiplied.
@return a quaternion representing Q, where Q = Q * q. */
FGQuaternion operator*(const FGQuaternion& q) const {
return FGQuaternion(data[0]*q(1)-data[1]*q(2)-data[2]*q(3)-data[3]*q(4),
data[0]*q(2)+data[1]*q(1)+data[2]*q(4)-data[3]*q(3),
data[0]*q(3)-data[1]*q(4)+data[2]*q(1)+data[3]*q(2),
data[0]*q(4)+data[1]*q(3)-data[2]*q(2)+data[3]*q(1));
return FGQuaternion(data[0]*q.data[0]-data[1]*q.data[1]-data[2]*q.data[2]-data[3]*q.data[3],
data[0]*q.data[1]+data[1]*q.data[0]+data[2]*q.data[3]-data[3]*q.data[2],
data[0]*q.data[2]-data[1]*q.data[3]+data[2]*q.data[0]+data[3]*q.data[1],
data[0]*q.data[3]+data[1]*q.data[2]-data[2]*q.data[1]+data[3]*q.data[0]);
}
/** Arithmetic operator "*=".
@ -399,10 +399,10 @@ public:
@param q a quaternion to be multiplied.
@return a quaternion reference representing Q, where Q = Q * q. */
const FGQuaternion& operator*=(const FGQuaternion& q) {
double q0 = data[0]*q(1)-data[1]*q(2)-data[2]*q(3)-data[3]*q(4);
double q1 = data[0]*q(2)+data[1]*q(1)+data[2]*q(4)-data[3]*q(3);
double q2 = data[0]*q(3)-data[1]*q(4)+data[2]*q(1)+data[3]*q(2);
double q3 = data[0]*q(4)+data[1]*q(3)-data[2]*q(2)+data[3]*q(1);
double q0 = data[0]*q.data[0]-data[1]*q.data[1]-data[2]*q.data[2]-data[3]*q.data[3];
double q1 = data[0]*q.data[1]+data[1]*q.data[0]+data[2]*q.data[3]-data[3]*q.data[2];
double q2 = data[0]*q.data[2]-data[1]*q.data[3]+data[2]*q.data[0]+data[3]*q.data[1];
double q3 = data[0]*q.data[3]+data[1]*q.data[2]-data[2]*q.data[1]+data[3]*q.data[0];
data[0] = q0;
data[1] = q1;
data[2] = q2;
@ -506,8 +506,6 @@ private:
mutable FGColumnVector3 mEulerSines;
mutable FGColumnVector3 mEulerCosines;
void Debug(int from) const;
void InitializeFromEulerAngles(double phi, double tht, double psi);
};
@ -519,9 +517,15 @@ private:
Multiply the Vector with a scalar value.
*/
inline FGQuaternion operator*(double scalar, const FGQuaternion& q) {
return FGQuaternion(scalar*q(1), scalar*q(2), scalar*q(3), scalar*q(4));
return FGQuaternion(scalar*q.data[0], scalar*q.data[1], scalar*q.data[2], scalar*q.data[3]);
}
/** Write quaternion to a stream.
@param os Stream to write to.
@param q Quaternion to write.
Write the quaternion to a stream.*/
std::ostream& operator<<(std::ostream& os, const FGQuaternion& q);
} // namespace JSBSim
#include "FGMatrix33.h"

View file

@ -52,7 +52,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.35 2010/11/18 12:38:06 jberndt Exp $";
static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.36 2011/01/19 12:41:19 jberndt Exp $";
static const char *IdHdr = ID_AERODYNAMICS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -388,23 +388,28 @@ void FGAerodynamics::DetermineAxisSystem()
string axis;
while (axis_element) {
axis = axis_element->GetAttributeValue("name");
if (axis == "LIFT" || axis == "DRAG" || axis == "SIDE") {
if (axis == "LIFT" || axis == "DRAG") {
if (axisType == atNone) axisType = atLiftDrag;
else if (axisType != atLiftDrag) {
cerr << endl << " Mixed aerodynamic axis systems have been used in the"
<< " aircraft config file." << endl;
<< " aircraft config file. (LIFT DRAG)" << endl;
}
} else if (axis == "SIDE") {
if (axisType != atNone && axisType != atLiftDrag && axisType != atAxialNormal) {
cerr << endl << " Mixed aerodynamic axis systems have been used in the"
<< " aircraft config file. (SIDE)" << endl;
}
} else if (axis == "AXIAL" || axis == "NORMAL") {
if (axisType == atNone) axisType = atAxialNormal;
else if (axisType != atAxialNormal) {
cerr << endl << " Mixed aerodynamic axis systems have been used in the"
<< " aircraft config file." << endl;
<< " aircraft config file. (NORMAL AXIAL)" << endl;
}
} else if (axis == "X" || axis == "Y" || axis == "Z") {
if (axisType == atNone) axisType = atBodyXYZ;
else if (axisType != atBodyXYZ) {
cerr << endl << " Mixed aerodynamic axis systems have been used in the"
<< " aircraft config file." << endl;
<< " aircraft config file. (XYZ)" << endl;
}
} else if (axis != "ROLL" && axis != "PITCH" && axis != "YAW") { // error
cerr << endl << " An unknown axis type, " << axis << " has been specified"

View file

@ -53,7 +53,7 @@ using std::max;
namespace JSBSim {
static const char *IdSrc = "$Id: FGGasCell.cpp,v 1.12 2009/10/24 22:59:30 jberndt Exp $";
static const char *IdSrc = "$Id: FGGasCell.cpp,v 1.13 2010/12/29 22:39:25 andgi Exp $";
static const char *IdHdr = ID_GASCELL;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -206,20 +206,20 @@ FGGasCell::FGGasCell(FGFDMExec* exec, Element* el, int num) : FGForce(exec)
base_property_name = CreateIndexedPropertyName("buoyant_forces/gas-cell", CellNum);
property_name = base_property_name + "/max_volume-ft3";
PropertyManager->Tie( property_name.c_str(), &MaxVolume );
PropertyManager->Tie( property_name.c_str(), &MaxVolume, false );
PropertyManager->SetWritable( property_name, false );
property_name = base_property_name + "/temp-R";
PropertyManager->Tie( property_name.c_str(), &Temperature );
PropertyManager->Tie( property_name.c_str(), &Temperature, false );
property_name = base_property_name + "/pressure-psf";
PropertyManager->Tie( property_name.c_str(), &Pressure );
PropertyManager->Tie( property_name.c_str(), &Pressure, false );
property_name = base_property_name + "/volume-ft3";
PropertyManager->Tie( property_name.c_str(), &Volume );
PropertyManager->Tie( property_name.c_str(), &Volume, false );
property_name = base_property_name + "/buoyancy-lbs";
PropertyManager->Tie( property_name.c_str(), &Buoyancy );
PropertyManager->Tie( property_name.c_str(), &Buoyancy, false );
property_name = base_property_name + "/contents-mol";
PropertyManager->Tie( property_name.c_str(), &Contents );
PropertyManager->Tie( property_name.c_str(), &Contents, false );
property_name = base_property_name + "/valve_open";
PropertyManager->Tie( property_name.c_str(), &ValveOpen );
PropertyManager->Tie( property_name.c_str(), &ValveOpen, false );
Debug(0);
@ -646,23 +646,23 @@ FGBallonet::FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent)
base_property_name = CreateIndexedPropertyName(base_property_name + "/ballonet", CellNum);
property_name = base_property_name + "/max_volume-ft3";
PropertyManager->Tie( property_name, &MaxVolume );
PropertyManager->Tie( property_name, &MaxVolume, false );
PropertyManager->SetWritable( property_name, false );
property_name = base_property_name + "/temp-R";
PropertyManager->Tie( property_name, &Temperature );
PropertyManager->Tie( property_name, &Temperature, false );
property_name = base_property_name + "/pressure-psf";
PropertyManager->Tie( property_name, &Pressure );
PropertyManager->Tie( property_name, &Pressure, false );
property_name = base_property_name + "/volume-ft3";
PropertyManager->Tie( property_name, &Volume );
PropertyManager->Tie( property_name, &Volume, false );
property_name = base_property_name + "/contents-mol";
PropertyManager->Tie( property_name, &Contents );
PropertyManager->Tie( property_name, &Contents, false );
property_name = base_property_name + "/valve_open";
PropertyManager->Tie( property_name, &ValveOpen );
PropertyManager->Tie( property_name, &ValveOpen, false );
Debug(0);

View file

@ -71,7 +71,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.74 2010/11/28 13:02:43 bcoconni Exp $";
static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.76 2011/01/16 16:10:59 bcoconni Exp $";
static const char *IdHdr = ID_PROPAGATE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -157,8 +157,8 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle());
Ti2ec = GetTi2ec(); // ECI to ECEF transform
Tec2i = Ti2ec.Transposed(); // ECEF to ECI frame transform
Ti2ec = VState.vLocation.GetTi2ec(); // ECI to ECEF transform
Tec2i = Ti2ec.Transposed(); // ECEF to ECI frame transform
VState.vInertialPosition = Tec2i * VState.vLocation;
@ -260,8 +260,8 @@ bool FGPropagate::Run(void)
VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle());
// 2. Update the Ti2ec and Tec2i transforms from the updated EPA
Ti2ec = GetTi2ec(); // ECI to ECEF transform
Tec2i = Ti2ec.Transposed(); // ECEF to ECI frame transform
Ti2ec = VState.vLocation.GetTi2ec(); // ECI to ECEF transform
Tec2i = Ti2ec.Transposed(); // ECEF to ECI frame transform
// 3. Update the location from the updated Ti2ec and inertial position
VState.vLocation = Ti2ec*VState.vInertialPosition;
@ -561,7 +561,7 @@ void FGPropagate::ResolveFrictionForces(double dt)
// Prepare the linear system for the Gauss-Seidel algorithm :
// 1. Compute the right hand side member 'rhs'
// 2. Divide every line of 'a' and 'lhs' by a[i,i]. This is in order to save
// 2. Divide every line of 'a' and 'rhs' by a[i,i]. This is in order to save
// a division computation at each iteration of Gauss-Seidel.
for (int i=0; i < n; i++) {
double d = 1.0 / a[i*n+i];
@ -619,22 +619,22 @@ void FGPropagate::ResolveFrictionForces(double dt)
void FGPropagate::UpdateLocationMatrices(void)
{
Tl2ec = GetTl2ec(); // local to ECEF transform
Tec2l = Tl2ec.Transposed(); // ECEF to local frame transform
Ti2l = GetTi2l();
Tl2i = Ti2l.Transposed();
Tl2ec = VState.vLocation.GetTl2ec(); // local to ECEF transform
Tec2l = Tl2ec.Transposed(); // ECEF to local frame transform
Ti2l = VState.vLocation.GetTi2l(); // ECI to local frame transform
Tl2i = Ti2l.Transposed(); // local to ECI transform
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::UpdateBodyMatrices(void)
{
Ti2b = GetTi2b(); // ECI to body frame transform
Tb2i = Ti2b.Transposed(); // body to ECI frame transform
Tl2b = Ti2b*Tl2i; // local to body frame transform
Tb2l = Tl2b.Transposed(); // body to local frame transform
Tec2b = Tl2b * Tec2l; // ECEF to body frame transform
Tb2ec = Tec2b.Transposed(); // body to ECEF frame tranform
Ti2b = VState.qAttitudeECI.GetT(); // ECI to body frame transform
Tb2i = Ti2b.Transposed(); // body to ECI frame transform
Tl2b = Ti2b*Tl2i; // local to body frame transform
Tb2l = Tl2b.Transposed(); // body to local frame transform
Tec2b = Tl2b * Tec2l; // ECEF to body frame transform
Tb2ec = Tec2b.Transposed(); // body to ECEF frame tranform
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -651,7 +651,7 @@ void FGPropagate::SetInertialOrientation(FGQuaternion Qi) {
void FGPropagate::SetInertialVelocity(FGColumnVector3 Vi) {
VState.vInertialVelocity = Vi;
CalculateUVW();
vVel = GetTb2l() * VState.vUVW;
vVel = Tb2l * VState.vUVW;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -715,36 +715,6 @@ double FGPropagate::GetTerrainElevation(void) const
return FDMExec->GetGroundCallback()->GetTerrainGeoCentRadius()-SeaLevelRadius;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//Todo: when should this be called - when should the new EPA be used to
// calculate the transformation matrix, so that the matrix is not a step
// ahead of the sim and the associated calculations?
const FGMatrix33& FGPropagate::GetTi2ec(void)
{
return VState.vLocation.GetTi2ec();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
const FGMatrix33& FGPropagate::GetTec2i(void)
{
return VState.vLocation.GetTec2i();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::SetAltitudeASL(double altASL)
{
VState.vLocation.SetRadius( altASL + SeaLevelRadius );
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGPropagate::GetLocalTerrainRadius(void) const
{
return LocalTerrainRadius;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGPropagate::GetDistanceAGL(void) const
@ -754,9 +724,48 @@ double FGPropagate::GetDistanceAGL(void) const
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::SetDistanceAGL(double tt)
void FGPropagate::SetVState(const VehicleState& vstate)
{
VState.vLocation.SetRadius( tt + LocalTerrainRadius );
VState.vLocation = vstate.vLocation;
VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle());
Ti2ec = VState.vLocation.GetTi2ec(); // useless ?
Tec2i = Ti2ec.Transposed();
UpdateLocationMatrices();
SetInertialOrientation(vstate.qAttitudeECI);
RecomputeLocalTerrainRadius();
VehicleRadius = GetRadius();
VState.vUVW = vstate.vUVW;
vVel = Tb2l * VState.vUVW;
VState.vPQR = vstate.vPQR;
VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth;
VState.vPQRi_i = Tb2i * VState.vPQRi;
VState.vInertialPosition = vstate.vInertialPosition;
InitializeDerivatives();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::UpdateVehicleState(void)
{
RecomputeLocalTerrainRadius();
VehicleRadius = GetRadius();
VState.vInertialPosition = Tec2i * VState.vLocation;
UpdateLocationMatrices();
UpdateBodyMatrices();
vVel = Tb2l * VState.vUVW;
VState.qAttitudeLocal = Tl2b.GetQuaternion();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::SetLocation(const FGLocation& l)
{
VState.vLocation = l;
VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle());
Ti2ec = VState.vLocation.GetTi2ec(); // useless ?
Tec2i = Ti2ec.Transposed();
UpdateVehicleState();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -784,7 +793,7 @@ void FGPropagate::DumpState(void)
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 << " ECEF: " << (Tb2ec * 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;

View file

@ -49,7 +49,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.53 2010/11/28 13:02:43 bcoconni Exp $"
#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.55 2011/01/16 16:10:59 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -102,7 +102,7 @@ CLASS DOCUMENTATION
@endcode
@author Jon S. Berndt, Mathias Froehlich
@version $Id: FGPropagate.h,v 1.53 2010/11/28 13:02:43 bcoconni Exp $
@version $Id: FGPropagate.h,v 1.55 2011/01/16 16:10:59 bcoconni Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -441,7 +441,7 @@ public:
units feet
@return distance of the local terrain from the center of the earth.
*/
double GetLocalTerrainRadius(void) const;
double GetLocalTerrainRadius(void) const { return LocalTerrainRadius; }
double GetSeaLevelRadius(void) const { return SeaLevelRadius; }
double GetTerrainElevation(void) const;
@ -466,13 +466,13 @@ public:
The quaternion class, being the means by which the orientation of the
vehicle is stored, manages the local-to-body transformation matrix.
@return a reference to the local-to-body transformation matrix. */
const FGMatrix33& GetTl2b(void) const { return VState.qAttitudeLocal.GetT(); }
const FGMatrix33& GetTl2b(void) const { return Tl2b; }
/** Retrieves the body-to-local transformation matrix.
The quaternion class, being the means by which the orientation of the
vehicle is stored, manages the body-to-local transformation matrix.
@return a reference to the body-to-local matrix. */
const FGMatrix33& GetTb2l(void) const { return VState.qAttitudeLocal.GetTInv(); }
const FGMatrix33& GetTb2l(void) const { return Tb2l; }
/** Retrieves the ECEF-to-body transformation matrix.
@return a reference to the ECEF-to-body transformation matrix. */
@ -484,55 +484,43 @@ public:
/** Retrieves the ECI-to-body transformation matrix.
@return a reference to the ECI-to-body transformation matrix. */
const FGMatrix33& GetTi2b(void) const { return VState.qAttitudeECI.GetT(); }
const FGMatrix33& GetTi2b(void) const { return Ti2b; }
/** Retrieves the body-to-ECI transformation matrix.
@return a reference to the body-to-ECI matrix. */
const FGMatrix33& GetTb2i(void) const { return VState.qAttitudeECI.GetTInv(); }
const FGMatrix33& GetTb2i(void) const { return Tb2i; }
/** Retrieves the ECEF-to-ECI transformation matrix.
@return a reference to the ECEF-to-ECI transformation matrix. */
const FGMatrix33& GetTec2i(void);
const FGMatrix33& GetTec2i(void) const { return Tec2i; }
/** Retrieves the ECI-to-ECEF transformation matrix.
@return a reference to the ECI-to-ECEF matrix. */
const FGMatrix33& GetTi2ec(void);
const FGMatrix33& GetTi2ec(void) const { return Ti2ec; }
/** Retrieves the ECEF-to-local transformation matrix.
Retrieves the ECEF-to-local transformation matrix. Note that the so-called
local from is also know as the NED frame (for North, East, Down).
@return a reference to the ECEF-to-local matrix. */
const FGMatrix33& GetTec2l(void) const { return VState.vLocation.GetTec2l(); }
const FGMatrix33& GetTec2l(void) const { return Tec2l; }
/** Retrieves the local-to-ECEF transformation matrix.
Retrieves the local-to-ECEF transformation matrix. Note that the so-called
local from is also know as the NED frame (for North, East, Down).
@return a reference to the local-to-ECEF matrix. */
const FGMatrix33& GetTl2ec(void) const { return VState.vLocation.GetTl2ec(); }
const FGMatrix33& GetTl2ec(void) const { return Tl2ec; }
/** Retrieves the local-to-inertial transformation matrix.
@return a reference to the local-to-inertial transformation matrix. */
const FGMatrix33& GetTl2i(void) { return VState.vLocation.GetTl2i(); }
const FGMatrix33& GetTl2i(void) const { return Tl2i; }
/** Retrieves the inertial-to-local transformation matrix.
@return a reference to the inertial-to-local matrix. */
const FGMatrix33& GetTi2l(void) { return VState.vLocation.GetTi2l(); }
const FGMatrix33& GetTi2l(void) const { return Ti2l; }
VehicleState* GetVState(void) { return &VState; }
const VehicleState& GetVState(void) const { return VState; }
void SetVState(VehicleState* vstate) {
VState.vLocation = vstate->vLocation;
UpdateLocationMatrices();
SetInertialOrientation(vstate->qAttitudeECI);
VehicleRadius = GetRadius();
VState.vUVW = vstate->vUVW;
vVel = GetTb2l() * VState.vUVW;
VState.vPQR = vstate->vPQR;
VState.vPQRi = VState.vPQR + Ti2b * vOmegaEarth;
VState.vInertialPosition = vstate->vInertialPosition;
InitializeDerivatives();
}
void SetVState(const VehicleState& vstate);
void InitializeDerivatives(void);
@ -554,50 +542,46 @@ public:
// SET functions
void SetLongitude(double lon) {
VState.vLocation.SetLongitude(lon);
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
void SetLongitude(double lon)
{
VState.vLocation.SetLongitude(lon);
UpdateVehicleState();
}
void SetLongitudeDeg(double lon) { SetLongitude(lon*degtorad); }
void SetLatitude(double lat) {
VState.vLocation.SetLatitude(lat);
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
void SetLatitude(double lat)
{
VState.vLocation.SetLatitude(lat);
UpdateVehicleState();
}
void SetLatitudeDeg(double lat) { SetLatitude(lat*degtorad); }
void SetRadius(double r) {
VState.vLocation.SetRadius(r);
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
void SetRadius(double r)
{
VState.vLocation.SetRadius(r);
VehicleRadius = r;
VState.vInertialPosition = Tec2i * VState.vLocation;
}
void SetAltitudeASL(double altASL);
void SetAltitudeASLmeters(double altASL) {SetAltitudeASL(altASL/fttom);}
void SetAltitudeASL(double altASL) { SetRadius(altASL + SeaLevelRadius); }
void SetAltitudeASLmeters(double altASL) { SetRadius(altASL/fttom + SeaLevelRadius); }
void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; }
void SetTerrainElevation(double tt);
void SetDistanceAGL(double tt);
void SetDistanceAGL(double tt) { SetRadius(tt + LocalTerrainRadius); }
void SetInitialState(const FGInitialCondition *);
void SetPosition(const double Lon, const double Lat, const double Radius) {
VState.vLocation.SetPosition(Lon, Lat, Radius);
VState.vInertialPosition = GetTec2i() * VState.vLocation;
VehicleRadius = GetRadius();
UpdateLocationMatrices();
void SetLocation(const FGLocation& l);
void SetLocation(const FGColumnVector3& lv)
{
FGLocation l = FGLocation(lv);
SetLocation(l);
}
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 SetPosition(const double Lon, const double Lat, const double Radius)
{
FGLocation l = FGLocation(Lon, Lat, Radius);
SetLocation(l);
}
void RecomputeLocalTerrainRadius(void);
void NudgeBodyLocation(FGColumnVector3 deltaLoc) {
vDeltaXYZEC = GetTb2ec()*deltaLoc;
vDeltaXYZEC = Tb2ec*deltaLoc;
VState.vLocation -= vDeltaXYZEC;
}
@ -678,13 +662,11 @@ private:
void UpdateLocationMatrices(void);
void UpdateBodyMatrices(void);
void UpdateVehicleState(void);
void bind(void);
void Debug(int from);
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#include "initialization/FGInitialCondition.h"
#endif

View file

@ -307,18 +307,23 @@ bool FGPropulsion::Load(Element* el)
try {
if (type == "piston_engine") {
HavePistonEngine = true;
if (!IsBound) bind();
Engines.push_back(new FGPiston(FDMExec, document, numEngines));
} else if (type == "turbine_engine") {
HaveTurbineEngine = true;
if (!IsBound) bind();
Engines.push_back(new FGTurbine(FDMExec, document, numEngines));
} else if (type == "turboprop_engine") {
HaveTurboPropEngine = true;
if (!IsBound) bind();
Engines.push_back(new FGTurboProp(FDMExec, document, numEngines));
} else if (type == "rocket_engine") {
HaveRocketEngine = true;
if (!IsBound) bind();
Engines.push_back(new FGRocket(FDMExec, document, numEngines));
} else if (type == "electric_engine") {
HaveElectricEngine = true;
if (!IsBound) bind();
Engines.push_back(new FGElectric(FDMExec, document, numEngines));
} else {
cerr << "Unknown engine type: " << type << endl;
@ -345,7 +350,6 @@ bool FGPropulsion::Load(Element* el)
if (el->FindElement("dump-rate"))
DumpRate = el->FindElementValueAsNumberConvertTo("dump-rate", "LBS/MIN");
if (!IsBound) bind();
PostLoad(el, PropertyManager);
return true;

View file

@ -49,7 +49,7 @@ using namespace std;
namespace JSBSim {
static const char *IdSrc = "$Id: FGRocket.cpp,v 1.20 2010/08/21 17:13:48 jberndt Exp $";
static const char *IdSrc = "$Id: FGRocket.cpp,v 1.22 2010/12/30 13:35:09 jberndt Exp $";
static const char *IdHdr = ID_ROCKET;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -215,9 +215,9 @@ void FGRocket::ConsumeFuel(void)
if (Tank->GetContents() > 0.0 && Tank->GetSelected() && SourceTanks[i] > 0) ++TanksWithFuel;
break;
case FGTank::ttOXIDIZER:
if (Tank->GetContents() > 0.0 && Tank->GetSelected() && SourceTanks[i] > 0) {
if (Tank->GetSelected() && SourceTanks[i] > 0) {
haveOxTanks = true;
++TanksWithOxidizer;
if (Tank->GetContents() > 0.0) ++TanksWithOxidizer;
}
break;
}

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
Author: T. Kreitler
Date started: 08/24/00
------------- Copyright (C) 2010 T. Kreitler -------------
------------- Copyright (C) 2010 T. Kreitler (t.kreitler@web.de) -------------
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
@ -26,6 +26,7 @@
HISTORY
--------------------------------------------------------------------------------
01/01/10 T.Kreitler test implementation
01/10/11 T.Kreitler changed to single rotor model
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
@ -39,14 +40,12 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGThruster.h"
#include "math/FGTable.h"
#include "math/FGRungeKutta.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_ROTOR "$Id: FGRotor.h,v 1.6 2010/06/02 04:05:13 jberndt Exp $"
#define ID_ROTOR "$Id: FGRotor.h,v 1.8 2011/01/17 22:09:59 jberndt Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -58,58 +57,35 @@ namespace JSBSim {
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Models a rotor system. The default configuration consists of main and
tail rotor. A practical way to define the positions is to start with an
imaginary gear-box near the cg of the vehicle.
In this case the location in the thruster definition should be
approximately equal to the cg defined in the <tt>fdm_config/mass_balance</tt>
section. If the default orientation (roll=pitch=yaw=0) is used the
positions of the rotor hubs are now defined relative to the location
of the thruster (i.e. the cg-centered body coordinate system).
/** Models a helicopter rotor.
<h3>Configuration File Format:</h3>
<h3>Configuration File Format</h3>
@code
<rotor name="{string}" variant="{string}">
<rotor name="{string}">
<diameter unit="{LENGTH}"> {number} </diameter>
<numblades> {number} </numblades>
<xhub unit="{LENGTH}"> {number} </xhub>
<zhub unit="{LENGTH}"> {number} </zhub>
<gearratio> {number} </gearratio>
<nominalrpm> {number} </nominalrpm>
<minrpm> {number} </minrpm>
<chord unit="{LENGTH}"> {number} </chord>
<liftcurveslope Xunit="1/RAD"> {number} </liftcurveslope>
<flappingmoment unit="{MOMENT}"> {number} </flappingmoment>
<twist unit="{ANGLE}"> {number} </twist>
<massmoment Xunit="SLUG*FT"> {number} </massmoment>
<tiplossfactor> {number} </tiplossfactor>
<polarmoment unit="{MOMENT}"> {number}</polarmoment>
<inflowlag> {number} </inflowlag>
<shafttilt unit="{ANGLE}"> {number} </shafttilt>
<hingeoffset unit="{LENGTH}"> {number} </hingeoffset>
<tailrotor>
<diameter unit="{LENGTH}"> {number} </diameter>
<numblades> {number} </numblades>
<xhub unit="{LENGTH}">{number} </xhub>
<zhub unit="{LENGTH}">{number} </zhub>
<nominalrpm> {number} </nominalrpm>
<chord unit="{LENGTH}"> {number} </chord>
<liftcurveslope Xunit="1/RAD"> {number} </liftcurveslope>
<flappingmoment unit="{MOMENT}"> {number} </flappingmoment>
<twist unit="RAD"> {number} </twist>
<massmoment Xunit="SLUG*FT"> {number} </massmoment>
<tiplossfactor> {number} </tiplossfactor>
<inflowlag> {number} </inflowlag>
<hingeoffset unit="{LENGTH}"> {number} </hingeoffset>
<cantangle unit="{ANGLE}"> {number} </cantangle>
</tailrotor>
<cgroundeffect> {number} </cgroundeffect>
<flappingmoment unit="{MOMENT}"> {number} </flappingmoment>
<massmoment Xunit="SLUG*FT"> {number} </massmoment>
<polarmoment unit="{MOMENT}"> {number} </polarmoment>
<inflowlag> {number} </inflowlag>
<tiplossfactor> {number} </tiplossfactor>
<controlmap> {MAIN|TAIL|TANDEM} </controlmap>
<ExternalRPM> {number} </ExternalRPM>
<groundeffectexp> {number} </groundeffectexp>
<groundeffectshift unit="{LENGTH}"> {number} </groundeffectshift>
</rotor>
// LENGTH means any of the supported units, same for ANGLE and MOMENT.
// Xunit-attributes are a hint for currently unsupported units, so
// Xunit-attributes are a hint for currently unsupported units, so
// values must be provided accordingly.
@endcode
@ -119,67 +95,87 @@ CLASS DOCUMENTATION
Brief description and the symbol frequently found in the literature.
<pre>
\<diameter> - Rotor disk diameter (R).
\<diameter> - Rotor disk diameter (2x R).
\<numblades> - Number of blades (b).
\<xhub> - Relative height in body coordinate system, thus usually negative.
\<zhub> - Relative distance in body coordinate system, close to zero
for main rotor, and usually negative for the tail rotor.
\<gearratio> - Ratio of (engine rpm) / (rotor rpm), usually > 1.
\<nominalrpm> - RPM at which the rotor usally operates.
\<minrpm> - Lowest RPM generated by the code, optional.
\<chord> - Blade chord, (c).
\<liftcurveslope> - Slope of curve of section lift against section angle of attack,
per rad (a).
\<flappingmoment> - Flapping moment of inertia (I_b).
\<twist> - Blade twist from root to tip, (theta_1).
\<massmoment> - Blade mass moment. (Biege/Widerstands-moment)
\<hingeoffset> - Rotor flapping-hinge offset (e).
\<flappingmoment> - Flapping moment of inertia (I_b).
\<massmoment> - Blade mass moment. Mass of a single blade times the blade's
cg-distance from the hub, optional.
\<polarmoment> - Moment of inertia for the whole rotor disk, optional.
\<inflowlag> - Rotor inflow time constant, sec. Smaller values yield to
quicker responses to control input (defaults to 0.2).
\<tiplossfactor> - Tip-loss factor. The Blade fraction that produces lift.
Value usually ranges between 0.95 - 1.0, optional (B).
\<polarmoment> - Moment of inertia for the whole rotor disk, optional.
\<inflowlag> - Rotor inflow time constant, sec.
\<shafttilt> - Orientation of the rotor shaft, negative angles define
a 'forward' tilt. Used by main rotor, optional.
\<hingeoffset> - Rotor flapping-hinge offset (e).
\<controlmap> - Defines the control inputs used (see notes).
\<ExternalRPM> - Links the rotor to another rotor, or an user controllable property.
Experimental properties
\<cantangle> - Flapping hinge cantangle used by tail rotor, optional.
\<cgroundeffect> - Parameter for exponent in ground effect approximation. Value should
be in the range 0.2 - 0.35, 0.0 disables, optional.
\<groundeffectshift> - Further adjustment of ground effect.
\<groundeffectexp> - Exponent for ground effect approximation. Values usually range from 0.04
for large rotors to 0.1 for smaller ones. As a rule of thumb the effect
vanishes at a height 2-3 times the rotor diameter.
formula used: exp ( - groundeffectexp * (height+groundeffectshift) )
Omitting or setting to 0.0 disables the effect calculation.
\<groundeffectshift> - Further adjustment of ground effect, approx. hub height or slightly above.
</pre>
<h3>Notes:</h3>
The behavior of the rotor is controlled/influenced by 5 inputs.<ul>
<li> The power provided by the engine. This is handled by the regular engine controls.</li>
<li> The collective control input. This is read from the <tt>fdm</tt> property
<tt>propulsion/engine[x]/collective-ctrl-rad</tt>.</li>
<li> The lateral cyclic input. Read from
<tt>propulsion/engine[x]/lateral-ctrl-rad</tt>.</li>
<li> The longitudinal cyclic input. Read from
<tt>propulsion/engine[x]/longitudinal-ctrl-rad</tt>.</li>
<li> The tail collective (aka antitorque, aka pedal) control input. Read from
<tt>propulsion/engine[x]/antitorque-ctrl-rad</tt>.</li>
<h4>- Controls -</h4>
</ul>
The behavior of the rotor is controlled/influenced by following inputs.<ul>
<li> The power provided by the engine. This is handled by the regular engine controls.</li>
<li> The collective control input. This is read from the <tt>fdm</tt> property
<tt>propulsion/engine[x]/collective-ctrl-rad</tt>. See below for tail rotor</li>
<li> The lateral cyclic input. Read from
<tt>propulsion/engine[x]/lateral-ctrl-rad</tt>.</li>
<li> The longitudinal cyclic input. Read from
<tt>propulsion/engine[x]/longitudinal-ctrl-rad</tt>.</li>
<li> The tail collective (aka antitorque, aka pedal) control input. Read from
<tt>propulsion/engine[x]/antitorque-ctrl-rad</tt> or
<tt>propulsion/engine[x]/tail-collective-ctrl-rad</tt>.</li>
In order to keep the rotor speed constant, use of a RPM-Governor system is encouraged.
</ul>
It is possible to use different orientation/locations for the rotor system, but then xhub
and zhub are no longer aligned to the body frame and need proper recalculation.
<h4>- Tail/tandem rotor -</h4>
To model a standalone main rotor just omit the <tailrotor/> element. If you provide
a plain <tailrotor/> element all tail rotor parameters are estimated.
The 'sense' parameter from the thruster is interpreted as follows, sense=1 means
counter clockwise rotation of the main rotor, as viewed from above. This is as a far
as I know more popular than clockwise rotation, which is defined by setting sense to
-1 (to be honest, I'm just 99.9% sure that the orientation is handled properly).
Concerning coaxial designs: By providing the 'variant' attribute with value 'coaxial'
a Kamov-style rotor is modeled - i.e. the rotor produces no torque.
Providing <tt>\<ExternalRPM\> 0 \</ExternalRPM\></tt> the tail rotor's RPM
is linked to to the main (=first, =0) rotor, and specifing
<tt>\<controlmap\> TAIL \</controlmap\></tt> tells this rotor to read the
collective input from <tt>propulsion/engine[1]/antitorque-ctrl-rad</tt>
(The TAIL-map ignores lateral and longitudinal input). The rotor needs to be
attached to a dummy engine, e.g. an 1HP electrical engine.
A tandem rotor is setup analogous.
<h4>- Sense -</h4>
The 'sense' parameter from the thruster is interpreted as follows, sense=1 means
counter clockwise rotation of the main rotor, as viewed from above. This is as a far
as I know more popular than clockwise rotation, which is defined by setting sense to
-1. Concerning coaxial designs - by setting 'sense' to zero, a Kamov-style rotor is
modeled (i.e. the rotor produces no torque).
<h4>- Engine issues -</h4>
Currently the rotor can only be driven with piston and electrical engines. An adaption
for the turboprop engine might become available in the future.
In order to keep the rotor speed constant, use of a RPM-Governor system is
encouraged (see examples).
<h4>- Development hints -</h4>
Setting <tt>\<ExternalRPM> -1 \</ExternalRPM></tt> the rotor's RPM is controlled by
the <tt>propulsion/engine[x]/x-rpm-dict</tt> property. This feature can be useful
when developing a FDM.
<h3>References:</h3>
@ -196,147 +192,90 @@ CLASS DOCUMENTATION
</dl>
@author Thomas Kreitler
@version $Id: FGRotor.h,v 1.6 2010/06/02 04:05:13 jberndt Exp $
@version $Id: FGRotor.h,v 1.8 2011/01/17 22:09:59 jberndt Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGRotor : public FGThruster {
enum eRotorFlags {eNone=0, eMain=1, eTail=2, eCoaxial=4, eRotCW=8} ;
struct rotor {
virtual ~rotor();
void zero();
void configure(int f, const rotor *xmain = NULL);
// assist in parameter retrieval
double cnf_elem(const string& ename, double default_val=0.0, const string& unit = "", bool tell=false);
double cnf_elem(const string& ename, double default_val=0.0, bool tell=false);
// rotor dynamics
void calc_flow_and_thrust(double dt, double rho, double theta_0, double Uw, double Ww, double flow_scale = 1.0);
void calc_torque(double rho, double theta_0);
void calc_coning_angle(double rho, double theta_0);
void calc_flapping_angles(double rho, double theta_0, const FGColumnVector3 &pqr_fus_w);
void calc_drag_and_side_forces(double rho, double theta_0);
// transformations
FGColumnVector3 hub_vel_body2ca( const FGColumnVector3 &uvw, const FGColumnVector3 &pqr,
double a_ic = 0.0 , double b_ic = 0.0 );
FGColumnVector3 fus_angvel_body2ca( const FGColumnVector3 &pqr);
FGColumnVector3 body_forces(double a_ic = 0.0 , double b_ic = 0.0 );
FGColumnVector3 body_moments(FGColumnVector3 F_h, double a_ic = 0.0 , double b_ic = 0.0 );
// bookkeeping
int flags ;
Element *parent ;
// used in flow calculation
// FGRK4 rk ; // use this after checking
FGRKFehlberg rk ;
int reports ;
// configuration parameters
double Radius ;
int BladeNum ;
double RelDistance_xhub ;
double RelShift_yhub ;
double RelHeight_zhub ;
double NominalRPM ;
double MinRPM ;
double BladeChord ;
double LiftCurveSlope ;
double BladeFlappingMoment ;
double BladeTwist ;
double BladeMassMoment ;
double TipLossB ;
double PolarMoment ;
double InflowLag ;
double ShaftTilt ;
double HingeOffset ;
double HingeOffset_hover ;
double CantAngleD3 ;
double theta_shaft ;
double phi_shaft ;
// derived parameters
double LockNumberByRho ;
double solidity ; // aka sigma
double RpmRatio ; // main_to_tail, hmm
double R[5] ; // Radius powers
double B[6] ; // TipLossB powers
FGMatrix33 BodyToShaft ; // [S]T, see /SH79/ eqn(17,18)
FGMatrix33 ShaftToBody ; // [S]
// dynamic values
double ActualRPM ;
double Omega ; // must be > 0
double beta_orient ;
double a0 ; // coning angle (rad)
double a_1, b_1, a_dw ;
double a1s, b1s ; // cyclic flapping relative to shaft axes, /SH79/ eqn(43)
double H_drag, J_side ;
double Torque ;
double Thrust ;
double Ct ;
double lambda ; // inflow ratio
double mu ; // tip-speed ratio
double nu ; // induced inflow ratio
double v_induced ; // always positive [ft/s]
// results
FGColumnVector3 force ;
FGColumnVector3 moment ;
// declare the problem function
class dnuFunction : public FGRungeKuttaProblem {
public:
void update_params(rotor *r, double ct_t01, double fs, double w);
private:
double pFunc(double x, double y);
// some shortcuts
double k_sat, ct_lambda, k_wor, k_theta, mu2, k_flowscale;
} flowEquation;
};
class FGRotor : public FGThruster {
enum eCtrlMapping {eMainCtrl=0, eTailCtrl, eTandemCtrl};
public:
/** Constructor
@param exec pointer to executive structure
@param rotor_element pointer to XML element in the config file
@param num the number of this rotor */
/** Constructor for FGRotor.
@param exec a pointer to the main executive object
@param rotor_element a pointer to the thruster config file XML element
@param num the number of this rotor */
FGRotor(FGFDMExec *exec, Element* rotor_element, int num);
/// Destructor
/// Destructor for FGRotor
~FGRotor();
void SetRPM(double rpm) {RPM = rpm;}
/** Returns the power required by the rotor. Well, to achieve this the rotor
is cycled through the whole machinery, yielding to a new state.
(hmm, sort of a huge side effect)
*/
double GetPowerRequired(void);
/** Calculates forces and moments created by the rotor(s) and updates
vFn,vMn state variables. RPM changes are handled inside, too.
The RPM change is based on estimating the torque provided by the engine.
/** Returns the scalar thrust of the rotor, and adjusts the RPM value. */
double Calculate(double PowerAvailable);
@param PowerAvailable here this is the thrust (not power) provided by a turbine
@return PowerAvailable */
double Calculate(double);
double GetRPM(void) const { return RPM; }
double GetDiameter(void) { return mr.Radius*2.0; }
/// Retrieves the RPMs of the rotor.
double GetRPM(void) const { return RPM; }
// void SetRPM(double rpm) { RPM = rpm; }
/// Retrieves the RPMs of the Engine, as seen from this rotor.
double GetEngineRPM(void) const { return GearRatio*RPM; } // bit of a hack.
/// Tells the rotor's gear ratio, usually the engine asks for this.
double GetGearRatio(void) { return GearRatio; }
/// Retrieves the thrust of the rotor.
double GetThrust(void) const { return Thrust; }
// Stubs. Right now this rotor-to-engine interface is just a hack.
double GetTorque(void) { return 0.0; /* return mr.Torque;*/ }
double GetPowerRequired(void);
/// Retrieves the rotor's coning angle
double GetA0(void) const { return a0; }
/// Retrieves the longitudinal flapping angle with respect to the rotor shaft
double GetA1(void) const { return a1s; }
/// Retrieves the lateral flapping angle with respect to the rotor shaft
double GetB1(void) const { return b1s; }
/// Retrieves the inflow ratio
double GetLambda(void) const { return lambda; }
/// Retrieves the tip-speed (aka advance) ratio
double GetMu(void) const { return mu; }
/// Retrieves the induced inflow ratio
double GetNu(void) const { return nu; }
/// Retrieves the induced velocity
double GetVi(void) const { return v_induced; }
/// Retrieves the thrust coefficient
double GetCT(void) const { return C_T; }
/// Retrieves the torque
double GetTorque(void) const { return Torque; }
/// Downwash angle - currently only valid for a rotor that spins horizontally
double GetThetaDW(void) const { return theta_downwash; }
/// Downwash angle - currently only valid for a rotor that spins horizontally
double GetPhiDW(void) const { return phi_downwash; }
/// Retrieves the collective control input in radians.
double GetCollectiveCtrl(void) const { return CollectiveCtrl; }
/// Retrieves the lateral control input in radians.
double GetLateralCtrl(void) const { return LateralCtrl; }
/// Retrieves the longitudinal control input in radians.
double GetLongitudinalCtrl(void) const { return LongitudinalCtrl; }
/// Sets the collective control input in radians.
void SetCollectiveCtrl(double c) { CollectiveCtrl = c; }
/// Sets the lateral control input in radians.
void SetLateralCtrl(double c) { LateralCtrl = c; }
/// Sets the longitudinal control input in radians.
void SetLongitudinalCtrl(double c) { LongitudinalCtrl = c; }
// Stubs. Only main rotor RPM is returned
string GetThrusterLabels(int id, string delimeter);
@ -344,59 +283,105 @@ public:
private:
bool bind(void);
// assist in parameter retrieval
double ConfigValueConv( Element* e, const string& ename, double default_val=0.0,
const string& unit = "", bool tell=false);
double RPM;
double Sense; // default is counter clockwise rotation of the main rotor (viewed from above)
bool tailRotorPresent;
double ConfigValue( Element* e, const string& ename, double default_val=0.0,
bool tell=false);
void Configure(Element* rotor_element);
// true entry points
void CalcStatePart1(void);
void CalcStatePart2(double PowerAvailable);
// rotor dynamics
void calc_flow_and_thrust(double theta_0, double Uw, double Ww, double flow_scale = 1.0);
void calc_coning_angle(double theta_0);
void calc_flapping_angles(double theta_0, const FGColumnVector3 &pqr_fus_w);
void calc_drag_and_side_forces(double theta_0);
void calc_torque(double theta_0);
// transformations
FGColumnVector3 hub_vel_body2ca( const FGColumnVector3 &uvw, const FGColumnVector3 &pqr,
double a_ic = 0.0 , double b_ic = 0.0 );
FGColumnVector3 fus_angvel_body2ca( const FGColumnVector3 &pqr);
FGColumnVector3 body_forces(double a_ic = 0.0 , double b_ic = 0.0 );
FGColumnVector3 body_moments(double a_ic = 0.0 , double b_ic = 0.0 );
// interface
bool BindModel(void);
void Debug(int from);
FGPropertyManager* PropertyManager;
rotor mr;
rotor tr;
// environment
double dt;
double rho;
Filter damp_hagl;
double rho;
double effective_tail_col; // /SH79/ eqn(47)
// configuration parameters
double Radius;
int BladeNum;
double ground_effect_exp;
double ground_effect_shift;
double Sense;
double NominalRPM;
int ExternalRPM;
int RPMdefinition;
FGPropertyManager* ExtRPMsource;
double hover_threshold;
double hover_scale;
double BladeChord;
double LiftCurveSlope;
double BladeTwist;
double HingeOffset;
double BladeFlappingMoment;
double BladeMassMoment;
double PolarMoment;
double InflowLag;
double TipLossB;
// fdm imported controls
FGPropertyManager* prop_collective_ctrl;
FGPropertyManager* prop_lateral_ctrl;
FGPropertyManager* prop_longitudinal_ctrl;
FGPropertyManager* prop_antitorque_ctrl;
double GroundEffectExp;
double GroundEffectShift;
FGPropertyManager* prop_freewheel_factor;
FGPropertyManager* prop_rotorbrake;
// derived parameters
double LockNumberByRho;
double Solidity; // aka sigma
double R[5]; // Radius powers
double B[5]; // TipLossB powers
// fdm export ...
double prop_inflow_ratio_lambda;
double prop_advance_ratio_mu;
double prop_inflow_ratio_induced_nu;
double prop_mr_torque;
double prop_coning_angle;
// Some of the calculations require shaft axes. So the
// thruster orientation (Tbo, with b for body) needs to be
// expressed/represented in helicopter shaft coordinates (Hsr).
FGMatrix33 InvTransform;
FGMatrix33 TboToHsr;
FGMatrix33 HsrToTbo;
double prop_theta_downwash;
double prop_phi_downwash;
// dynamic values
double RPM;
double Omega; // must be > 0
double beta_orient; // rotor orientation angle (rad)
double a0; // coning angle (rad)
double a_1, b_1, a_dw; // flapping angles
double a1s, b1s; // cyclic flapping relative to shaft axes, /SH79/ eqn(43)
double H_drag, J_side; // Forces
double prop_thrust_coefficient;
double prop_lift_coefficient;
double Torque;
double C_T; // rotor thrust coefficient
double lambda; // inflow ratio
double mu; // tip-speed ratio
double nu; // induced inflow ratio
double v_induced; // induced velocity, always positive [ft/s]
double dt; // deltaT doesn't do the thing
double theta_downwash;
double phi_downwash;
// devel/debug stuff
int prop_DumpFlag; // causes 1-time dump on stdout
// control
eCtrlMapping ControlMap;
double CollectiveCtrl;
double LateralCtrl;
double LongitudinalCtrl;
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif