A simulink exploration: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
(title)
 
 
(23 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{stub}}
===  A Simulink exploration (one month free trial :) ===
===  A Simulink exploration (one month free trial :) ===
If you can't wait, see [https://forum.flightgear.org/viewtopic.php?f=27&t=38421 the topic on the forum] :P
here are some tips to improve visuals for simulink driven Flightgear videos.
I only used the month free trial for matlab, so i can't run it anymore, but i still have netfdm packets recorded during some simulink run.
== simulink - fg synchronization ==
I used the asbhl20 project from simulink, which is a spacial ship short final landing. Flighgear use the netfdm input, with something like:
<code>''' --native-fdm=socket,in,30,,5502,udp --fdm=null '''</code>
You need to set the destination ip and port for the netfdm output from Simulink to match Flightgear ip and port, and if you're lucky, the plane fly to land safely in Flightgear when you start a simulink run !
Notice the netfdm protocol had some change after 2020.3 FG version (some tank props were added at jsbsim request), so using a more recent Flightgear with the same simulink i used ( 2020) will end as failure.
== a not so smooth visual ==
I didn't put a video example here, but the visual flow of an externally driven Flightgear is not a fluid experience, it's more like a compilation of frozen state played one after an other.
The current netfdm implementation consist simply in having the plane's position slaved to the last netfdm position received. Depending simulink and FG fps, we can have some frames having the same position, waiting from a netfdm update, or netfdm position being skipped because FG was to slow to render or load 3D stuff.
It's bearable when the plane is solo in the air, but this lead to big jitter if we try to have two planes together (or more)  and is obvious close to the ground for solo plane.
== trying to run FlightGear and Simulink in synchronization ==
Later 2020.3 releases (>= 2020.3.9) include a way to run Flightgear more précisely on a time grid, we'll use this to have a better synchronization, where each simulink frame is displayed, and Flightgear use each simulink positions for only one frame.
* FlightGear:
Using the throttle frame rate option in the rendering menu make Flightgear starting each frame on a time grid, if it run fast enough, and if not, it will start on the next step given from the model-hz option, so to use a time grid at 30fps, we need both the model-hz and the throttle frame rate at 30:
<code>--model-hz=30 --prop:/sim/frame-rate-model-hz=30</code>
You can see the error between the time grid and the real time the frame started with /sim/time/dt-remainder-sec in the properties, if you want to log it and see if FG is stable enough.
* Simulink:
Sadly i didn't manage to have simulink run and send the netfdm packet at a nice 30fps (maybe because of the computer old age ? or the need of the real time mode not available to me), if you need to use feedback information from FlightGear, this is something to look at, notice Simulink provide a log of the offset between the sim running time and the real running time (add a scope to the output of the "set pace" module)
i didn't need feedback from Flightgear, so i changed the block waiting for it to use a record (iirc, otherwise Simulink was waiting nearly 5s for  FG packet (not sent) before starting)
Here's  what my log looked like: 1s late early, closing on real time, then in a 50ms window, not precise enough for my need (the result was the same from wireshark log analysis)
[[File:Simulink pace error log.jpg|none|pace error log]]
The cheat: as i couldn't manage a stable 30fps from simulink, i simply recorded the netfdm packets (with wireshark) and replayed them at 30fps with a network tool (tcpreplay on linux)
*Both together:
With a steady netfdm flow of 30 fps and FlightGear running on a time grid, the result was way better, there are still some frame a bit late to create some stuttering, but this is something to expect on my old dual core.
FlightGear run on a time grid passing by the full second, but that's not the case for tcpreplay witch start at random (no clue for simulink) so you may need a bit of tries before having  a good result, if both run at nearly the same time, you'll notice more jitter!
There's a simple way to see how both are interacting: the record of the network packets involved  (wireshark or similar is your friend) if you make FlightGear send mp packet each frame, you'll see how in synchronization they are.
== Video tips ==
Using a network tool to record and replay a simulink session allow to separate the Simulink run, from the video run, you can eg run Simulink and Flightgear at 1 fps and then replay the netfdm at 30 fps for the video.
== using 2 planes ==
Next was the need for a video with two planes interacting, Both FlightGear were driven from simulink netfdm, and they are seeing the other by the mp protocol. the idea here is for each frame to run Simulink , a bit later FG1 and a bit later FG2, this way FG1 will see FG2's plane one frame late, but the result should be visually good on FG2, if it manage to receive FG1's position from the same frame.
We will use a time offset in Flightgear, to shift the time grid a bit, using:
<code>--prop:/sim/time/steady-offset-ms=16.6</code>
here it shift the time grid by 16.6 ms, half the 33.3333ms length of a 30fps frame, so FG1 and FG2 will run one after the other every 16.6ms, and depending when Simulink play in the loop, you'll have a nice video on FG1 or FG2, after probably some bad tries (Simulink/tcpreplay nearly at the same time of one of FG making jitter planes)
Notice that the clock used for the time grid is initialized by the wall clock, so having multiple FlightGear on multiple computers running on a precise timing is possible if the wall clocks are in synchronization, ntp, ptp or alike are your friends ...
== more than 2 planes ==
the best solution for displaying more than 2 planes from Simulink in FlightGear would be to directly send the mp protocol, one FlightGear displaying all the multiplayers at once.
an other way is to have each plane running a FlightGear, each sending the mp protocol to a FlightGear session used as final visual.
If Simulink doesn't output the mp protocol, a little soft to convert netfdm to mp protocol would do the job, but there's the need for a timestamp in the netfdm protocol.
If you use multiple Flightgear on the same computer, be sure they use different CPU cores, here it run always in the first core and i need to change the core affinity once started. Notice that disk access can make the frames a bit  longer, so avoiding log files or the like is better, and a ssd HD is probably a good choice.
== possible improvements ==
The current netfdm protocol doesn't include a timestamp, so we lack the time information for the position we have, that's why running both in synchronization is the only way to have a smooth result as of now (end 2021)
With a timestamp and the planes's velocity added (was not sent from the project i used), the jitter between two planes externally driven could be removed as this allow to predict the mp plane's position, but that would need a bit of work in FlightGear to use this timestamp as time in the mp protocol to display the other planes, and to send in the mp packets. 
[[Category:Interfacing protocols| ]]

Latest revision as of 16:32, 9 January 2022

This article is a stub. You can help the wiki by expanding it.

A Simulink exploration (one month free trial :)

If you can't wait, see the topic on the forum :P here are some tips to improve visuals for simulink driven Flightgear videos. I only used the month free trial for matlab, so i can't run it anymore, but i still have netfdm packets recorded during some simulink run.

simulink - fg synchronization

I used the asbhl20 project from simulink, which is a spacial ship short final landing. Flighgear use the netfdm input, with something like:

 --native-fdm=socket,in,30,,5502,udp --fdm=null 

You need to set the destination ip and port for the netfdm output from Simulink to match Flightgear ip and port, and if you're lucky, the plane fly to land safely in Flightgear when you start a simulink run !

Notice the netfdm protocol had some change after 2020.3 FG version (some tank props were added at jsbsim request), so using a more recent Flightgear with the same simulink i used ( 2020) will end as failure.

a not so smooth visual

I didn't put a video example here, but the visual flow of an externally driven Flightgear is not a fluid experience, it's more like a compilation of frozen state played one after an other. The current netfdm implementation consist simply in having the plane's position slaved to the last netfdm position received. Depending simulink and FG fps, we can have some frames having the same position, waiting from a netfdm update, or netfdm position being skipped because FG was to slow to render or load 3D stuff.

It's bearable when the plane is solo in the air, but this lead to big jitter if we try to have two planes together (or more) and is obvious close to the ground for solo plane.

trying to run FlightGear and Simulink in synchronization

Later 2020.3 releases (>= 2020.3.9) include a way to run Flightgear more précisely on a time grid, we'll use this to have a better synchronization, where each simulink frame is displayed, and Flightgear use each simulink positions for only one frame.

  • FlightGear:

Using the throttle frame rate option in the rendering menu make Flightgear starting each frame on a time grid, if it run fast enough, and if not, it will start on the next step given from the model-hz option, so to use a time grid at 30fps, we need both the model-hz and the throttle frame rate at 30:

--model-hz=30 --prop:/sim/frame-rate-model-hz=30

You can see the error between the time grid and the real time the frame started with /sim/time/dt-remainder-sec in the properties, if you want to log it and see if FG is stable enough.

  • Simulink:

Sadly i didn't manage to have simulink run and send the netfdm packet at a nice 30fps (maybe because of the computer old age ? or the need of the real time mode not available to me), if you need to use feedback information from FlightGear, this is something to look at, notice Simulink provide a log of the offset between the sim running time and the real running time (add a scope to the output of the "set pace" module) i didn't need feedback from Flightgear, so i changed the block waiting for it to use a record (iirc, otherwise Simulink was waiting nearly 5s for FG packet (not sent) before starting)

Here's what my log looked like: 1s late early, closing on real time, then in a 50ms window, not precise enough for my need (the result was the same from wireshark log analysis)

pace error log

The cheat: as i couldn't manage a stable 30fps from simulink, i simply recorded the netfdm packets (with wireshark) and replayed them at 30fps with a network tool (tcpreplay on linux)

  • Both together:

With a steady netfdm flow of 30 fps and FlightGear running on a time grid, the result was way better, there are still some frame a bit late to create some stuttering, but this is something to expect on my old dual core. FlightGear run on a time grid passing by the full second, but that's not the case for tcpreplay witch start at random (no clue for simulink) so you may need a bit of tries before having a good result, if both run at nearly the same time, you'll notice more jitter! There's a simple way to see how both are interacting: the record of the network packets involved (wireshark or similar is your friend) if you make FlightGear send mp packet each frame, you'll see how in synchronization they are.

Video tips

Using a network tool to record and replay a simulink session allow to separate the Simulink run, from the video run, you can eg run Simulink and Flightgear at 1 fps and then replay the netfdm at 30 fps for the video.

using 2 planes

Next was the need for a video with two planes interacting, Both FlightGear were driven from simulink netfdm, and they are seeing the other by the mp protocol. the idea here is for each frame to run Simulink , a bit later FG1 and a bit later FG2, this way FG1 will see FG2's plane one frame late, but the result should be visually good on FG2, if it manage to receive FG1's position from the same frame. We will use a time offset in Flightgear, to shift the time grid a bit, using: --prop:/sim/time/steady-offset-ms=16.6

here it shift the time grid by 16.6 ms, half the 33.3333ms length of a 30fps frame, so FG1 and FG2 will run one after the other every 16.6ms, and depending when Simulink play in the loop, you'll have a nice video on FG1 or FG2, after probably some bad tries (Simulink/tcpreplay nearly at the same time of one of FG making jitter planes) Notice that the clock used for the time grid is initialized by the wall clock, so having multiple FlightGear on multiple computers running on a precise timing is possible if the wall clocks are in synchronization, ntp, ptp or alike are your friends ...

more than 2 planes

the best solution for displaying more than 2 planes from Simulink in FlightGear would be to directly send the mp protocol, one FlightGear displaying all the multiplayers at once. an other way is to have each plane running a FlightGear, each sending the mp protocol to a FlightGear session used as final visual.

If Simulink doesn't output the mp protocol, a little soft to convert netfdm to mp protocol would do the job, but there's the need for a timestamp in the netfdm protocol.

If you use multiple Flightgear on the same computer, be sure they use different CPU cores, here it run always in the first core and i need to change the core affinity once started. Notice that disk access can make the frames a bit longer, so avoiding log files or the like is better, and a ssd HD is probably a good choice.

possible improvements

The current netfdm protocol doesn't include a timestamp, so we lack the time information for the position we have, that's why running both in synchronization is the only way to have a smooth result as of now (end 2021)

With a timestamp and the planes's velocity added (was not sent from the project i used), the jitter between two planes externally driven could be removed as this allow to predict the mp plane's position, but that would need a bit of work in FlightGear to use this timestamp as time in the mp protocol to display the other planes, and to send in the mp packets.