Real-time horizon line visualization on screen with rust

I'm working on a project to visualize the horizon line on a screen in real time.

I have already written a small program in Rust that allows me to retrieve pitch and roll data in real time using an IMU.

Using this data, I would like to visualize the horizon line in real time on a window.

Could you help me find the simplest way to solve my problem?

1 Like

The simplest way to draw a single shape is likely to use a framework meant for animations and games, such as nannou.

If you eventually want to have several different “instruments” in the window, then you might want something more of a GUI framework, like egui.

Thank you very much.

Indeed, I discovered nannou and I think it meets my needs perfectly.

I send serial data at a frequency of 50 Hz and I would like my drawing to update automatically upon receiving the data. How do you suggest I do this? Interrupts or events?

Since the rate at which data is arriving is similar to typical screen refresh rates, you can simply treat it as a continuous animation. Each time your drawing code runs, check if new data is available and store it if it is, then draw the (most recent) stored data. For nannou, I believe this would mean that you put the stored data (and the channel receiver for the data) in your “model” struct.

The checking would be done by using a channel’s try_recv() function or a similar non-blocking operation for whatever other communication strategy you use. It is very important that your GUI code does not block, to avoid interfering with the responsiveness of basic GUI functions (or outright hanging if the data source stops delivering new data), which is why you must use try_recv() and not recv().

You do not need to use any “interrupts or events” because the cost of drawing a few extra frames is insignificant. You might or might not also want to resample the data to match the refresh rate so that the display changes smoothly (like an analog instrument would) rather than only updating exactly when there is a new data point, and in that case, there are no extra frames.

Thank you again for your very relevant answer.
I'd like to take this opportunity to ask another question: how do I combine receiving serial data via UART with the "try_recv()" function?
In my program, I use "if uart.read() ? > 0 {}"

The optimal way depends on what the serial interface type offers, but the fully generic solution to add nonblocking reads when not otherwise possible is to start a thread that reads from the serial port and writes to a channel. That should be sufficient for your needs.