• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

MSFS20 Question about client to server latency

Messages
945
Country
ca-ontario
Hi Everyone,

I have a question about the latency during the SimConnect client-to-server request-response cycle. Namely, when I send a request for Nav data on a user object (Lat Lon Alt Pitch Bank Heading), the response I get is about ~10000 microseconds, which is about 0.01 seconds:

1706378059715.png


This basically means that the data I got is basically 0.01 seconds old, and it has slightly changed in that time.

Now, for the instrumentation display purposes, this may be trivial. However, if you calculate this error in terms of distance, the positional error for an average passenger jet at a cruise speed is approximately 3 meters. Note, the smaller the speed, the smaller the error is, approaching zero at standstill. Again, for the purpose of instrumentation display at such speeds, this error is trivial.

However, I have a requirement in my code to have a precise, instantaneous positional reading of the aircraft's Nav data, without any errors due to the client-server communication lag, that is, the Nav data reading as it is currently in the sim, not 0.01 seconds later ;)

Any idea how to accomplish this? I am thinking, as an alternate solution, using the lag time and the velocity vector I could predict the new position, but before I start doing that, I'd like to see if there is a way to get instantaneous Nav data from the sim itself.
 
It's an async network protocol.... there's no way it will be real-time, ever. (Even on something like a custom "drone" (RC/multicopter) with direct access to the CPU and tight telemetry code, it's nearly impossible even over a wired link.)

Even were you to get this data "instantly" from within the sim engine itself somehow (JS API or maybe WASM), how would you get that "instantly" to your external app? Maybe if your app was running in the sim itself... but I wonder even then.

Would be curious to compare the delay when letting the sim push changes to the SimConnect client, vs. polling for changes. But I don't know how'd you'd even measure the latency on that. 🤷‍♂️

-Max
 
It's an async network protocol.... there's no way it will be real-time, ever. (Even on something like a custom "drone" (RC/multicopter) with direct access to the CPU and tight telemetry code, it's nearly impossible even over a wired link.)

Even were you to get this data "instantly" from within the sim engine itself somehow (JS API or maybe WASM), how would you get that "instantly" to your external app? Maybe if your app was running in the sim itself... but I wonder even then.

My client is not external app - it IS running in the sim itself. It is a simple SimConnect client.

Would be curious to compare the delay when letting the sim push changes to the SimConnect client, vs. polling for changes. But I don't know how'd you'd even measure the latency on that. 🤷‍♂️

-Max
Pushing changes? Do you have any code samples on how to do that?
 
Well, at risk of assuming anything further, my response was based on the part of your OP where you say "when I send a request..." So I don't really know how exactly you're requesting data now. :)

But what I was referring to....

Pushing changes? Do you have any code samples on how to do that?


Allows you to specify a period and interval which dictates how often the sim will check for changes in your requested variable/data and push updates to your client if any changes are detected (you still have to run the usual message dispatch check/loop, unless running the client in a WASM module of course where that's unnecessary).

This would be instead of using RequestDataOnSimObjectType() which requires polling for changes. The subscription setup process is the same for both versions. The incoming data ID is SIMCONNECT_RECV_ID_SIMOBJECT_DATA and the structure is https://docs.flightsimulator.com/ht...umerations/SIMCONNECT_RECV_SIMOBJECT_DATA.htm which is actually identical to the "_BYTYPE" version.

HTH,
-Max
 
Well, at risk of assuming anything further, my response was based on the part of your OP where you say "when I send a request..." So I don't really know how exactly you're requesting data now. :)

But what I was referring to....




Allows you to specify a period and interval which dictates how often the sim will check for changes in your requested variable/data and push updates to your client if any changes are detected (you still have to run the usual message dispatch check/loop, unless running the client in a WASM module of course where that's unnecessary).

This would be instead of using RequestDataOnSimObjectType() which requires polling for changes. The subscription setup process is the same for both versions. The incoming data ID is SIMCONNECT_RECV_ID_SIMOBJECT_DATA and the structure is https://docs.flightsimulator.com/ht...umerations/SIMCONNECT_RECV_SIMOBJECT_DATA.htm which is actually identical to the "_BYTYPE" version.

HTH,
-Max
Aha, yes - I am already doing that:

Code:
hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_SIM_NAV_DATA, DEFINITION_SIM_NAV_DATA, m_ObjectID, SIMCONNECT_PERIOD_SIM_FRAME);

And that works well - except, it takes ~0.01 second to get from server to my client... and that is the problem.
 
It is possible to request data and have the sim update it as it changes... one call, multiple responses.
 
it takes ~0.01 second to get from server to my client
Out of curiosity, how are you measuring that?
(Or actually I'm not sure what the server and client is in this case... server is the sim and the client is your SimConnect code?).
 
EDIT: Sorry, you had the math right, it was my mistake reading .01 seconds vs. .001 seconds.

But regarding the 10ms update this still applies I think...
To put things in perspective, if the sim is running at 60Hz, for example, ~16ms is going to be the fastest rate any data can be updated at.

From observations, the sim rate dictates how often data updates will be coming in (assuming SIM_FRAME update period). For rapidly changing data like location or speed the value updates typically top out at about 10-30Hz on my box (for each data point individually, not total). That's w/out applying any delta epsilon filtering, just raw updates on every change (which I'd typically filter because who cares if airspeed changed by 0.000001 knots).
(Yea that's about as fast as my sim runs... when I grow up I'd like to get a supercomputer.)

Anyway, just to throw that out there...

Cheers,
-Max
 
Last edited:
Out of curiosity, how are you measuring that?
(Or actually I'm not sure what the server and client is in this case... server is the sim and the client is your SimConnect code?).
To roughly measure response time, I sent out the request using

Code:
hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_SIM_NAV_DATA, DEFINITION_SIM_NAV_DATA, m_ObjectID, SIMCONNECT_PERIOD_ONCE);
ServerResponseTime = SystemVars->m_SimCurrentTime;

(Note the SIMCONNECT_PERIOD_ONCE)

...and I measured the time it took between that call and when the corresponding event is returned:

Code:
case REQUEST_SIM_NAV_DATA:
                    {       
                        ServerResponseDuration = SystemVars->m_SimCurrentTime - ServerResponseTime;

But ordinarily, I am using the SimConnect_RequestDataOnSimObject call in the SIMCONNECT_PERIOD_SIM_FRAME mode (so, called it only once and let it push the data into my client through the case REQUEST_SIM_NAV_DATA:

But now, to be honest, I am unsure if I am doing this right. I did a bit more timing testing, and it looks as if my main event loop is running at about the same frame rate, so I think my timing method is invalid.
 
Alright, so I posted this question on MSFS2020 Developer Forum and I've got a few helpful hints and suggestions. Namely, along with position and attitude, I am setting linear and rotational velocities as well, and getting the data from the token variables instead of SimVars, as they seem to be "instantaneous", and not requiring server request/response. I have managed to stabilize horizontal positioning oscillations (“jerks”) (on Latitude and Longitude), and thigs look much better/smoother. I am also setting these SimVars on per-visual frame (instead of per-sim frame), since I need this to work visually.

However, now I can’t get vertical (altitude / speed) to stabilize - the SimObject that I am trying to get to smoothly follow user aircraft is now moving in up/down oscillating motion, and is not clamping its vertical position to the parent aircraft. I am applying both absolute altitude value and the vertical speed to the SimObject. This worked for Lat/Long, where things stabilized, but so far not for altitude (vertical position).

Note: If I am in level flight, the up/down oscillations are minimized - I guess due to the fact that the altitude position is more or less a constant value. However, as soon as I start climbing/diving, the oscillation worsens proportionally.

Considering the fact that the vertical position was somewhat stable, and got worse after Lat/Lon positions stabilized, I am wondering if the order of setting things would matter? I am using a combo of token and SimVars and testing various parameters and the order of setting them, which for now is an exercise in sheer luck rather than deduction, since we have zero insight into the inner workings and how these parameters are applied inside the sim.

Any ideas or thoughts on this? Any input would be appreciated. I can post a video of what I am working with, if needed for clarification.
 
Misho - not an answer, but a comment that may help newer developers. Yes, I agree that module_vars are a lot faster than SimVars or querying via SimConnect. They're also available a lot earlier than either a SimVar or SimConnect request. I tried to drop module_vars and switch over to 100% SimConnect but it didn't take long to find that it wasn't going to work.
 
You're trying to "lock" another object to the plane's position, maybe kinda like the "drone follow" FS mode?

So that means you have two delays to contend with, plus whatever processing logic you have sitting in between getting the data and sending out the new position for your object?

Seems like there could/should be some feature for that, but I have no idea how. The drone following mode always seems like the camera is essentially just attached to the airplane model itself, with some offsets to reposition it (it doesn't "feel" like an actual drone following you). Could you use something like that instead?

Lacking exact real-time "stick like glue" coordinates of the plane being followed, sounds like you may need a PI[D] controller to smooth out the oscillations?
EDIT:
For the "D" part to work you'd want some way to measure the difference between desired position and current actual position... is that measurable?
But even just a PI controller should smooth out or remove the oscillations. Which sound typical of a controller which doesn't have a PI integrator so is constantly jumping between where it needs to be w/out smoothing it.

Following a moving aircraft is actually fairly complicated in real life, definitely requiring PID or other control theory applications (something humans do "naturally"). The following controller is always going to be "catching up" to the vehicle being followed since feedback of it's position isn't quite real-time and hard to predict. Of course in a sim you should already have the data, but if there's no way to actually read/manipulate things in real-time in the sim then it's kinda back to control theory basics.

Isn't there some way to replace the autopilot logic in MSFS? Or am I confusing it with another sim? Wondering because it seems that would require the same kind of data and manipulation techniques that perhaps you're looking for here.

Cheers,
-Max
 
Last edited:
Interesting about the Token vars being faster to access... never knew that! We're talking about Gauge API, aircraft_varget() vs. lookup_var(), right?
 
You're trying to "lock" another object to the plane's position, maybe kinda like the "drone follow" FS mode?
Precisely.
So that means you have two delays to contend with, plus whatever processing logic you have sitting in between getting the data and sending out the new position for your object?
Correct. Delay with getting the data, and the delay with setting the data. Processing logic is minimal, for now, but I don't see it as a huge factor considering I am working with a visual frame time interval, not the sim frame.
Seems like there could/should be some feature for that, but I have no idea how. The drone following mode always seems like the camera is essentially just attached to the airplane model itself, with some offsets to reposition it (it doesn't "feel" like an actual drone following you). Could you use something like that instead?
From my understanding, the drone is a camera/viewpoint, not a SimObject. I didn't see any functionality to obtain drone's position/attitude.
Lacking exact real-time "stick like glue" coordinates of the plane being followed, sounds like you may need a PI[D] controller to smooth out the oscillations?
EDIT:
For the "D" part to work you'd want some way to measure the difference between desired position and current actual position... is that measurable?
But even just a PI controller should smooth out or remove the oscillations. Which sound typical of a controller which doesn't have a PI integrator so is constantly jumping between where it needs to be w/out smoothing it.
Yeah - I was thinking of smoothing the result by trying to measure out what I am getting during every sim frame, averaging it (to start out with) and then applying it to a visual frame. But first, I need to record and carefully examine what I am getting from the token vars, over time. If there are no oscillations and I am getting the smooth altitude values, then there is something in the way the vars are being set on SimObject.
Following a moving aircraft is actually fairly complicated in real life, definitely requiring PID or other control theory applications (something humans do "naturally"). The following controller is always going to be "catching up" to the vehicle being followed since feedback of it's position isn't quite real-time and hard to predict. Of course in a sim you should already have the data, but if there's no way to actually read/manipulate things in real-time in the sim then it's kinda back to control theory basics.
Since I am getting good results on LAT LON (from token vars) and NOT from altitude, I THINK that there is some kind of an order that these vars need to be applied in on a sim loop level. I am guessing that, after I set the vars on the SimObject there is some internal calculation that may be overriding the altitude.
 
Interesting about the Token vars being faster to access... never knew that! We're talking about Gauge API, aircraft_varget() vs. lookup_var(), right?
Yes, super simple:
Code:
MODULE_VAR ALT_var = { PLANE_ALTITUDE }; // Specifies the current altitude of the aircraft, in meters.
lookup_var(&ALT_var);
LLA_PBH.Altitude = ALT_var.var_value.n;
 
Back
Top