fgSubsystem init() and update() interface.
#define anzg sixdof_to_visuals.anzg
+FGADA::FGADA( double dt ) {
+ set_delta_t( dt );
+}
+
+
+FGADA::~FGADA() {
+}
+
+
// Initialize the ADA flight model, dt is the time increment
// for each subsequent iteration through the EOM
-bool FGADA::init( double dt ) {
+void FGADA::init() {
// cout << "FGADA::init()" << endl;
char Buffer[numberofbytes];
int result = fdmsock->write(Buffer, numberofbytes);
printf("Connection established.\n");
}
-
- return true;
}
public:
+ FGADA( double dt );
+ ~FGADA();
+
// reset flight params to a specific position
- bool init( double dt );
+ void init();
// update position based on inputs, positions, velocities, etc.
bool update( int multiloop );
/****************************************************************************/
+FGBalloonSim::FGBalloonSim( double dt ) {
+ //set the dt of the model
+ current_balloon.set_dt(dt);
+}
+
+
+FGBalloonSim::~FGBalloonSim() {
+}
+
+
// Initialize the BalloonSim flight model, dt is the time increment for
// each subsequent iteration through the EOM
-bool FGBalloonSim::init( double dt ) {
+void FGBalloonSim::init() {
sgVec3 temp;
FG_LOG( FG_FLIGHT, FG_INFO, "Starting initializing BalloonSim" );
FG_LOG( FG_FLIGHT, FG_INFO, " created a balloon" );
- //set the dt of the model
- current_balloon.set_dt(dt);
-
//set position
sgSetVec3( temp,
get_Latitude(),
current_balloon.setVelocity( temp );
FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing BalloonSim" );
-
- return true;
}
/* DECLARATIONS */
/****************************************************************************/
-// reset flight params to a specific position
-// int fgBalloonSimInit(double dt, FGInterface& f);
-
-// update position based on inputs, positions, velocities, etc.
-// int fgBalloonSimUpdate(FGInterface& f, int multiloop);
-
-// Convert from the FGInterface struct to the BalloonSim
-// int FGInterface_2_fgBalloonSim (FGInterface& f);
-
-// Convert from the BalloonSim to the FGInterface struct
-// int fgBalloonSim_2_FGInterface (FGInterface& f);
class FGBalloonSim: public FGInterface {
public:
+ FGBalloonSim( double dt );
+ ~FGBalloonSim();
+
// copy FDM state to BalloonSim structures
bool copy_to_BalloonSim();
bool copy_from_BalloonSim();
// reset flight params to a specific position
- bool init( double dt );
+ void init();
// update position based on inputs, positions, velocities, etc.
bool update( int multiloop );
#include "External.hxx"
+FGExternal::FGExternal( double dt ) {
+ set_delta_t( dt );
+}
+
+
+FGExternal::~FGExternal() {
+}
+
+
// Initialize the External flight model, dt is the time increment
// for each subsequent iteration through the EOM
-bool FGExternal::init( double dt ) {
+void FGExternal::init() {
// cout << "FGExternal::init()" << endl;
// set valid time for this record
stamp_time();
-
- return true;
}
class FGExternal: public FGInterface {
public:
+ FGExternal::FGExternal( double dt );
+ FGExternal::~FGExternal();
+
// reset flight params to a specific position
- bool init( double dt );
+ void init();
// update position based on inputs, positions, velocities, etc.
bool update( int multiloop );
/******************************************************************************/
-FGJSBsim::FGJSBsim(void) {
+FGJSBsim::FGJSBsim( double dt ) {
bool result;
runcount=0;
FGPath engine_path( globals->get_fg_root() );
engine_path.append( "Engine" );
- float dt = 1.0 / fgGetInt("/sim/model-hz");
+ set_delta_t( dt );
fdmex->GetState()->Setdt( dt );
result = fdmex->LoadModel( aircraft_path.str(),
// Initialize the JSBsim flight model, dt is the time increment for
// each subsequent iteration through the EOM
-bool FGJSBsim::init( double dt ) {
+void FGJSBsim::init() {
bool result;
FGPath engine_path( globals->get_fg_root() );
engine_path.append( "Engine" );
- fdmex->GetState()->Setdt( dt );
+ fdmex->GetState()->Setdt( get_delta_t() );
result = fdmex->LoadModel( aircraft_path.str(),
engine_path.str(),
FG_LOG( FG_FLIGHT, FG_INFO, " aircraft "
<< fgGetString("/sim/aircraft")
<< " does not exist" );
- return false;
+ exit(-1);
}
fdmex->GetAtmosphere()->UseInternal();
FG_LOG( FG_FLIGHT, FG_INFO, " set dt" );
FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing JSBSim" );
-
- return true;
}
/******************************************************************************/
public:
/// Constructor
- FGJSBsim::FGJSBsim(void);
+ FGJSBsim::FGJSBsim( double dt );
/// Destructor
FGJSBsim::~FGJSBsim();
bool copy_from_JSBsim();
/// Reset flight params to a specific position
- bool init( double dt );
+ void init();
/// @name Position Parameter Set
//@{
#include "IO360.hxx"
#include "LaRCsim.hxx"
-FGLaRCsim::FGLaRCsim(void) {
+FGLaRCsim::FGLaRCsim( double dt ) {
+ set_delta_t( dt );
+
ls_toplevel_init( 0.0,
(char *)fgGetString("/sim/aircraft").c_str() );
lsic=new LaRCsimIC; //this needs to be brought up after LaRCsim is
// Initialize the LaRCsim flight model, dt is the time increment for
// each subsequent iteration through the EOM
-bool FGLaRCsim::init( double dt ) {
+void FGLaRCsim::init() {
speed_up = fgGetValue("/sim/speed-up", true);
- ls_set_model_dt(dt);
+ ls_set_model_dt( get_delta_t() );
// Initialize our little engine that hopefully might
- eng.init(dt);
+ eng.init( get_delta_t() );
// dcl - in passing dt to init rather than update I am assuming
// that the LaRCsim dt is fixed at one value (yes it is 120hz CLO)
// set valid time for this record
stamp_time();
-
- return true;
}
SGValue * speed_up;
public:
- FGLaRCsim(void);
+ FGLaRCsim( double dt );
~FGLaRCsim(void);
// copy FDM state to LaRCsim structures
bool copy_from_LaRCsim();
// reset flight params to a specific position
- bool init( double dt );
+ void init();
// update position based on inputs, positions, velocities, etc.
bool update( int multiloop );
#include "MagicCarpet.hxx"
+FGMagicCarpet::FGMagicCarpet( double dt ) {
+ set_delta_t( dt );
+}
+
+
+FGMagicCarpet::~FGMagicCarpet() {
+}
+
+
// Initialize the Magic Carpet flight model, dt is the time increment
// for each subsequent iteration through the EOM
-bool FGMagicCarpet::init( double dt ) {
+void FGMagicCarpet::init() {
// set valid time for this record
stamp_time();
- model_hz = fgGetValue("/sim/model-hz", true);
-
- return true;
}
bool FGMagicCarpet::update( int multiloop ) {
// cout << "FGLaRCsim::update()" << endl;
- double time_step = (1.0 / model_hz->getIntValue()) *
- multiloop;
+ double time_step = get_delta_t() * multiloop;
// speed and distance traveled
double speed = controls.get_throttle( 0 ) * 2000; // meters/sec
class FGMagicCarpet: public FGInterface {
public:
+ FGMagicCarpet::FGMagicCarpet( double dt );
+ FGMagicCarpet::~FGMagicCarpet();
+
// reset flight params to a specific position
- bool init( double dt );
+ void init();
// update position based on inputs, positions, velocities, etc.
bool update( int multiloop );
-private:
- SGValue * model_hz;
};
vec[0] = 0.0; vec[1] = 0.0; vec[2] = 0.0;
}
-FGEngInterface::FGEngInterface(void) {
+FGEngInterface::FGEngInterface() {
// inputs
Throttle=0;
// Constructor
-FGInterface::FGInterface(void) {
+FGInterface::FGInterface() {
init_vec( d_pilot_rp_body_v );
init_vec( d_cg_rp_body_v );
init_vec( f_body_total_v );
altitude_agl=0;
}
+FGInterface::FGInterface( double dt ) {
+ FGInterface();
+
+ delta_t = dt;
+ remainder = elapsed = multi_loop = 0;
+}
// Destructor
FGInterface::~FGInterface() {
void
FGInterface::init ()
{
- init(1.0 / fgGetInt("/sim/model-hz"));
}
void
FGInterface::bind ()
{
- // Aircraft position
+ // Time management
+ fgTie("/fdm/time/delta_t", this,
+ &(FGInterface::get_delta_t),
+ &(FGInterface::set_delta_t));
+
+ // The following two can't be uncommented until we have support for
+ // the "long" data type in the property manager
+ /* fgTie("/fdm/time/elapsed", this,
+ &(FGInterface::get_elapsed),
+ &(FGInterface::set_elapsed));
+ fgTie("/fdm/time/remainder", this,
+ &(FGInterface::get_remainder),
+ &(FGInterface::set_remainder)); */
+ fgTie("/fdm/time/multi_loop", this,
+ &(FGInterface::get_multi_loop),
+ &(FGInterface::set_multi_loop));
+
+ // Aircraft position
fgTie("/position/latitude", this,
&(FGInterface::get_Latitude_deg),
&(FGInterface::set_Latitude_deg));
void
FGInterface::unbind ()
{
+ fgUntie("/fdm/time/delta_t");
+ fgUntie("/fdm/time/elapsed");
+ fgUntie("/fdm/time/remainder");
+ fgUntie("/fdm/time/multi_loop");
fgUntie("/position/latitude");
fgUntie("/position/longitude");
fgUntie("/position/altitude");
}
-bool FGInterface::init( double dt ) {
- cout << "dummy init() ... SHOULDN'T BE CALLED!" << endl;
- return false;
-}
-
-
bool FGInterface::update( int multi_loop ) {
cout << "dummy update() ... SHOULDN'T BE CALLED!" << endl;
return false;
private:
+ // periodic update management variable. This is a scheme to run
+ // the fdm with a fixed delta-t. We control how many iteration of
+ // the fdm to run with the fixed dt based on the elapsed time from
+ // the last update. This allows us to maintain sync with the real
+ // time clock, even though each frame could take a random amount
+ // of time. Since "dt" is unlikely to divide evenly into the
+ // elapse time, we keep track of the remainder and add it into the
+ // next elapsed time. This yields a small amount of temporal
+ // jitter ( < dt ) but in practice seems to work well.
+
+ double delta_t; // delta "t"
+ long elapsed; // time elapsed since last run
+ long remainder; // remainder time from last run
+ int multi_loop; // number of iterations of "delta_t" to run
+
// Pilot location rel to ref pt
FG_VECTOR_3 d_pilot_rp_body_v;
SGTimeStamp next_stamp; // time this record is valid
protected:
- virtual bool init( double dt );
-
- void _busdump(void);
+ void _busdump(void);
void _updatePosition( double lat_geoc, double lon, double alt );
void _updateWeather( void );
public:
- FGInterface(void);
+ FGInterface();
+ FGInterface( double dt );
virtual ~FGInterface();
virtual void init ();
FG_EXTERNAL = 10
};
+ // time and update management values
+ inline double get_delta_t() const { return delta_t; }
+ inline void set_delta_t( double dt ) { delta_t = dt; }
+ inline long get_elapsed() const { return elapsed; }
+ inline void set_elapsed( long e ) { elapsed = e; }
+ inline long get_remainder() const { return remainder; }
+ inline void set_remainder( long r ) { remainder = r; }
+ inline int get_multi_loop() const { return multi_loop; }
+ inline void set_multi_loop( int ml ) { multi_loop = ml; }
+
// Positions
virtual void set_Latitude(double lat); // geocentric
virtual void set_Longitude(double lon);
"Current terrain elevation after tile mgr init " <<
scenery.cur_elev );
+ double dt = 1.0 / fgGetInt("/sim/model-hz");
+
const string &model = fgGetString("/sim/flight-model");
if (model == "larcsim") {
- cur_fdm_state = new FGLaRCsim;
+ cur_fdm_state = new FGLaRCsim( dt );
} else if (model == "jsb") {
- cur_fdm_state = new FGJSBsim;
+ cur_fdm_state = new FGJSBsim( dt );
} else if (model == "ada") {
- cur_fdm_state = new FGADA;
+ cur_fdm_state = new FGADA( dt );
} else if (model == "balloon") {
- cur_fdm_state = new FGBalloonSim;
+ cur_fdm_state = new FGBalloonSim( dt );
} else if (model == "magic") {
- cur_fdm_state = new FGMagicCarpet;
+ cur_fdm_state = new FGMagicCarpet( dt );
} else if (model == "external") {
- cur_fdm_state = new FGExternal;
+ cur_fdm_state = new FGExternal( dt );
} else {
FG_LOG(FG_GENERAL, FG_ALERT,
"Unrecognized flight model '" << model
// attempt to avoid a large bounce at startup
static bool initial_freeze = true;
-// Another hack
-int use_signals = 0;
-
// forward declaration
void fgReshape( int width, int height );
#endif
// Run flight model
- if ( ! use_signals ) {
- // Calculate model iterations needed for next frame
- elapsed += remainder;
-
- global_multi_loop = (int)(((double)elapsed * 0.000001) *
- fgGetInt("/sim/model-hz"));
- remainder = elapsed - ( (global_multi_loop*1000000) /
- fgGetInt("/sim/model-hz") );
- FG_LOG( FG_ALL, FG_DEBUG,
- "Model iterations needed = " << global_multi_loop
- << ", new remainder = " << remainder );
+
+ // Calculate model iterations needed for next frame
+ elapsed += remainder;
+
+ global_multi_loop = (int)(((double)elapsed * 0.000001) *
+ fgGetInt("/sim/model-hz"));
+ remainder = elapsed - ( (global_multi_loop*1000000) /
+ fgGetInt("/sim/model-hz") );
+ FG_LOG( FG_ALL, FG_DEBUG,
+ "Model iterations needed = " << global_multi_loop
+ << ", new remainder = " << remainder );
- // flight model
- if ( global_multi_loop > 0 ) {
- fgUpdateTimeDepCalcs(global_multi_loop, remainder);
- } else {
- FG_LOG( FG_ALL, FG_DEBUG,
- "Elapsed time is zero ... we're zinging" );
- }
+ // flight model
+ if ( global_multi_loop > 0 ) {
+ fgUpdateTimeDepCalcs(global_multi_loop, remainder);
+ } else {
+ FG_LOG( FG_ALL, FG_DEBUG,
+ "Elapsed time is zero ... we're zinging" );
}
#if ! defined( macintosh )
// setup OpenGL view parameters
fgInitVisuals();
- if ( use_signals ) {
- // init timer routines, signals, etc. Arrange for an alarm
- // signal to be generated, etc.
- fgInitTimeDepCalcs();
- }
-
idle_state++;
} else if ( idle_state == 5 ) {