Indeed, I/O is frame-rate dependent - typical frame rates are roughly 50-60 fps/hz. Thus, 100hz would seem like a lot, and it would never be steady either, because all I/O is running interleaved with the main loop, i.e. with other subsystems. Unfortunately, FlightGear's I/O system doesn't run in its own thread. Like Philosopher said, you /may/ be able to work around this by using an FDM-coupled subsystem,or by interleaving your I/O subsystem with the FDM, which may either require creative use of listeners & signals (property rules).
Alternatively, you could throttle the frame rate to a sane value like 20-30 fps and then use accelerated sim time. I think several people have used this workaround in the past
Overall, it would be a good idea to file a feature request. In the meantime, you could also use some minor C++ changes:
Subject: Actual programming language for autopilot implementation?Hooray wrote:I still don't think this needs to be very complicated, especially not with all the pointers that you have now - this is what I got after 5-10 minutes playing around (not really tested in depth yet) - but this should get you started on the right track:
- Code: Select all
diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx
index cb4a2e5..ddafce0 100644
--- a/src/Main/fg_init.cxx
+++ b/src/Main/fg_init.cxx
@@ -1069,6 +1069,10 @@ bool fgInitSubsystems() {
globals->get_event_mgr()->init();
globals->get_event_mgr()->setRealtimeProperty(fgGetNode("/sim/time/delta-realtime-sec", true));
+ // and now for the FDM-coupled event mgr:
+ globals->get_event_mgr(true)->init();
+ globals->get_event_mgr(true)->setRealtimeProperty(fgGetNode("/sim/time/delta-realtime-sec",true));
+
////////////////////////////////////////////////////////////////////
// Initialize the property interpolator subsystem. Put into the INIT
// group because the "nasal" subsystem may need it at GENERAL take-down.
@@ -1247,6 +1251,10 @@ bool fgInitSubsystems() {
// ordering here is important : Nasal (via events), then models, then views
globals->add_subsystem("events", globals->get_event_mgr(), SGSubsystemMgr::DISPLAY);
+
+ // another event system instance that runs coupled with the FDM
+ // to be used for Nasal scripts
+ globals->add_subsystem("fdm-events", globals->get_event_mgr(true), SGSubsystemMgr::FDM);
FGAircraftModel* acm = new FGAircraftModel;
globals->set_aircraft_model(acm);
diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx
index 8c8ca52..698ef4a 100644
--- a/src/Main/globals.cxx
+++ b/src/Main/globals.cxx
@@ -126,6 +126,7 @@ FGGlobals::FGGlobals() :
renderer( new FGRenderer ),
subsystem_mgr( new SGSubsystemMgr ),
event_mgr( new SGEventMgr ),
+ fdm_coupled_event_mgr( new SGEventMgr ),
sim_time_sec( 0.0 ),
fg_root( "" ),
time_params( NULL ),
@@ -378,9 +379,10 @@ FGGlobals::get_soundmgr () const
}
SGEventMgr *
-FGGlobals::get_event_mgr () const
+FGGlobals::get_event_mgr (bool fdm_coupled) const
{
- return event_mgr;
+ if (!fdm_coupled) return event_mgr;
+ return fdm_coupled_event_mgr;
}
const SGGeod &
diff --git a/src/Main/globals.hxx b/src/Main/globals.hxx
index 2ec9cc3..73e69ad 100644
--- a/src/Main/globals.hxx
+++ b/src/Main/globals.hxx
@@ -91,6 +91,7 @@ private:
FGRenderer *renderer;
SGSubsystemMgr *subsystem_mgr;
SGEventMgr *event_mgr;
+ SGEventMgr *fdm_coupled_event_mgr;
// Number of milliseconds elapsed since the start of the program.
double sim_time_sec;
@@ -181,7 +182,7 @@ public:
type = SGSubsystemMgr::GENERAL,
double min_time_sec = 0);
- virtual SGEventMgr *get_event_mgr () const;
+ virtual SGEventMgr *get_event_mgr (bool fdm_coupled=false) const;
virtual SGSoundMgr *get_soundmgr () const;
diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx
index a398301..24d7fb3 100644
--- a/src/Scripting/NasalSys.cxx
+++ b/src/Scripting/NasalSys.cxx
@@ -897,6 +897,7 @@ void FGNasalSys::setTimer(naContext c, int argc, naRef* args)
}
bool simtime = (argc > 2 && naTrue(args[2])) ? false : true;
+ bool fdm_coupled = (argc > 3 && naTrue(args[3])) ? true: false;
// Generate and register a C++ timer handler
NasalTimer* t = new NasalTimer;
@@ -904,9 +905,17 @@ void FGNasalSys::setTimer(naContext c, int argc, naRef* args)
t->gcKey = gcSave(handler);
t->nasal = this;
- globals->get_event_mgr()->addEvent("NasalTimer",
+ if (fdm_coupled) {
+ static_cast<SGEventMgr *>(globals->get_subsystem("fdm-events"))->addEvent("NasalTimer (FDM coupled)",
+ t, &NasalTimer::timerExpired,
+ delta.num, simtime);
+ SG_LOG(SG_NASAL, SG_DEBUG, "Registering FDM-coupled Nasal callback!");
+ }
+ else {
+ globals->get_event_mgr()->addEvent("NasalTimer",
t, &NasalTimer::timerExpired,
delta.num, simtime);
+ }
}
void FGNasalSys::handleTimer(NasalTimer* t)
Note: I only started with --model-hz=500 to make the difference really obvious
Notice how the remaining subsystems (in particular nasal and events) still run at framerate, only scripts using the new optional settimer() argument will be run fdm-coupled