1
0
Fork 0
This commit is contained in:
Torsten Dreyer 2011-01-23 22:02:40 +01:00
commit b689e9dee7
34 changed files with 1950 additions and 2251 deletions

View file

@ -111,16 +111,17 @@ if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND")
# on MSVC builds # on MSVC builds
set(thread_lib threads) set(thread_lib threads)
endif(NOT MSVC) endif(NOT MSVC)
# note the order here affects the order Simgear libraries are # note the order here affects the order Simgear libraries are
# linked in, and hence ability to link when using a traditional # linked in, and hence ability to link when using a traditional
# linker such as GNU ld on Linux # linker such as GNU ld on Linux
set(comps set(comps
ephemeris ephem
environment environment
nasal nasal
sky sky
material tgdb material
tgdb
model model
screen screen
bucket bucket

View file

@ -19,7 +19,17 @@ if(HAVE_APR_CONFIG)
string(STRIP ${RAW_APR_LIBS} APR_LIBS) string(STRIP ${RAW_APR_LIBS} APR_LIBS)
else(HAVE_APR_CONFIG) else(HAVE_APR_CONFIG)
message(STATUS "apr-1-config not found, implement manual search for APR") FIND_LIBRARY(APR_LIBS
NAMES libapr-1 apr-1
HINTS
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
endif(HAVE_APR_CONFIG) endif(HAVE_APR_CONFIG)
find_path(LIBSVN_INCLUDE_DIR svn_client.h find_path(LIBSVN_INCLUDE_DIR svn_client.h
@ -32,17 +42,49 @@ find_path(LIBSVN_INCLUDE_DIR svn_client.h
/opt /opt
) )
check_library_exists(svn_client-1 svn_client_checkout "" HAVE_LIB_SVNCLIENT) FIND_LIBRARY(SVNCLIENT_LIBRARY
check_library_exists(svn_subr-1 svn_cmdline_init "" HAVE_LIB_SVNSUBR) NAMES libsvn_client-1 svn_client-1
check_library_exists(svn_ra-1 svn_ra_initialize "" HAVE_LIB_SVNRA) HINTS
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
FIND_LIBRARY(SVNSUBR_LIBRARY
NAMES libsvn_subr-1 svn_subr-1
HINTS
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
FIND_LIBRARY(SVNRA_LIBRARY
NAMES libsvn_ra-1 svn_ra-1
HINTS
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt
)
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG
HAVE_LIB_SVNSUBR SVNSUBR_LIBRARY
HAVE_LIB_SVNCLIENT SVNCLIENT_LIBRARY
HAVE_LIB_SVNRA SVNRA_LIBRARY
LIBSVN_INCLUDE_DIR) LIBSVN_INCLUDE_DIR)
if(LIBSVN_FOUND) if(LIBSVN_FOUND)
set(LIBSVN_LIBRARIES "svn_client-1" "svn_subr-1" "svn_ra-1" ${APR_LIBS}) set(LIBSVN_LIBRARIES ${SVNCLIENT_LIBRARY} ${SVNSUBR_LIBRARY} ${SVNRA_LIBRARY} ${APR_LIBS})
endif(LIBSVN_FOUND) endif(LIBSVN_FOUND)

View file

@ -271,9 +271,11 @@ if test "x$with_rti13" != "xno"; then
if test "x$simgear_hla" = "xyes" ; then if test "x$simgear_hla" = "xyes" ; then
AC_MSG_CHECKING([for hla libraries]) AC_MSG_CHECKING([for hla libraries])
saved_LIBS="$LIBS" saved_LIBS="$LIBS"
saved_LDFLAGS="$LDFLAGS"
for rti13libs in "-lRTI-NG -lFedTime" "-lRTI-NGd -lFedTimed" ; do for rti13libs in "-lRTI-NG -lFedTime" "-lRTI-NGd -lFedTimed" ; do
if test "x$hla_libs" = "x" ; then if test "x$hla_libs" = "x" ; then
LIBS="-lsghla13 -lsghla -lsgxml -lsgstructure -lsgmath -lsgdebug -lsgtiming $rti13libs -lrt $saved_LIBS" LIBS="-lsghla13 -lsghla -lsgxml -lsgstructure -lsgmath -lsgdebug -lsgtiming $rti13libs -lrt $saved_LIBS"
LDFLAGS="$HLA_LDFLAGS $saved_LDFLAGS"
AC_TRY_LINK([ AC_TRY_LINK([
#include <simgear/hla/HLA13Federate.hxx> #include <simgear/hla/HLA13Federate.hxx>
],[ ],[
@ -282,6 +284,7 @@ if test "x$with_rti13" != "xno"; then
fi fi
done done
LIBS="$saved_LIBS" LIBS="$saved_LIBS"
LDFLAGS="$saved_LDFLAGS"
AC_MSG_RESULT($hla_libs) AC_MSG_RESULT($hla_libs)
fi fi
AC_LANG_POP() AC_LANG_POP()

View file

@ -354,11 +354,6 @@ flightgear::WayptRef FGRouteMgr::removeWayptAtIndex(int aIndex)
SG_LOG(SG_AUTOPILOT, SG_WARN, "removeWayptAtIndex with invalid index:" << aIndex); SG_LOG(SG_AUTOPILOT, SG_WARN, "removeWayptAtIndex with invalid index:" << aIndex);
return NULL; return NULL;
} }
if (_currentIndex > index) {
--_currentIndex; // shift current index down if necessary
}
WayptVec::iterator it = _route.begin(); WayptVec::iterator it = _route.begin();
it += index; it += index;
@ -366,6 +361,15 @@ flightgear::WayptRef FGRouteMgr::removeWayptAtIndex(int aIndex)
_route.erase(it); _route.erase(it);
update_mirror(); update_mirror();
if (_currentIndex == index) {
currentWaypointChanged(); // current waypoint was removed
}
else
if (_currentIndex > index) {
--_currentIndex; // shift current index down if necessary
}
_edited->fireValueChanged(); _edited->fireValueChanged();
checkFinished(); checkFinished();
@ -682,7 +686,7 @@ void FGRouteMgr::insertWayptAtIndex(Waypt* aWpt, int aIndex)
WayptVec::iterator it = _route.begin(); WayptVec::iterator it = _route.begin();
it += index; it += index;
if (_currentIndex > index) { if (_currentIndex >= index) {
++_currentIndex; ++_currentIndex;
} }

View file

@ -194,18 +194,18 @@ public:
class MetarLoadRequest { class MetarLoadRequest {
public: public:
MetarLoadRequest( const string & stationId ) { MetarLoadRequest( const string & stationId ) :
_stationId = stationId; _stationId(stationId),
_proxyHost = fgGetNode("/sim/presets/proxy/host", true)->getStringValue(); _proxyHost(fgGetNode("/sim/presets/proxy/host", true)->getStringValue()),
_proxyPort = fgGetNode("/sim/presets/proxy/port", true)->getStringValue(); _proxyPort(fgGetNode("/sim/presets/proxy/port", true)->getStringValue()),
_proxyAuth = fgGetNode("/sim/presets/proxy/authentication", true)->getStringValue(); _proxyAuth(fgGetNode("/sim/presets/proxy/authentication", true)->getStringValue())
} {}
MetarLoadRequest( const MetarLoadRequest & other ) { MetarLoadRequest( const MetarLoadRequest & other ) :
_stationId = other._stationId; _stationId(other._stationId),
_proxyHost = other._proxyAuth; _proxyHost(other._proxyAuth),
_proxyPort = other._proxyPort; _proxyPort(other._proxyPort),
_proxyAuth = other._proxyAuth; _proxyAuth(other._proxyAuth)
} {}
string _stationId; string _stationId;
string _proxyHost; string _proxyHost;
string _proxyPort; string _proxyPort;

View file

@ -7,7 +7,7 @@ using simgear::PropertyList;
class TiedPropertyList : PropertyList { class TiedPropertyList : PropertyList {
public: public:
TiedPropertyList() {} TiedPropertyList() {}
TiedPropertyList( SGPropertyNode_ptr root ) { _root = root; } TiedPropertyList( SGPropertyNode_ptr root ) : _root(root) {}
void setRoot( SGPropertyNode_ptr root ) { _root = root; } void setRoot( SGPropertyNode_ptr root ) { _root = root; }
SGPropertyNode_ptr getRoot() const { return _root; } SGPropertyNode_ptr getRoot() const { return _root; }

View file

@ -71,7 +71,7 @@ using namespace std;
namespace JSBSim { 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; static const char *IdHdr = ID_FDMEXEC;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -700,7 +700,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
FCS->LateBind(); FCS->LateBind();
} catch (string prop) { } catch (string prop) {
cerr << endl << fgred << " Could not late bind property " << prop cerr << endl << fgred << " Could not late bind property " << prop
<< ". Aborting." << endl; << ". Aborting." << reset << endl;
result = false; result = false;
} }

View file

@ -143,8 +143,6 @@ FGJSBsim::FGJSBsim( double dt )
break; break;
} }
} }
resetPropertyState();
fdmex = new FGFDMExec( (FGPropertyManager*)globals->get_props() ); 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); 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 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 INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFDMExec.h"
#include "FGJSBBase.h"
#include "math/FGColumnVector3.h"
#include "input_output/FGXMLFileRead.h" #include "input_output/FGXMLFileRead.h"
#include "math/FGLocation.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS 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 FORWARD DECLARATIONS
@ -64,8 +62,11 @@ FORWARD DECLARATIONS
namespace JSBSim { namespace JSBSim {
class FGFDMExec;
class FGMatrix33;
class FGColumnVector3;
typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset; typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
typedef enum { setwned, setwmd, setwhc } windset;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION CLASS DOCUMENTATION
@ -83,17 +84,27 @@ CLASS DOCUMENTATION
With a valid object of FGFDMExec and an aircraft model loaded: With a valid object of FGFDMExec and an aircraft model loaded:
@code @code
FGInitialCondition fgic=new FGInitialCondition(FDMExec); FGInitialCondition* fgic = FDMExec->GetIC();
fgic->SetVcalibratedKtsIC()
fgic->SetAltitudeAGLFtIC(); // Reset the initial conditions and set VCAS and altitude
fgic->InitializeIC();
fgic->SetVcalibratedKtsIC(vcas);
fgic->SetAltitudeAGLFtIC(altitude);
// directly into Run // directly into Run
FDMExec->GetState()->Initialize(fgic) FDMExec->GetPropagate()->SetInitialState(fgic);
delete fgic; delete fgic;
FDMExec->Run() FDMExec->Run();
//or to loop the sim w/o integrating //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 @endcode
<h3>Speed</h3> <h3>Speed</h3>
@ -202,7 +213,7 @@ CLASS DOCUMENTATION
@property ic/r-rad_sec (read/write) Yaw rate initial condition in radians/second @property ic/r-rad_sec (read/write) Yaw rate initial condition in radians/second
@author Tony Peden @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. /** Set true airspeed initial condition in knots.
@param vt True airspeed 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. /** Set ground speed initial condition in knots.
@param vg Ground speed 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. /** Set mach initial condition.
@param mach Mach number */ @param mach Mach number */
@ -239,15 +250,15 @@ public:
/** Sets angle of attack initial condition in degrees. /** Sets angle of attack initial condition in degrees.
@param a Alpha 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. /** Sets angle of sideslip initial condition in degrees.
@param B Beta 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. /** Sets pitch angle initial condition in degrees.
@param theta Theta (pitch) angle 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 /** Resets the IC data structure to new values
@param u, v, w, ... **/ @param u, v, w, ... **/
@ -258,19 +269,20 @@ public:
/** Sets the roll angle initial condition in degrees. /** Sets the roll angle initial condition in degrees.
@param phi roll angle 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. /** Sets the heading angle initial condition in degrees.
@param psi Heading angle 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. /** Sets the climb rate initial condition in feet/minute.
@param roc Rate of Climb 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. /** Sets the flight path angle initial condition in degrees.
@param gamma Flight path angle 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. /** Sets the altitude above sea level initial condition in feet.
@param altitudeASL Altitude above sea level in feet */ @param altitudeASL Altitude above sea level in feet */
@ -278,95 +290,98 @@ public:
/** Sets the initial Altitude above ground level. /** Sets the initial Altitude above ground level.
@param agl Altitude above ground level in feet */ @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 /** Sets the initial sea level radius from planet center
@param sl_rad sea level radius in feet */ @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. /** Sets the initial terrain elevation.
@param elev Initial terrain elevation in feet */ @param elev Initial terrain elevation in feet */
void SetTerrainElevationFtIC(double elev); void SetTerrainElevationFtIC(double elev) { terrain_elevation = elev; }
/** Sets the initial latitude. /** Sets the initial latitude.
@param lat Initial latitude in degrees */ @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. /** Sets the initial longitude.
@param lon Initial longitude in degrees */ @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. /** Gets the initial calibrated airspeed.
@return Initial calibrated airspeed in knots */ @return Initial calibrated airspeed in knots */
inline double GetVcalibratedKtsIC(void) const { return vc*fpstokts; } double GetVcalibratedKtsIC(void) const;
/** Gets the initial equivalent airspeed. /** Gets the initial equivalent airspeed.
@return Initial equivalent airspeed in knots */ @return Initial equivalent airspeed in knots */
inline double GetVequivalentKtsIC(void) const { return ve*fpstokts; } double GetVequivalentKtsIC(void) const;
/** Gets the initial ground speed. /** Gets the initial ground speed.
@return Initial ground speed in knots */ @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. /** Gets the initial true velocity.
@return Initial true airspeed in knots. */ @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. /** Gets the initial mach.
@return Initial mach number */ @return Initial mach number */
inline double GetMachIC(void) const { return mach; } double GetMachIC(void) const;
/** Gets the initial climb rate. /** Gets the initial climb rate.
@return Initial climb rate in feet/minute */ @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. /** Gets the initial flight path angle.
@return Initial flight path angle in degrees */ @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. /** Gets the initial angle of attack.
@return Initial alpha in degrees */ @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. /** Gets the initial sideslip angle.
@return Initial beta in degrees */ @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. /** Gets the initial pitch angle.
@return Initial pitch angle in degrees */ @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. /** Gets the initial roll angle.
@return Initial phi in degrees */ @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. /** Gets the initial heading angle.
@return Initial psi in degrees */ @return Initial psi in degrees */
inline double GetPsiDegIC(void) const { return psi*radtodeg; } double GetPsiDegIC(void) const { return psi*radtodeg; }
/** Gets the initial latitude. /** Gets the initial latitude.
@return Initial geocentric latitude in degrees */ @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. /** Gets the initial longitude.
@return Initial longitude in degrees */ @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. /** Gets the initial altitude above sea level.
@return Initial altitude in feet. */ @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. /** Gets the initial altitude above ground level.
@return Initial altitude AGL in feet */ @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. /** Gets the initial sea level radius.
@return 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. /** Gets the initial terrain elevation.
@return Initial terrain elevation in feet */ @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. /** Sets the initial ground speed.
@param vg Initial ground speed in feet/second */ @param vg Initial ground speed in feet/second */
@ -378,27 +393,27 @@ public:
/** Sets the initial body axis X velocity. /** Sets the initial body axis X velocity.
@param ubody Initial X velocity in feet/second */ @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. /** Sets the initial body axis Y velocity.
@param vbody Initial Y velocity in feet/second */ @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. /** Sets the initial body axis Z velocity.
@param wbody Initial Z velocity in feet/second */ @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. /** Sets the initial local axis north velocity.
@param vn Initial north velocity in feet/second */ @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. /** Sets the initial local axis east velocity.
@param ve Initial east velocity in feet/second */ @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. /** Sets the initial local axis down velocity.
@param vd Initial down velocity in feet/second */ @param vd Initial down velocity in feet/second */
void SetVDownFpsIC(double vd); void SetVDownFpsIC(double vd) { SetNEDVelFpsIC(eW, vd); }
/** Sets the initial roll rate. /** Sets the initial roll rate.
@param P Initial roll rate in radians/second */ @param P Initial roll rate in radians/second */
@ -444,39 +459,39 @@ public:
/** Gets the initial ground velocity. /** Gets the initial ground velocity.
@return Initial ground velocity in feet/second */ @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. /** Gets the initial true velocity.
@return Initial true velocity in feet/second */ @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. /** Gets the initial body axis X wind velocity.
@return Initial body axis X wind velocity in feet/second */ @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. /** Gets the initial body axis Y wind velocity.
@return Initial body axis Y wind velocity in feet/second */ @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. /** Gets the initial body axis Z wind velocity.
@return Initial body axis Z wind velocity in feet/second */ @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. /** Gets the initial wind velocity in local frame.
@return Initial wind velocity toward north in feet/second */ @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. /** Gets the initial wind velocity in local frame.
@return Initial wind velocity eastwards in feet/second */ @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. /** Gets the initial wind velocity in local frame.
@return Initial wind velocity downwards in feet/second */ @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. /** Gets the initial total wind velocity in feet/sec.
@return Initial wind velocity in feet/second */ @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. /** Gets the initial wind direction.
@return Initial wind direction in feet/second */ @return Initial wind direction in feet/second */
@ -484,31 +499,35 @@ public:
/** Gets the initial climb rate. /** Gets the initial climb rate.
@return Initial rate of climb in feet/second */ @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. /** Gets the initial body axis X velocity.
@return Initial body axis X velocity in feet/second. */ @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. /** Gets the initial body axis Y velocity.
@return Initial body axis Y velocity in feet/second. */ @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. /** Gets the initial body axis Z velocity.
@return Initial body axis Z velocity in feet/second. */ @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. /** Gets the initial local frame X (North) velocity.
@return Initial local frame X (North) axis velocity in feet/second. */ @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. /** Gets the initial local frame Y (East) velocity.
@return Initial local frame Y (East) axis velocity in feet/second. */ @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. /** Gets the initial local frame Z (Down) velocity.
@return Initial local frame Z (Down) axis velocity in feet/second. */ @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. /** Gets the initial body axis roll rate.
@return Initial body axis roll rate in radians/second */ @return Initial body axis roll rate in radians/second */
@ -524,7 +543,8 @@ public:
/** Sets the initial flight path angle. /** Sets the initial flight path angle.
@param gamma Initial flight path angle in radians */ @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. /** Sets the initial angle of attack.
@param alpha Initial angle of attack in radians */ @param alpha Initial angle of attack in radians */
@ -548,59 +568,57 @@ public:
/** Sets the initial latitude. /** Sets the initial latitude.
@param lat Initial latitude in radians */ @param lat Initial latitude in radians */
inline void SetLatitudeRadIC(double lat) { latitude=lat; } void SetLatitudeRadIC(double lat) { position.SetLatitude(lat); }
/** Sets the initial longitude. /** Sets the initial longitude.
@param lon Initial longitude in radians */ @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. /** Sets the target normal load factor.
@param nlf 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. /** Gets the initial flight path angle.
If total velocity is zero, this function returns zero.
@return Initial flight path angle in radians */ @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. /** Gets the initial angle of attack.
@return Initial alpha in radians */ @return Initial alpha in radians */
inline double GetAlphaRadIC(void) const { return alpha; } double GetAlphaRadIC(void) const { return alpha; }
/** Gets the initial angle of sideslip. /** Gets the initial angle of sideslip.
@return Initial sideslip angle in radians */ @return Initial sideslip angle in radians */
inline double GetBetaRadIC(void) const { return beta; } double GetBetaRadIC(void) const { return beta; }
/** Gets the initial roll angle. /** Gets the initial roll angle.
@return Initial roll angle in radians */ @return Initial roll angle in radians */
inline double GetPhiRadIC(void) const { return phi; } double GetPhiRadIC(void) const { return phi; }
/** Gets the initial latitude. /** Gets the initial latitude.
@return Initial latitude in radians */ @return Initial latitude in radians */
inline double GetLatitudeRadIC(void) const { return latitude; } double GetLatitudeRadIC(void) const { return position.GetLatitude(); }
/** Gets the initial longitude. /** Gets the initial longitude.
@return Initial longitude in radians */ @return Initial longitude in radians */
inline double GetLongitudeRadIC(void) const { return longitude; } double GetLongitudeRadIC(void) const { return position.GetLongitude(); }
/** Gets the initial pitch angle. /** Gets the initial pitch angle.
@return Initial pitch angle in radians */ @return Initial pitch angle in radians */
inline double GetThetaRadIC(void) const { return theta; } double GetThetaRadIC(void) const { return theta; }
/** Gets the initial heading angle. /** Gets the initial heading angle.
@return Initial heading angle in radians */ @return Initial heading angle in radians */
inline double GetPsiRadIC(void) const { return psi; } double GetPsiRadIC(void) const { return psi; }
/** Gets the initial speedset. /** Gets the initial speedset.
@return Initial speedset */ @return Initial speedset */
inline speedset GetSpeedSet(void) { return lastSpeedSet; } speedset GetSpeedSet(void) const { return lastSpeedSet; }
/** Gets the initial windset.
@return Initial windset */
inline windset GetWindSet(void) { return lastWindSet; }
/** Gets the target normal load factor set from IC. /** Gets the target normal load factor set from IC.
@return 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. /** Loads the initial conditions.
@param rstname The name of an initial conditions file @param rstname The name of an initial conditions file
@ -610,39 +628,26 @@ public:
/** Get init-file name /** Get init-file name
*/ */
string GetInitFile(void) {return init_file_name;} string GetInitFile(void) const {return init_file_name;}
/** Set init-file name /** Set init-file name
*/ */
void SetInitFile(string f) { init_file_name = f;} void SetInitFile(string f) { init_file_name = f;}
void WriteStateFile(int num); void WriteStateFile(int num);
private: private:
double vt,vc,ve,vg; FGColumnVector3 vUVW_NED;
double mach; FGLocation position;
double altitudeASL,hdot; double vt;
double latitude,longitude;
double u,v,w;
double p,q,r; 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 sea_level_radius;
double terrain_elevation; double terrain_elevation;
double radius_to_vehicle;
double targetNlfIC; double targetNlfIC;
double alpha, beta, theta, phi, psi, gamma; FGMatrix33 Tw2b, Tb2w;
double salpha,sbeta,stheta,sphi,spsi,sgamma; FGMatrix33 Tl2b, Tb2l;
double calpha,cbeta,ctheta,cphi,cpsi,cgamma; double alpha, beta, theta, phi, psi;
double xlo, xhi,xmin,xmax;
typedef double (FGInitialCondition::*fp)(double x);
fp sfunc;
speedset lastSpeedSet; speedset lastSpeedSet;
windset lastWindSet;
FGFDMExec *fdmex; FGFDMExec *fdmex;
FGPropertyManager *PropertyManager; FGPropertyManager *PropertyManager;
@ -651,20 +656,16 @@ private:
bool Load_v2(void); bool Load_v2(void);
bool Constructing; bool Constructing;
bool getAlpha(void);
bool getTheta(void);
bool getMachFromVcas(double *Mach,double vcas);
double GammaEqOfTheta(double Theta);
void InitializeIC(void); void InitializeIC(void);
double GammaEqOfAlpha(double Alpha); void SetBodyVelFpsIC(int idx, double vel);
double calcVcas(double Mach); void SetNEDVelFpsIC(int idx, double vel);
void calcUVWfromNED(void); double GetBodyWindFpsIC(int idx) const;
void calcWindUVW(void); double GetNEDWindFpsIC(int idx) const;
void calcAeroEuler(void); double GetBodyVelFpsIC(int idx) const;
double getMachFromVcas(double vcas);
bool findInterval(double x,double guess); double calcVcas(double Mach) const;
bool solve(double *y, double x); void calcAeroAngles(const FGColumnVector3& _vt_BODY);
void bind(void); void bind(void);
void Debug(int from); void Debug(int from);

View file

@ -54,7 +54,7 @@ using namespace std;
namespace JSBSim { 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; static const char *IdHdr = ID_FGSCRIPT;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -266,8 +266,9 @@ bool FGScript::LoadScript(string script, double deltaT)
} else { } else {
cout << endl << fgred << " Could not find the property named " cout << endl << fgred << " Could not find the property named "
<< notifyPropertyName << " in script" << endl << " \"" << notifyPropertyName << " in script" << endl << " \""
<< ScriptName << "\". This unknown property will not be " << ScriptName << "\". Execution is aborted. Please recheck "
<< "echoed for notification." << reset << endl; << "your input files and scripts." << reset << endl;
return false;
} }
notify_property_element = notify_element->FindNextElement("property"); notify_property_element = notify_element->FindNextElement("property");
} }

View file

@ -47,7 +47,7 @@ using namespace std;
namespace JSBSim { 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; static const char *IdHdr = ID_COLUMNVECTOR3;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -125,47 +125,11 @@ FGColumnVector3& FGColumnVector3::Normalize(void)
return *this; 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) double FGColumnVector3::Magnitude(const int idx1, const int idx2) const {
{ return sqrt( data[idx1-1]*data[idx1-1] + data[idx2-1]*data[idx2-1] );
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;
}
}
} }
} // namespace JSBSim } // namespace JSBSim

View file

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

View file

@ -48,7 +48,7 @@ using namespace std;
namespace JSBSim { 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; 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[0] = data[1] = data[2] = data[3] = data[4] = data[5] =
data[6] = data[7] = data[8] = 0.0; 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 ); 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 <iosfwd>
#include "FGColumnVector3.h" #include "FGColumnVector3.h"
#include "FGJSBBase.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS 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 FORWARD DECLARATIONS
@ -72,7 +71,7 @@ CLASS DOCUMENTATION
DECLARATION: MatrixException DECLARATION: MatrixException
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class MatrixException : public FGJSBBase class MatrixException //: public FGJSBBase
{ {
public: public:
std::string Message; std::string Message;
@ -90,7 +89,7 @@ CLASS DOCUMENTATION
DECLARATION: FGMatrix33 DECLARATION: FGMatrix33
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGMatrix33 : public FGJSBBase class FGMatrix33
{ {
public: public:
@ -122,8 +121,6 @@ public:
data[6] = M.data[6]; data[6] = M.data[6];
data[7] = M.data[7]; data[7] = M.data[7];
data[8] = M.data[8]; data[8] = M.data[8];
// Debug(0);
} }
/** Initialization by given values. /** Initialization by given values.
@ -140,9 +137,10 @@ public:
Create a matrix from the doubles given in the arguments. Create a matrix from the doubles given in the arguments.
*/ */
FGMatrix33(double m11, double m12, double m13, FGMatrix33(const double m11, const double m12, const double m13,
double m21, double m22, double m23, const double m21, const double m22, const double m23,
double m31, double m32, double m33) { const double m31, const double m32, const double m33)
{
data[0] = m11; data[0] = m11;
data[1] = m21; data[1] = m21;
data[2] = m31; data[2] = m31;
@ -152,13 +150,11 @@ public:
data[6] = m13; data[6] = m13;
data[7] = m23; data[7] = m23;
data[8] = m33; data[8] = m33;
// Debug(0);
} }
/** Destructor. /** Destructor.
*/ */
~FGMatrix33(void) { /* Debug(1); */ } ~FGMatrix33(void) {}
/** Prints the contents of the matrix. /** Prints the contents of the matrix.
@param delimeter the item separator (tab or comma) @param delimeter the item separator (tab or comma)
@ -263,9 +259,10 @@ public:
/** Initialize the matrix. /** Initialize the matrix.
This function initializes a matrix to user specified values. This function initializes a matrix to user specified values.
*/ */
void InitMatrix(double m11, double m12, double m13, void InitMatrix(const double m11, const double m12, const double m13,
double m21, double m22, double m23, const double m21, const double m22, const double m23,
double m31, double m32, double m33) { const double m31, const double m32, const double m33)
{
data[0] = m11; data[0] = m11;
data[1] = m21; data[1] = m21;
data[2] = m31; data[2] = m31;
@ -309,7 +306,8 @@ public:
Copy the content of the matrix given in the argument into *this. 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[0] = A.data[0];
data[1] = A.data[1]; data[1] = A.data[1];
data[2] = A.data[2]; data[2] = A.data[2];
@ -434,8 +432,6 @@ public:
private: private:
double data[eRows*eColumns]; double data[eRows*eColumns];
void Debug(int from);
}; };
/** Scalar multiplication. /** Scalar multiplication.

View file

@ -57,7 +57,7 @@ using std::endl;
namespace JSBSim { 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; static const char *IdHdr = ID_QUATERNION;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -254,55 +254,14 @@ void FGQuaternion::ComputeDerivedUnconditional(void) const
mEulerCosines(ePhi) = cos(mEulerAngles(ePhi)); mEulerCosines(ePhi) = cos(mEulerAngles(ePhi));
mEulerCosines(eTht) = cos(mEulerAngles(eTht)); mEulerCosines(eTht) = cos(mEulerAngles(eTht));
mEulerCosines(ePsi) = cos(mEulerAngles(ePsi)); 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; os << q(1) << " , " << q(2) << " , " << q(3) << " , " << q(4);
return os;
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;
}
}
} }
} // namespace JSBSim } // namespace JSBSim

View file

@ -47,7 +47,7 @@ SENTRY
DEFINITIONS 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 { namespace JSBSim {
@ -88,7 +88,7 @@ class FGMatrix33;
CLASS DECLARATION CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGQuaternion : virtual FGJSBBase { class FGQuaternion : public FGJSBBase {
public: public:
/** Default initializer. /** Default initializer.
Default initializer, initializes the class with the identity rotation. */ Default initializer, initializes the class with the identity rotation. */
@ -293,10 +293,10 @@ public:
@return reference to a quaternion object */ @return reference to a quaternion object */
const FGQuaternion& operator=(const FGQuaternion& q) { const FGQuaternion& operator=(const FGQuaternion& q) {
// Copy the master values ... // Copy the master values ...
data[0] = q(1); data[0] = q.data[0];
data[1] = q(2); data[1] = q.data[1];
data[2] = q(3); data[2] = q.data[2];
data[3] = q(4); data[3] = q.data[3];
ComputeDerived(); ComputeDerived();
// .. and copy the derived values if they are valid // .. and copy the derived values if they are valid
mCacheValid = q.mCacheValid; mCacheValid = q.mCacheValid;
@ -317,8 +317,8 @@ public:
@param q a quaternion reference @param q a quaternion reference
@return true if both quaternions represent the same rotation. */ @return true if both quaternions represent the same rotation. */
bool operator==(const FGQuaternion& q) const { bool operator==(const FGQuaternion& q) const {
return data[0] == q(1) && data[1] == q(2) return data[0] == q.data[0] && data[1] == q.data[1]
&& data[2] == q(3) && data[3] == q(4); && data[2] == q.data[2] && data[3] == q.data[3];
} }
/** Comparison operator "!=". /** Comparison operator "!=".
@ -327,10 +327,10 @@ public:
bool operator!=(const FGQuaternion& q) const { return ! operator==(q); } bool operator!=(const FGQuaternion& q) const { return ! operator==(q); }
const FGQuaternion& operator+=(const FGQuaternion& q) { const FGQuaternion& operator+=(const FGQuaternion& q) {
// Copy the master values ... // Copy the master values ...
data[0] += q(1); data[0] += q.data[0];
data[1] += q(2); data[1] += q.data[1];
data[2] += q(3); data[2] += q.data[2];
data[3] += q(4); data[3] += q.data[3];
mCacheValid = false; mCacheValid = false;
return *this; return *this;
} }
@ -340,10 +340,10 @@ public:
@return a quaternion reference representing Q, where Q = Q - q. */ @return a quaternion reference representing Q, where Q = Q - q. */
const FGQuaternion& operator-=(const FGQuaternion& q) { const FGQuaternion& operator-=(const FGQuaternion& q) {
// Copy the master values ... // Copy the master values ...
data[0] -= q(1); data[0] -= q.data[0];
data[1] -= q(2); data[1] -= q.data[1];
data[2] -= q(3); data[2] -= q.data[2];
data[3] -= q(4); data[3] -= q.data[3];
mCacheValid = false; mCacheValid = false;
return *this; return *this;
} }
@ -371,16 +371,16 @@ public:
@param q a quaternion to be summed. @param q a quaternion to be summed.
@return a quaternion representing Q, where Q = Q + q. */ @return a quaternion representing Q, where Q = Q + q. */
FGQuaternion operator+(const FGQuaternion& q) const { FGQuaternion operator+(const FGQuaternion& q) const {
return FGQuaternion(data[0]+q(1), data[1]+q(2), return FGQuaternion(data[0]+q.data[0], data[1]+q.data[1],
data[2]+q(3), data[3]+q(4)); data[2]+q.data[2], data[3]+q.data[3]);
} }
/** Arithmetic operator "-". /** Arithmetic operator "-".
@param q a quaternion to be subtracted. @param q a quaternion to be subtracted.
@return a quaternion representing Q, where Q = Q - q. */ @return a quaternion representing Q, where Q = Q - q. */
FGQuaternion operator-(const FGQuaternion& q) const { FGQuaternion operator-(const FGQuaternion& q) const {
return FGQuaternion(data[0]-q(1), data[1]-q(2), return FGQuaternion(data[0]-q.data[0], data[1]-q.data[1],
data[2]-q(3), data[3]-q(4)); data[2]-q.data[2], data[3]-q.data[3]);
} }
/** Arithmetic operator "*". /** Arithmetic operator "*".
@ -388,10 +388,10 @@ public:
@param q a quaternion to be multiplied. @param q a quaternion to be multiplied.
@return a quaternion representing Q, where Q = Q * q. */ @return a quaternion representing Q, where Q = Q * q. */
FGQuaternion operator*(const FGQuaternion& q) const { 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],
data[0]*q(2)+data[1]*q(1)+data[2]*q(4)-data[3]*q(3), data[0]*q.data[1]+data[1]*q.data[0]+data[2]*q.data[3]-data[3]*q.data[2],
data[0]*q(3)-data[1]*q(4)+data[2]*q(1)+data[3]*q(2), data[0]*q.data[2]-data[1]*q.data[3]+data[2]*q.data[0]+data[3]*q.data[1],
data[0]*q(4)+data[1]*q(3)-data[2]*q(2)+data[3]*q(1)); data[0]*q.data[3]+data[1]*q.data[2]-data[2]*q.data[1]+data[3]*q.data[0]);
} }
/** Arithmetic operator "*=". /** Arithmetic operator "*=".
@ -399,10 +399,10 @@ public:
@param q a quaternion to be multiplied. @param q a quaternion to be multiplied.
@return a quaternion reference representing Q, where Q = Q * q. */ @return a quaternion reference representing Q, where Q = Q * q. */
const FGQuaternion& operator*=(const FGQuaternion& 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 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(2)+data[1]*q(1)+data[2]*q(4)-data[3]*q(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(3)-data[1]*q(4)+data[2]*q(1)+data[3]*q(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(4)+data[1]*q(3)-data[2]*q(2)+data[3]*q(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[0] = q0;
data[1] = q1; data[1] = q1;
data[2] = q2; data[2] = q2;
@ -506,8 +506,6 @@ private:
mutable FGColumnVector3 mEulerSines; mutable FGColumnVector3 mEulerSines;
mutable FGColumnVector3 mEulerCosines; mutable FGColumnVector3 mEulerCosines;
void Debug(int from) const;
void InitializeFromEulerAngles(double phi, double tht, double psi); void InitializeFromEulerAngles(double phi, double tht, double psi);
}; };
@ -519,9 +517,15 @@ private:
Multiply the Vector with a scalar value. Multiply the Vector with a scalar value.
*/ */
inline FGQuaternion operator*(double scalar, const FGQuaternion& q) { 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 } // namespace JSBSim
#include "FGMatrix33.h" #include "FGMatrix33.h"

View file

@ -52,7 +52,7 @@ using namespace std;
namespace JSBSim { 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; static const char *IdHdr = ID_AERODYNAMICS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -388,23 +388,28 @@ void FGAerodynamics::DetermineAxisSystem()
string axis; string axis;
while (axis_element) { while (axis_element) {
axis = axis_element->GetAttributeValue("name"); axis = axis_element->GetAttributeValue("name");
if (axis == "LIFT" || axis == "DRAG" || axis == "SIDE") { if (axis == "LIFT" || axis == "DRAG") {
if (axisType == atNone) axisType = atLiftDrag; if (axisType == atNone) axisType = atLiftDrag;
else if (axisType != atLiftDrag) { else if (axisType != atLiftDrag) {
cerr << endl << " Mixed aerodynamic axis systems have been used in the" 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") { } else if (axis == "AXIAL" || axis == "NORMAL") {
if (axisType == atNone) axisType = atAxialNormal; if (axisType == atNone) axisType = atAxialNormal;
else if (axisType != atAxialNormal) { else if (axisType != atAxialNormal) {
cerr << endl << " Mixed aerodynamic axis systems have been used in the" 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") { } else if (axis == "X" || axis == "Y" || axis == "Z") {
if (axisType == atNone) axisType = atBodyXYZ; if (axisType == atNone) axisType = atBodyXYZ;
else if (axisType != atBodyXYZ) { else if (axisType != atBodyXYZ) {
cerr << endl << " Mixed aerodynamic axis systems have been used in the" 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 } else if (axis != "ROLL" && axis != "PITCH" && axis != "YAW") { // error
cerr << endl << " An unknown axis type, " << axis << " has been specified" cerr << endl << " An unknown axis type, " << axis << " has been specified"

View file

@ -53,7 +53,7 @@ using std::max;
namespace JSBSim { 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; 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); base_property_name = CreateIndexedPropertyName("buoyant_forces/gas-cell", CellNum);
property_name = base_property_name + "/max_volume-ft3"; 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 ); PropertyManager->SetWritable( property_name, false );
property_name = base_property_name + "/temp-R"; 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"; 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"; 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"; 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"; 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"; property_name = base_property_name + "/valve_open";
PropertyManager->Tie( property_name.c_str(), &ValveOpen ); PropertyManager->Tie( property_name.c_str(), &ValveOpen, false );
Debug(0); 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); base_property_name = CreateIndexedPropertyName(base_property_name + "/ballonet", CellNum);
property_name = base_property_name + "/max_volume-ft3"; property_name = base_property_name + "/max_volume-ft3";
PropertyManager->Tie( property_name, &MaxVolume ); PropertyManager->Tie( property_name, &MaxVolume, false );
PropertyManager->SetWritable( property_name, false ); PropertyManager->SetWritable( property_name, false );
property_name = base_property_name + "/temp-R"; 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"; 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"; 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"; 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"; property_name = base_property_name + "/valve_open";
PropertyManager->Tie( property_name, &ValveOpen ); PropertyManager->Tie( property_name, &ValveOpen, false );
Debug(0); Debug(0);

View file

@ -71,7 +71,7 @@ using namespace std;
namespace JSBSim { 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; static const char *IdHdr = ID_PROPAGATE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -157,8 +157,8 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle()); VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle());
Ti2ec = GetTi2ec(); // ECI to ECEF transform Ti2ec = VState.vLocation.GetTi2ec(); // ECI to ECEF transform
Tec2i = Ti2ec.Transposed(); // ECEF to ECI frame transform Tec2i = Ti2ec.Transposed(); // ECEF to ECI frame transform
VState.vInertialPosition = Tec2i * VState.vLocation; VState.vInertialPosition = Tec2i * VState.vLocation;
@ -260,8 +260,8 @@ bool FGPropagate::Run(void)
VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle()); VState.vLocation.SetEarthPositionAngle(FDMExec->GetInertial()->GetEarthPositionAngle());
// 2. Update the Ti2ec and Tec2i transforms from the updated EPA // 2. Update the Ti2ec and Tec2i transforms from the updated EPA
Ti2ec = GetTi2ec(); // ECI to ECEF transform Ti2ec = VState.vLocation.GetTi2ec(); // ECI to ECEF transform
Tec2i = Ti2ec.Transposed(); // ECEF to ECI frame transform Tec2i = Ti2ec.Transposed(); // ECEF to ECI frame transform
// 3. Update the location from the updated Ti2ec and inertial position // 3. Update the location from the updated Ti2ec and inertial position
VState.vLocation = Ti2ec*VState.vInertialPosition; VState.vLocation = Ti2ec*VState.vInertialPosition;
@ -561,7 +561,7 @@ void FGPropagate::ResolveFrictionForces(double dt)
// Prepare the linear system for the Gauss-Seidel algorithm : // Prepare the linear system for the Gauss-Seidel algorithm :
// 1. Compute the right hand side member 'rhs' // 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. // a division computation at each iteration of Gauss-Seidel.
for (int i=0; i < n; i++) { for (int i=0; i < n; i++) {
double d = 1.0 / a[i*n+i]; double d = 1.0 / a[i*n+i];
@ -619,22 +619,22 @@ void FGPropagate::ResolveFrictionForces(double dt)
void FGPropagate::UpdateLocationMatrices(void) void FGPropagate::UpdateLocationMatrices(void)
{ {
Tl2ec = GetTl2ec(); // local to ECEF transform Tl2ec = VState.vLocation.GetTl2ec(); // local to ECEF transform
Tec2l = Tl2ec.Transposed(); // ECEF to local frame transform Tec2l = Tl2ec.Transposed(); // ECEF to local frame transform
Ti2l = GetTi2l(); Ti2l = VState.vLocation.GetTi2l(); // ECI to local frame transform
Tl2i = Ti2l.Transposed(); Tl2i = Ti2l.Transposed(); // local to ECI transform
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::UpdateBodyMatrices(void) void FGPropagate::UpdateBodyMatrices(void)
{ {
Ti2b = GetTi2b(); // ECI to body frame transform Ti2b = VState.qAttitudeECI.GetT(); // ECI to body frame transform
Tb2i = Ti2b.Transposed(); // body to ECI frame transform Tb2i = Ti2b.Transposed(); // body to ECI frame transform
Tl2b = Ti2b*Tl2i; // local to body frame transform Tl2b = Ti2b*Tl2i; // local to body frame transform
Tb2l = Tl2b.Transposed(); // body to local frame transform Tb2l = Tl2b.Transposed(); // body to local frame transform
Tec2b = Tl2b * Tec2l; // ECEF to body frame transform Tec2b = Tl2b * Tec2l; // ECEF to body frame transform
Tb2ec = Tec2b.Transposed(); // body to ECEF frame tranform Tb2ec = Tec2b.Transposed(); // body to ECEF frame tranform
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -651,7 +651,7 @@ void FGPropagate::SetInertialOrientation(FGQuaternion Qi) {
void FGPropagate::SetInertialVelocity(FGColumnVector3 Vi) { void FGPropagate::SetInertialVelocity(FGColumnVector3 Vi) {
VState.vInertialVelocity = Vi; VState.vInertialVelocity = Vi;
CalculateUVW(); CalculateUVW();
vVel = GetTb2l() * VState.vUVW; vVel = Tb2l * VState.vUVW;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -715,36 +715,6 @@ double FGPropagate::GetTerrainElevation(void) const
return FDMExec->GetGroundCallback()->GetTerrainGeoCentRadius()-SeaLevelRadius; 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 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 cout << endl << " " << underon
<< "Velocity" << underoff << endl; << "Velocity" << underoff << endl;
cout << " ECI: " << VState.vInertialVelocity.Dump(", ") << " (x,y,z in ft/s)" << 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 << " Local: " << GetVel() << " (n,e,d in ft/sec)" << endl;
cout << " Body: " << GetUVW() << " (u,v,w in ft/sec)" << endl; cout << " Body: " << GetUVW() << " (u,v,w in ft/sec)" << endl;

View file

@ -49,7 +49,7 @@ INCLUDES
DEFINITIONS 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 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.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 units feet
@return distance of the local terrain from the center of the earth. @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 GetSeaLevelRadius(void) const { return SeaLevelRadius; }
double GetTerrainElevation(void) const; double GetTerrainElevation(void) const;
@ -466,13 +466,13 @@ public:
The quaternion class, being the means by which the orientation of the The quaternion class, being the means by which the orientation of the
vehicle is stored, manages the local-to-body transformation matrix. vehicle is stored, manages the local-to-body transformation matrix.
@return a reference to 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. /** Retrieves the body-to-local transformation matrix.
The quaternion class, being the means by which the orientation of the The quaternion class, being the means by which the orientation of the
vehicle is stored, manages the body-to-local transformation matrix. vehicle is stored, manages the body-to-local transformation matrix.
@return a reference to the body-to-local 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. /** Retrieves the ECEF-to-body transformation matrix.
@return a reference to 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. /** Retrieves the ECI-to-body transformation matrix.
@return a reference to 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. /** Retrieves the body-to-ECI transformation matrix.
@return a reference to the body-to-ECI 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. /** Retrieves the ECEF-to-ECI transformation matrix.
@return a reference to 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. /** Retrieves the ECI-to-ECEF transformation matrix.
@return a reference to the ECI-to-ECEF 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.
Retrieves the ECEF-to-local transformation matrix. Note that the so-called 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). local from is also know as the NED frame (for North, East, Down).
@return a reference to the ECEF-to-local matrix. */ @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.
Retrieves the local-to-ECEF transformation matrix. Note that the so-called 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). local from is also know as the NED frame (for North, East, Down).
@return a reference to the local-to-ECEF matrix. */ @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. /** Retrieves the local-to-inertial transformation matrix.
@return a reference to 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. /** Retrieves the inertial-to-local transformation matrix.
@return a reference to the inertial-to-local 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) { void SetVState(const 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 InitializeDerivatives(void); void InitializeDerivatives(void);
@ -554,50 +542,46 @@ public:
// SET functions // SET functions
void SetLongitude(double lon) { void SetLongitude(double lon)
VState.vLocation.SetLongitude(lon); {
VState.vInertialPosition = GetTec2i() * VState.vLocation; VState.vLocation.SetLongitude(lon);
UpdateLocationMatrices(); UpdateVehicleState();
} }
void SetLongitudeDeg(double lon) { SetLongitude(lon*degtorad); } void SetLongitudeDeg(double lon) { SetLongitude(lon*degtorad); }
void SetLatitude(double lat) { void SetLatitude(double lat)
VState.vLocation.SetLatitude(lat); {
VState.vInertialPosition = GetTec2i() * VState.vLocation; VState.vLocation.SetLatitude(lat);
UpdateLocationMatrices(); UpdateVehicleState();
} }
void SetLatitudeDeg(double lat) { SetLatitude(lat*degtorad); } void SetLatitudeDeg(double lat) { SetLatitude(lat*degtorad); }
void SetRadius(double r) { void SetRadius(double r)
VState.vLocation.SetRadius(r); {
VState.vInertialPosition = GetTec2i() * VState.vLocation; VState.vLocation.SetRadius(r);
UpdateLocationMatrices(); VehicleRadius = r;
VState.vInertialPosition = Tec2i * VState.vLocation;
} }
void SetAltitudeASL(double altASL); void SetAltitudeASL(double altASL) { SetRadius(altASL + SeaLevelRadius); }
void SetAltitudeASLmeters(double altASL) {SetAltitudeASL(altASL/fttom);} void SetAltitudeASLmeters(double altASL) { SetRadius(altASL/fttom + SeaLevelRadius); }
void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; } void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; }
void SetTerrainElevation(double tt); void SetTerrainElevation(double tt);
void SetDistanceAGL(double tt); void SetDistanceAGL(double tt) { SetRadius(tt + LocalTerrainRadius); }
void SetInitialState(const FGInitialCondition *); void SetInitialState(const FGInitialCondition *);
void SetPosition(const double Lon, const double Lat, const double Radius) { void SetLocation(const FGLocation& l);
VState.vLocation.SetPosition(Lon, Lat, Radius); void SetLocation(const FGColumnVector3& lv)
VState.vInertialPosition = GetTec2i() * VState.vLocation; {
VehicleRadius = GetRadius(); FGLocation l = FGLocation(lv);
UpdateLocationMatrices(); SetLocation(l);
} }
void SetLocation(const FGLocation& l) { void SetPosition(const double Lon, const double Lat, const double Radius)
VState.vLocation = l; {
VState.vInertialPosition = GetTec2i() * VState.vLocation; FGLocation l = FGLocation(Lon, Lat, Radius);
UpdateLocationMatrices(); SetLocation(l);
}
void SetLocation(const FGColumnVector3& l) {
VState.vLocation = l;
VState.vInertialPosition = GetTec2i() * VState.vLocation;
UpdateLocationMatrices();
} }
void RecomputeLocalTerrainRadius(void); void RecomputeLocalTerrainRadius(void);
void NudgeBodyLocation(FGColumnVector3 deltaLoc) { void NudgeBodyLocation(FGColumnVector3 deltaLoc) {
vDeltaXYZEC = GetTb2ec()*deltaLoc; vDeltaXYZEC = Tb2ec*deltaLoc;
VState.vLocation -= vDeltaXYZEC; VState.vLocation -= vDeltaXYZEC;
} }
@ -678,13 +662,11 @@ private:
void UpdateLocationMatrices(void); void UpdateLocationMatrices(void);
void UpdateBodyMatrices(void); void UpdateBodyMatrices(void);
void UpdateVehicleState(void);
void bind(void); void bind(void);
void Debug(int from); void Debug(int from);
}; };
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#include "initialization/FGInitialCondition.h"
#endif #endif

View file

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

View file

@ -49,7 +49,7 @@ using namespace std;
namespace JSBSim { 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; 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; if (Tank->GetContents() > 0.0 && Tank->GetSelected() && SourceTanks[i] > 0) ++TanksWithFuel;
break; break;
case FGTank::ttOXIDIZER: case FGTank::ttOXIDIZER:
if (Tank->GetContents() > 0.0 && Tank->GetSelected() && SourceTanks[i] > 0) { if (Tank->GetSelected() && SourceTanks[i] > 0) {
haveOxTanks = true; haveOxTanks = true;
++TanksWithOxidizer; if (Tank->GetContents() > 0.0) ++TanksWithOxidizer;
} }
break; break;
} }

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
Author: T. Kreitler Author: T. Kreitler
Date started: 08/24/00 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 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 the terms of the GNU Lesser General Public License as published by the Free Software
@ -26,6 +26,7 @@
HISTORY HISTORY
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
01/01/10 T.Kreitler test implementation 01/01/10 T.Kreitler test implementation
01/10/11 T.Kreitler changed to single rotor model
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY SENTRY
@ -39,14 +40,12 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGThruster.h" #include "FGThruster.h"
#include "math/FGTable.h"
#include "math/FGRungeKutta.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS 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 FORWARD DECLARATIONS
@ -58,58 +57,35 @@ namespace JSBSim {
CLASS DOCUMENTATION CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Models a rotor system. The default configuration consists of main and /** Models a helicopter rotor.
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).
<h3>Configuration File Format:</h3> <h3>Configuration File Format</h3>
@code @code
<rotor name="{string}" variant="{string}"> <rotor name="{string}">
<diameter unit="{LENGTH}"> {number} </diameter> <diameter unit="{LENGTH}"> {number} </diameter>
<numblades> {number} </numblades> <numblades> {number} </numblades>
<xhub unit="{LENGTH}"> {number} </xhub> <gearratio> {number} </gearratio>
<zhub unit="{LENGTH}"> {number} </zhub>
<nominalrpm> {number} </nominalrpm> <nominalrpm> {number} </nominalrpm>
<minrpm> {number} </minrpm>
<chord unit="{LENGTH}"> {number} </chord> <chord unit="{LENGTH}"> {number} </chord>
<liftcurveslope Xunit="1/RAD"> {number} </liftcurveslope> <liftcurveslope Xunit="1/RAD"> {number} </liftcurveslope>
<flappingmoment unit="{MOMENT}"> {number} </flappingmoment>
<twist unit="{ANGLE}"> {number} </twist> <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> <hingeoffset unit="{LENGTH}"> {number} </hingeoffset>
<tailrotor> <flappingmoment unit="{MOMENT}"> {number} </flappingmoment>
<diameter unit="{LENGTH}"> {number} </diameter> <massmoment Xunit="SLUG*FT"> {number} </massmoment>
<numblades> {number} </numblades> <polarmoment unit="{MOMENT}"> {number} </polarmoment>
<xhub unit="{LENGTH}">{number} </xhub> <inflowlag> {number} </inflowlag>
<zhub unit="{LENGTH}">{number} </zhub> <tiplossfactor> {number} </tiplossfactor>
<nominalrpm> {number} </nominalrpm>
<chord unit="{LENGTH}"> {number} </chord> <controlmap> {MAIN|TAIL|TANDEM} </controlmap>
<liftcurveslope Xunit="1/RAD"> {number} </liftcurveslope> <ExternalRPM> {number} </ExternalRPM>
<flappingmoment unit="{MOMENT}"> {number} </flappingmoment>
<twist unit="RAD"> {number} </twist> <groundeffectexp> {number} </groundeffectexp>
<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>
<groundeffectshift unit="{LENGTH}"> {number} </groundeffectshift> <groundeffectshift unit="{LENGTH}"> {number} </groundeffectshift>
</rotor> </rotor>
// LENGTH means any of the supported units, same for ANGLE and MOMENT. // 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. // values must be provided accordingly.
@endcode @endcode
@ -119,67 +95,87 @@ CLASS DOCUMENTATION
Brief description and the symbol frequently found in the literature. Brief description and the symbol frequently found in the literature.
<pre> <pre>
\<diameter> - Rotor disk diameter (R). \<diameter> - Rotor disk diameter (2x R).
\<numblades> - Number of blades (b). \<numblades> - Number of blades (b).
\<xhub> - Relative height in body coordinate system, thus usually negative. \<gearratio> - Ratio of (engine rpm) / (rotor rpm), usually > 1.
\<zhub> - Relative distance in body coordinate system, close to zero
for main rotor, and usually negative for the tail rotor.
\<nominalrpm> - RPM at which the rotor usally operates. \<nominalrpm> - RPM at which the rotor usally operates.
\<minrpm> - Lowest RPM generated by the code, optional.
\<chord> - Blade chord, (c). \<chord> - Blade chord, (c).
\<liftcurveslope> - Slope of curve of section lift against section angle of attack, \<liftcurveslope> - Slope of curve of section lift against section angle of attack,
per rad (a). per rad (a).
\<flappingmoment> - Flapping moment of inertia (I_b).
\<twist> - Blade twist from root to tip, (theta_1). \<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. \<tiplossfactor> - Tip-loss factor. The Blade fraction that produces lift.
Value usually ranges between 0.95 - 1.0, optional (B). 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. \<controlmap> - Defines the control inputs used (see notes).
\<shafttilt> - Orientation of the rotor shaft, negative angles define \<ExternalRPM> - Links the rotor to another rotor, or an user controllable property.
a 'forward' tilt. Used by main rotor, optional.
\<hingeoffset> - Rotor flapping-hinge offset (e).
Experimental properties Experimental properties
\<cantangle> - Flapping hinge cantangle used by tail rotor, optional. \<groundeffectexp> - Exponent for ground effect approximation. Values usually range from 0.04
\<cgroundeffect> - Parameter for exponent in ground effect approximation. Value should for large rotors to 0.1 for smaller ones. As a rule of thumb the effect
be in the range 0.2 - 0.35, 0.0 disables, optional. vanishes at a height 2-3 times the rotor diameter.
\<groundeffectshift> - Further adjustment of ground effect. 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> </pre>
<h3>Notes:</h3> <h3>Notes:</h3>
The behavior of the rotor is controlled/influenced by 5 inputs.<ul> <h4>- Controls -</h4>
<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>
</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 <h4>- Tail/tandem rotor -</h4>
and zhub are no longer aligned to the body frame and need proper recalculation.
To model a standalone main rotor just omit the <tailrotor/> element. If you provide Providing <tt>\<ExternalRPM\> 0 \</ExternalRPM\></tt> the tail rotor's RPM
a plain <tailrotor/> element all tail rotor parameters are estimated. is linked to to the main (=first, =0) rotor, and specifing
<tt>\<controlmap\> TAIL \</controlmap\></tt> tells this rotor to read the
The 'sense' parameter from the thruster is interpreted as follows, sense=1 means collective input from <tt>propulsion/engine[1]/antitorque-ctrl-rad</tt>
counter clockwise rotation of the main rotor, as viewed from above. This is as a far (The TAIL-map ignores lateral and longitudinal input). The rotor needs to be
as I know more popular than clockwise rotation, which is defined by setting sense to attached to a dummy engine, e.g. an 1HP electrical engine.
-1 (to be honest, I'm just 99.9% sure that the orientation is handled properly). A tandem rotor is setup analogous.
Concerning coaxial designs: By providing the 'variant' attribute with value 'coaxial'
a Kamov-style rotor is modeled - i.e. the rotor produces no torque.
<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> <h3>References:</h3>
@ -196,147 +192,90 @@ CLASS DOCUMENTATION
</dl> </dl>
@author Thomas Kreitler @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 DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGRotor : public FGThruster { 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;
};
enum eCtrlMapping {eMainCtrl=0, eTailCtrl, eTandemCtrl};
public: public:
/** Constructor
@param exec pointer to executive structure /** Constructor for FGRotor.
@param rotor_element pointer to XML element in the config file @param exec a pointer to the main executive object
@param num the number of this rotor */ @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); FGRotor(FGFDMExec *exec, Element* rotor_element, int num);
/// Destructor /// Destructor for FGRotor
~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 /** Returns the scalar thrust of the rotor, and adjusts the RPM value. */
vFn,vMn state variables. RPM changes are handled inside, too. double Calculate(double PowerAvailable);
The RPM change is based on estimating the torque provided by the engine.
@param PowerAvailable here this is the thrust (not power) provided by a turbine
@return PowerAvailable */
double Calculate(double);
double GetRPM(void) const { return RPM; } /// Retrieves the RPMs of the rotor.
double GetDiameter(void) { return mr.Radius*2.0; } 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. /// Retrieves the rotor's coning angle
double GetTorque(void) { return 0.0; /* return mr.Torque;*/ } double GetA0(void) const { return a0; }
double GetPowerRequired(void); /// 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 // Stubs. Only main rotor RPM is returned
string GetThrusterLabels(int id, string delimeter); string GetThrusterLabels(int id, string delimeter);
@ -344,59 +283,105 @@ public:
private: 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 ConfigValue( Element* e, const string& ename, double default_val=0.0,
double Sense; // default is counter clockwise rotation of the main rotor (viewed from above) bool tell=false);
bool tailRotorPresent;
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); void Debug(int from);
FGPropertyManager* PropertyManager; // environment
double dt;
rotor mr; double rho;
rotor tr;
Filter damp_hagl; Filter damp_hagl;
double rho; // configuration parameters
double Radius;
double effective_tail_col; // /SH79/ eqn(47) int BladeNum;
double ground_effect_exp; double Sense;
double ground_effect_shift; double NominalRPM;
int ExternalRPM;
int RPMdefinition;
FGPropertyManager* ExtRPMsource;
double hover_threshold; double BladeChord;
double hover_scale; double LiftCurveSlope;
double BladeTwist;
double HingeOffset;
double BladeFlappingMoment;
double BladeMassMoment;
double PolarMoment;
double InflowLag;
double TipLossB;
// fdm imported controls double GroundEffectExp;
FGPropertyManager* prop_collective_ctrl; double GroundEffectShift;
FGPropertyManager* prop_lateral_ctrl;
FGPropertyManager* prop_longitudinal_ctrl;
FGPropertyManager* prop_antitorque_ctrl;
FGPropertyManager* prop_freewheel_factor; // derived parameters
FGPropertyManager* prop_rotorbrake; double LockNumberByRho;
double Solidity; // aka sigma
double R[5]; // Radius powers
double B[5]; // TipLossB powers
// fdm export ... // Some of the calculations require shaft axes. So the
double prop_inflow_ratio_lambda; // thruster orientation (Tbo, with b for body) needs to be
double prop_advance_ratio_mu; // expressed/represented in helicopter shaft coordinates (Hsr).
double prop_inflow_ratio_induced_nu; FGMatrix33 InvTransform;
double prop_mr_torque; FGMatrix33 TboToHsr;
double prop_coning_angle; FGMatrix33 HsrToTbo;
double prop_theta_downwash; // dynamic values
double prop_phi_downwash; 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 Torque;
double prop_lift_coefficient; 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 // control
int prop_DumpFlag; // causes 1-time dump on stdout eCtrlMapping ControlMap;
double CollectiveCtrl;
double LateralCtrl;
double LongitudinalCtrl;
}; };
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif #endif

View file

@ -83,9 +83,15 @@ public:
--destIndex; --destIndex;
} }
int currentWpIndex = currentWaypoint();
WayptRef w(_rm->removeWayptAtIndex(srcIndex)); WayptRef w(_rm->removeWayptAtIndex(srcIndex));
SG_LOG(SG_GENERAL, SG_INFO, "wpt:" << w->ident()); SG_LOG(SG_GENERAL, SG_INFO, "wpt:" << w->ident());
_rm->insertWayptAtIndex(w, destIndex); _rm->insertWayptAtIndex(w, destIndex);
if (srcIndex == currentWpIndex) {
// current waypoint was moved
_rm->jumpToIndex(destIndex);
}
} }
virtual void setUpdateCallback(SGCallback* cb) virtual void setUpdateCallback(SGCallback* cb)

View file

@ -311,6 +311,7 @@ void FGLinuxInputDevice::Open()
continue; continue;
} }
absinfo[i] = ai; absinfo[i] = ai;
/*
SG_LOG( SG_INPUT, SG_INFO, "Axis #" << i << SG_LOG( SG_INPUT, SG_INFO, "Axis #" << i <<
": value=" << ai.value << ": value=" << ai.value <<
": minimum=" << ai.minimum << ": minimum=" << ai.minimum <<
@ -318,6 +319,7 @@ void FGLinuxInputDevice::Open()
": fuzz=" << ai.fuzz << ": fuzz=" << ai.fuzz <<
": flat=" << ai.flat << ": flat=" << ai.flat <<
": resolution=" << ai.resolution ); ": resolution=" << ai.resolution );
*/
// kick an initial event // kick an initial event
struct input_event event; struct input_event event;

View file

@ -1158,7 +1158,7 @@ double GPS::getWP1Bearing() const
double GPS::getWP1MagBearing() const double GPS::getWP1MagBearing() const
{ {
if (!_dataValid) { if (!_dataValid || !_wayptController.get()) {
return -9999.0; return -9999.0;
} }

View file

@ -2319,6 +2319,8 @@ MK_VIII::VoicePlayer::get_sample (const char *name)
void void
MK_VIII::VoicePlayer::play (Voice *_voice, unsigned int flags) MK_VIII::VoicePlayer::play (Voice *_voice, unsigned int flags)
{ {
if (!_voice)
return;
if (test_bits(flags, PLAY_NOW) || ! voice || voice->element->silence) if (test_bits(flags, PLAY_NOW) || ! voice || voice->element->silence)
{ {
if (voice) if (voice)
@ -2978,9 +2980,10 @@ MK_VIII::AlertHandler::update ()
mk->voice_player.play(mk_voice(bank_angle_pause_bank_angle)); mk->voice_player.play(mk_voice(bank_angle_pause_bank_angle));
} }
// set new state // remember all alerts voiced so far...
old_alerts |= voice_alerts;
old_alerts = voice_alerts; // ... forget those no longer active
old_alerts &= alerts;
repeated_alerts = 0; repeated_alerts = 0;
} }

View file

@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// //
// multiplaymgr.hpp // multiplaymgr.cxx
// //
// Written by Duncan McCreanor, started February 2003. // Written by Duncan McCreanor, started February 2003.
// duncan.mccreanor@airservicesaustralia.com // duncan.mccreanor@airservicesaustralia.com
@ -526,14 +526,44 @@ union FGMultiplayMgr::MsgBuf
T_MsgHdr Header; T_MsgHdr Header;
}; };
bool
FGMultiplayMgr::isSane(const FGExternalMotionData& motionInfo)
{
// check for corrupted data (NaNs)
bool isCorrupted = false;
isCorrupted |= ((osg::isNaN(motionInfo.time )) ||
(osg::isNaN(motionInfo.lag )) ||
(osg::isNaN(motionInfo.orientation(3) )));
for (unsigned i = 0; (i < 3)&&(!isCorrupted); ++i)
{
isCorrupted |= ((osg::isNaN(motionInfo.position(i) ))||
(osg::isNaN(motionInfo.orientation(i) ))||
(osg::isNaN(motionInfo.linearVel(i)) )||
(osg::isNaN(motionInfo.angularVel(i)) )||
(osg::isNaN(motionInfo.linearAccel(i)) )||
(osg::isNaN(motionInfo.angularAccel(i)) ));
}
return !isCorrupted;
}
void void
FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo) FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo)
{ {
if ((! mInitialised) || (! mHaveServer)) if ((! mInitialised) || (! mHaveServer))
return; return;
if (! mHaveServer) { if (! mHaveServer) {
SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - no server"); SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - no server");
return; return;
}
if (!isSane(motionInfo))
{
// Current local data is invalid (NaN), so stop MP transmission.
// => Be nice to older FG versions (no NaN checks) and don't waste bandwidth.
SG_LOG(SG_NETWORK, SG_ALERT, "FGMultiplayMgr::SendMyPosition - "
<< "Local data is invalid (NaN). Data not transmitted.");
return;
} }
static MsgBuf msgBuf; static MsgBuf msgBuf;
@ -780,7 +810,7 @@ FGMultiplayMgr::update(double)
} }
if (MsgHdr->Version != PROTO_VER) { if (MsgHdr->Version != PROTO_VER) {
SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::MP_ProcessData - " SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::MP_ProcessData - "
<< "message has invalid protocoll number!" ); << "message has invalid protocol number!" );
break; break;
} }
if (MsgHdr->MsgLen != bytes) { if (MsgHdr->MsgLen != bytes) {
@ -858,6 +888,15 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
for (unsigned i = 0; i < 3; ++i) for (unsigned i = 0; i < 3; ++i)
motionInfo.angularAccel(i) = XDR_decode_float(PosMsg->angularAccel[i]); motionInfo.angularAccel(i) = XDR_decode_float(PosMsg->angularAccel[i]);
// sanity check: do not allow injection of corrupted data (NaNs)
if (!isSane(motionInfo))
{
// drop this message, keep old position until receiving valid data
SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::ProcessPosMsg - "
<< "Position message with invalid data (NaN) received from "
<< MsgHdr->Callsign);
return;
}
//cout << "INPUT MESSAGE\n"; //cout << "INPUT MESSAGE\n";
@ -953,7 +992,7 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
SG_LOG(SG_NETWORK, SG_DEBUG, "Unknown Prop type " << pData->id << " " << pData->type); SG_LOG(SG_NETWORK, SG_DEBUG, "Unknown Prop type " << pData->id << " " << pData->type);
xdr++; xdr++;
break; break;
} }
motionInfo.properties.push_back(pData); motionInfo.properties.push_back(pData);
} }

View file

@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// //
// multiplaymgr.hpp // multiplaymgr.hxx
// //
// Written by Duncan McCreanor, started February 2003. // Written by Duncan McCreanor, started February 2003.
// duncan.mccreanor@airservicesaustralia.com // duncan.mccreanor@airservicesaustralia.com
@ -81,6 +81,7 @@ private:
void ProcessPosMsg(const MsgBuf& Msg, const simgear::IPAddress& SenderAddress, void ProcessPosMsg(const MsgBuf& Msg, const simgear::IPAddress& SenderAddress,
long stamp); long stamp);
void ProcessChatMsg(const MsgBuf& Msg, const simgear::IPAddress& SenderAddress); void ProcessChatMsg(const MsgBuf& Msg, const simgear::IPAddress& SenderAddress);
bool isSane(const FGExternalMotionData& motionInfo);
/// maps from the callsign string to the FGAIMultiplayer /// maps from the callsign string to the FGAIMultiplayer
typedef std::map<std::string, SGSharedPtr<FGAIMultiplayer> > MultiPlayerMap; typedef std::map<std::string, SGSharedPtr<FGAIMultiplayer> > MultiPlayerMap;

View file

@ -1,7 +1,4 @@
if(LIBSVN_FOUND)
include_directories(${LIBSVN_INCLUDE_DIR})
endif(LIBSVN_FOUND)
add_executable(terrasync terrasync.cxx) add_executable(terrasync terrasync.cxx)
@ -12,7 +9,13 @@ target_link_libraries(terrasync
if(LIBSVN_FOUND) if(LIBSVN_FOUND)
target_link_libraries(terrasync ${LIBSVN_LIBRARIES}) target_link_libraries(terrasync ${LIBSVN_LIBRARIES})
set_property(TARGET terrasync APPEND PROPERTY COMPILE_FLAGS ${APR_CFLAGS}) set_property(TARGET terrasync APPEND PROPERTY COMPILE_FLAGS "${APR_CFLAGS}")
IF(APPLE)
set_property(SOURCE terrasync.cxx PROPERTY COMPILE_FLAGS "-iwithsysroot ${LIBSVN_INCLUDE_DIR}")
ELSE()
include_directories(${LIBSVN_INCLUDE_DIR})
ENDIF(APPLE)
endif() endif()

View file

@ -183,8 +183,10 @@ int mysvn_setup(void) {
if (err) if (err)
return svn_cmdline_handle_exit_error(err, pool, "terrasync: "); return svn_cmdline_handle_exit_error(err, pool, "terrasync: ");
mysvn_ctx->auth_baton = ab; mysvn_ctx->auth_baton = ab;
#if (SVN_VER_MINOR >= 5)
mysvn_ctx->conflict_func = NULL; mysvn_ctx->conflict_func = NULL;
mysvn_ctx->conflict_baton = NULL; mysvn_ctx->conflict_baton = NULL;
#endif
// Now our magic revisions // Now our magic revisions
mysvn_rev = (svn_opt_revision_t*) apr_palloc(pool, mysvn_rev = (svn_opt_revision_t*) apr_palloc(pool,
sizeof(svn_opt_revision_t)); sizeof(svn_opt_revision_t));