Name
imud — a general-purpose IMU daemon for Linux
Think of it as gpsd for IMUs.
Synopsis
# install and run
sudo apt install imud imud-wmm-data
sudo systemctl enable --now imud
# or invoke it directly
imud [--config PATH] [--replay FILE] [--version]Description
imud owns the inertial sensor and does the hard real-time work exactly once: interrupt-driven sampling, calibration, sensor fusion, and precise hardware timestamps. It then publishes a clean attitude, heading, and motion estimate on standard interfaces that any number of programs can read at the same time.
Instead of every application re-implementing I²C drivers and a Kalman filter, you run one small daemon and consume its output. Like gpsd, it is meant to be boring, always-on infrastructure: start it, forget it, and point your software at the stream.
IMU + magnetometer (I²C) consumers
│ ┌────────────────────────────┐
▼ │ chartplotter / autopilot │
┌─────────────────┐ NMEA 0183 ───▶│ ROS2 node │
│ imud │ binary UDP ──▶│ vision / stabilization │
│ drivers·MEKF· │ AF_UNIX ──▶│ gimbal / dish pointing │
│ timestamps │ │ loggers, dashboards, … │
└─────────────────┘ └────────────────────────────┘It is written in C and depends only on libgpiod and the C
standard library. The license is MIT.
Features
- Owns the sensor, once.
- Drains the IMU FIFO on a hardware interrupt, applies calibration, and runs a quaternion MEKF at the full sample rate — so consumers get a fused estimate, not raw samples to process themselves.
- Publishes to many consumers at once.
- NMEA 0183 (UDP broadcast or a TCP listener that plotters simply connect to), a high-rate binary packet over UDP, and a loss-free stream of framed packets over a local AF_UNIX socket or TCP — so several programs share one IMU without contention.
- Clean, well-defined outputs.
- Quaternion, Euler angles, magnetic and true heading, rate of turn, heave, sea-state statistics (significant wave height and period, roll and pitch periods and amplitudes), compass-health diagnostics, and the attitude covariance — each carrying wall-clock, TAI, and per-sample hardware timestamps for correlation with cameras and other sensors.
- Pluggable hardware.
- A thin driver layer hides chip differences behind one interface, so
swapping sensors is a config change rather than a rewrite. A
simdriver runs the entire pipeline with no hardware at all. - A flight recorder built in.
- The capture black box records every raw sensor sample to rotating
files.
imud --replayplays a capture back through the full pipeline, andimud-calmeasures your unit's actual noise (Allan variance) and gyro temperature drift from those same files. - An ABI-stable client library.
libimuddecodes the binary stream for C programs and keeps working across daemon upgrades without recompiling. A single-file Python client ships too, and there is an Arduino/ESP32 client in its own repository.- Built to run unattended.
- A hardened systemd unit with a watchdog, calibration tools, level-gated logging, and a status socket for health queries.
Use cases
imud is output-agnostic — the same daemon serves very different consumers.
- Marine navigation
- NMEA 0183 to chartplotters, autopilots, and Signal K, with true heading
from the World Magnetic Model, heave, and live sea-state statistics. This is
the most exercised use case today, and several fusion options are tuned for
it. The
imud-signalkbridge feeds Signal K natively over UDP or TCP where NMEA parsing falls short. - Robotics and ROS2
- Attitude and rate of turn over the binary stream, at the sensor's full rate rather than a decimated NMEA cadence.
- Drones and autopilots
- The
imud-mavlinkbridge feeds MAVLink ATTITUDE messages to ArduPilot, PX4, or QGroundControl over UDP, serial, or TCP. - IoT, home automation, and dashboards
imud-mqttpublishes heading, attitude, and heave to an MQTT broker with Home Assistant auto-discovery;imud-influxdbwrites line-protocol points to InfluxDB for Grafana;imud-prometheusserves a/metricsendpoint for Prometheus scraping and alerting.- Machine vision and camera stabilization
- High-rate quaternion with hardware timestamps, for frame-accurate correlation between motion and imagery.
- Gimbals, pan/tilt rigs, and antenna pointing
- Low-latency attitude over the local stream socket or binary UDP.
Installation
Prebuilt, signed packages for Raspberry Pi OS and Debian — arm64 and armhf, suites bookworm and trixie — are in the imud apt repository. The suite is read from your machine, so these are the same four commands on either release:
# 1. Trust the signing key
curl -fsSL https://richcreations.github.io/imud/apt/KEY.gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/imud.gpg
# 2. Add the repository (suite detected from /etc/os-release)
sudo tee /etc/apt/sources.list.d/imud.sources >/dev/null <<EOF
Types: deb
URIs: https://richcreations.github.io/imud/apt
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: main
Signed-By: /usr/share/keyrings/imud.gpg
EOF
# 3. Install the daemon + World Magnetic Model data
sudo apt update && sudo apt install imud imud-wmm-data
# 4. Edit for your hardware, then start on boot
sudo nano /etc/imud/imud.conf
sudo systemctl enable --now imudThe optional bridges and the network monitor are separate packages —
imud-signalk, imud-mqtt, imud-influxdb,
imud-mavlink, imud-prometheus,
imud-utils. See the
apt repository page for the full package list.
On any other Linux host with I²C, build from source:
sudo apt update && sudo apt install -y build-essential libgpiod-dev
make
sudo make install
sudo make install-wmm-data # World Magnetic Model (for true heading)
sudo nano /etc/imud/imud.conf
sudo systemctl enable --now imudOnce it is running, imud-status reports daemon health,
attitude, declination, and heave; imud-mon gives a live view of
the output streams from any host on the network.
No hardware yet? Run the whole pipeline in simulation, or replay a capture recorded on a real vessel:
imud --config config/sim.conf # synthetic scenario
imud --replay session.imucap # recorded raw sensor dataBefore first real use, calibrate: imud-cal gyro,
imud-cal accel, and an in-situ imud-cal mag.
Output formats
| Output | Transport | For |
|---|---|---|
| NMEA 0183 | UDP broadcast, or TCP :10110 | Chartplotters, autopilots, Signal K |
| Binary packet | UDP :10111 | High-rate quaternion for vision and control |
| Framed stream | AF_UNIX socket, or TCP :10112 | Loss-free local consumers, bridges, libimud |
A stock install emits on the local AF_UNIX socket and nothing else; each
network output has to be switched on deliberately in
/etc/imud/imud.conf. If you just need heading, pitch, and roll
for a chartplotter, turn on the NMEA TCP listener and point your app at
tcp://<host>:10110.
Hardware
- Reference
- SparkFun 9DoF IMU Breakout — ST ISM330DHCX (gyro + accelerometer) with a MEMSIC MMC5983MA magnetometer. This is the best-tested combination.
- Experimental drivers
- ST LSM6DSO, TDK InvenSense ICM-20948, ICM-42688-P, MPU-9250 and
MPU-9255; magnetometers ST LIS2MDL and LIS3MDL, and AKM AK09916 and
AK8963.
imud-imutestis how one of these gets promoted: run it against the part and attach the report. - No hardware
- The
simdriver runs the full pipeline from a synthetic scenario or a recorded capture file, on any Linux machine.
Host side, imud targets the Raspberry Pi — it drives the sensor over I²C and takes the data-ready interrupt on a GPIO line via libgpiod — but nothing in it is Pi-specific beyond that.
Bridges and clients
- Protocol bridges
- Five optional daemons read the local stream socket and re-publish it:
imud-signalk(Signal K deltas),imud-mqtt(MQTT + Home Assistant discovery),imud-influxdb(line protocol for Grafana),imud-mavlink(MAVLink v1/v2 to autopilots), andimud-prometheus(a/metricsendpoint). Each is self-contained, with its own config file and man page. - Client libraries
libimudis the ABI-stable C library for the binary stream. A single-file Python client ships with the daemon, and ImudClient provides an Arduino/ESP32 client over TCP or UDP — header-only, no heap, for cockpit displays and telemetry heads.- Tools
imud-calfor gyro, accelerometer, and magnetometer calibration;imud-statusto query a running daemon;imud-monfor a live network view of the streams;imud-imutestto validate a sensor driver against real hardware and write a report worth attaching to an issue.
Reporting bugs and contributing
- Report a bug or request a feature
- Open an issue at
github.com/richcreations/imud/issues.
For a driver problem, attach an
imud-imutest --allreport — it captures the hardware, the timing, and every check the daemon relies on, which is most of what a diagnosis needs. - Search past reports
- Every report and the replies to it stay public and searchable: all issues, open and closed. Worth checking before filing — and worth reading afterwards, since the reasoning behind a fix usually lives in the thread rather than the commit.
- Report a security vulnerability
- Please do not open a public issue. Use GitHub's private vulnerability reporting, as described in SECURITY.md, which also states the supported versions and the response timeline.
- Contribute code or documentation
- CONTRIBUTING.md
covers the build, the test suite (
make test), the coding conventions, and the doc-sync rules — this project keeps the same facts in several places on purpose, so a change is not finished until its manual, man page and spec entries agree. Pull requests are welcome; CI runs the full suite on amd64, arm64 and armhf, under sanitizers, and against the fuzzers. - Clearing an experimental driver flag
- Ten of the twelve sensor drivers have never run on physical silicon.
If you have one of those parts, an
imud-imutestreport attached to an issue is what clears its flag — see the roadmap. - Code of conduct
- Contributor Covenant.
See also
- Source on GitHub — the full repository, issues, and pull requests.
- Issue tracker — bug reports and enhancement requests.
- Contributing — how to build, test, and submit a change.
- Releases — tagged versions and release notes.
- Manual — installation, the complete configuration reference, calibration, output streams, monitoring, troubleshooting, and how to write a driver.
- Protocol spec — architecture, the binary packet layout, NMEA sentence formats, and the timestamp design.
- Capture & replay — the black box, playback, and offline noise and temperature analysis.
- apt repository — Debian and Raspberry Pi OS packages.
- ImudClient — the Arduino/ESP32 client library for the binary stream.
Installed man pages: imud(8), imud-cal(8),
imud.conf(5), imud-status(1),
libimud(3), and one per bridge.
Author
Written by Richard Simpson. Released under the MIT license.