IMUD(8) System Manager's Manual IMUD(8)

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 sim driver 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 --replay plays a capture back through the full pipeline, and imud-cal measures your unit's actual noise (Allan variance) and gyro temperature drift from those same files.
An ABI-stable client library.
libimud decodes 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-signalk bridge 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-mavlink bridge feeds MAVLink ATTITUDE messages to ArduPilot, PX4, or QGroundControl over UDP, serial, or TCP.
IoT, home automation, and dashboards
imud-mqtt publishes heading, attitude, and heave to an MQTT broker with Home Assistant auto-discovery; imud-influxdb writes line-protocol points to InfluxDB for Grafana; imud-prometheus serves a /metrics endpoint 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 imud

The 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 imud

Once 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 data

Before first real use, calibrate: imud-cal gyro, imud-cal accel, and an in-situ imud-cal mag.

Output formats

OutputTransportFor
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-imutest is how one of these gets promoted: run it against the part and attach the report.
No hardware
The sim driver 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), and imud-prometheus (a /metrics endpoint). Each is self-contained, with its own config file and man page.
Client libraries
libimud is 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-cal for gyro, accelerometer, and magnetometer calibration; imud-status to query a running daemon; imud-mon for a live network view of the streams; imud-imutest to 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 --all report — 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-imutest report attached to an issue is what clears its flag — see the roadmap.
Code of conduct
Contributor Covenant.

See also

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.

imud 1.8 2026-07-31 IMUD(8)