Real-time IMU / PFD dashboard for any MAVLink flight controller
Project description
IMU Flight Monitor
A small cross-platform dashboard that shows a real-time artificial horizon (PFD) with a crash-warning overlay, plus optional GPS and lidar panels. It reads from any MAVLink flight controller (ArduPilot or PX4 — Pixhawk, Cube, Kakute, SpeedyBee, …), from your laptop's own IMU if it has one, or from a built-in simulation so it works with no hardware at all.
Display only — it never sends commands that change autopilot state.
Works on Windows, macOS, and Linux.
Install
pip install imu-flight-monitor
imu-demo
Or run from source:
pip install -r requirements.txt
python3 imu_demo.py
Pick Demo: Simulated from the Source dropdown and press Connect. You'll get a gentle flight with a crash warning every ~30 s, a GPS ground track, and a lidar map painting a virtual room.
On Linux you may first need sudo apt install python3-tk; tkinter ships with standard Python on Windows and macOS.
Sources
| Source | What you get |
|---|---|
| Serial port (flight controller) | Attitude from ATTITUDE; GPS panel from GPS_RAW_INT; lidar map from DISTANCE_SENSOR / OBSTACLE_DISTANCE. Panels for sensors your FC doesn't have simply grey out — the horizon works with nothing but the IMU. |
| Demo: Laptop IMU | Appears only on machines with a readable built-in IMU (many 2-in-1s/convertibles). Tilt the laptop and the horizon follows. Yaw shows —; GPS/lidar stay greyed. On Windows this needs pip install winsdk. |
| Demo: Simulated | Always available. Full fake flight: attitude, GPS circuit, lidar room scan. |
Connecting a flight controller
- Plug the FC in over USB (no motors/props needed — display only).
- Open the Source dropdown — ports refresh each time you open it. A likely flight controller is pre-selected when one is found.
- Press Connect. The link indicator turns green and shows the attitude message rate.
Any board that speaks MAVLink over serial works. The app asks the FC for the message streams it displays (MAV_CMD_SET_MESSAGE_INTERVAL, with the legacy stream request as fallback).
The Source box also accepts a typed MAVLink connection string — e.g. udpin:0.0.0.0:14551 to read a MAVProxy UDP output while QGC or MAVProxy keeps the serial port.
The display
- PFD (left): artificial horizon with pitch ladder, roll arc, and heading tape. Goes grey with NO DATA if attitude stops arriving for 1 s.
- ATTITUDE / GPS / LIDAR MAP cards (right): each greys out independently after 2 s without data, or shows not available if the source can never provide it.
- GPS card: fix type, satellites, position, altitude, speed, and an offline north-up track plot (first fix = origin). Click the card to pop it out into a resizable window.
- LIDAR MAP card: accumulates rangefinder/proximity returns into a north-up point map, oriented by the vehicle's yaw — keep the vehicle still and rotate it, and the outline of the room paints itself. Clear resets the map; click the card to pop it out.
- Status bar: green SAFE / red CRASH WARNING with the live angles. One beep plays each time a warning begins.
Warning thresholds
Edit the constants at the top of safety.py:
| Constant | Default | Meaning |
|---|---|---|
PITCH_MIN_DEG |
-30 | Nose-down limit (degrees) |
PITCH_MAX_DEG |
35 | Nose-up limit (degrees) |
ROLL_MAX_ABS_DEG |
45 | Maximum roll in either direction (degrees) |
Troubleshooting
- "port busy or no permission" — close Mission Planner / QGroundControl (or anything else holding the port). On Linux, add yourself to the serial group:
sudo usermod -aG dialout $USER(log out and back in). - Wrong/stale port selected — re-open the dropdown to refresh; on Linux, stable
/dev/serial/by-id/...paths are listed when available, so the right board is easy to spot. - "no MAVLink heartbeat" — wrong port, wrong baud device, or the FC is still booting; wait a few seconds and reconnect.
- No "Demo: Laptop IMU" entry — your machine has no readable IMU (most regular laptops and desktops don't). Use the simulator instead.
Code layout
| File | Purpose |
|---|---|
imu_demo.py |
Entry point: window, toolbar, poll loop |
pfd.py |
Artificial-horizon canvas |
panels.py |
Attitude / GPS / lidar cards |
safety.py |
Warning thresholds + beep |
sources.py |
Telemetry model, MAVLink source, simulator |
laptop_imu.py |
Laptop IMU probes (Linux iio, Windows sensors) |
Publishing a new version
- Bump
versioninpyproject.toml. - Build and upload:
pip install build twine python3 -m build twine upload dist/*twinewill ask for your PyPI credentials the first time (free account at pypi.org).
Tests
python3 -m unittest discover tests
No extra packages needed — the tests use Python's built-in unittest.
Repository notes
Telemetry logs (*.tlog, *.tlog.raw) and parameter dumps (*.parm) are git-ignored — they can grow to tens of megabytes per session.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file imu_flight_monitor-0.1.0.tar.gz.
File metadata
- Download URL: imu_flight_monitor-0.1.0.tar.gz
- Upload date:
- Size: 20.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3db537631ef44e459475bbc359a6fc9450e36ba9a25e597705ffe0b7a0748af0
|
|
| MD5 |
1ba01c836ec0293cf0abf0018ed78372
|
|
| BLAKE2b-256 |
15dea84319d05366f532019a03515905c8983ae1f45aee2db46d88a78ac601a1
|
File details
Details for the file imu_flight_monitor-0.1.0-py3-none-any.whl.
File metadata
- Download URL: imu_flight_monitor-0.1.0-py3-none-any.whl
- Upload date:
- Size: 19.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2f6d6c7ba73ecc1d3e3d373a0a3acd5ade5e0fb533a56484c2d3dc96c7865a4
|
|
| MD5 |
e36050b706d2de370b5e2a008b7baf64
|
|
| BLAKE2b-256 |
d212fa4f27d8e8d467a33724855d8a215ac5689975b4e7ae2e3571fa4855e7c6
|