Skip to content

UBCSailbot/PLRS-IMU

Repository files navigation

Polaris IMU

CI License C++23 RP2040

This repository contains the IMU firmware for Polaris.

Setup

This project's toolchain is based on PlatformIO, configured for the RP2040.

Nix

A dev shell is provided in flake.nix. If you use direnv, it will load automatically when you enter the directory. Otherwise:

nix develop

Linux

Install Nix using the Determinate installer:

curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
mkdir -p ~/.config/nix/
echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf

Then install direnv through Nix (the apt package is too old to support use flake):

nix profile add nixpkgs#direnv
echo '# Direnv shell hook'
echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
exec bash
direnv allow

macOS

Install Nix using the Determinate installer:

curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
mkdir -p ~/.config/nix/
echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf

Then install direnv through Nix:

nix profile add nixpkgs#direnv
echo '# Direnv shell hook'
echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc
exec zsh
direnv allow

Windows

The recommended path is WSL2 with Ubuntu 24.04. Install WSL2 from PowerShell:

wsl --install -d Ubuntu-24.04

Once in WSL, follow the Linux instructions above.

For flashing, the RP2040 needs to be forwarded from Windows into WSL using usbipd-win:

usbipd list                  # find the RP2040 bus ID
usbipd bind --busid <id>
usbipd attach --wsl --busid <id>

Set up Git and GitHub

Skip this section if you've already configured git and your GitHub credentials.

Configure Git:

git config --global user.email "you@example.com"
git config --global user.name "Your Name"
git config --global core.autocrlf false # Very important you don't miss this on WSL!

Configure the gh Helper (For Logging Into GitHub):

Linux:

sudo apt update && sudo apt install gh

macOS:

brew install gh

Then authenticate:

gh auth login

Build, test, and flash

make test    # host Unity tests
make build   # build firmware
make upload  # flash the RP2040
make format  # clang-format all sources in-place

Run make with no arguments to list all targets.

Python sim

A Python harness at sim/ runs the C++ EKF offline for visualization and tuning. The same filter that ships on the RP2040 runs in the sim, so Q values transfer faithfully. Synthetic trajectories (yaw, heel, pitch), injectable IMU and GNSS noise, and three views are available.

make sim drops into an arrow-key picker — choose a view, then a scenario:

Timeseries — heading, roll, and pitch channels; truth, GNSS measurements, EKF estimate, and open-loop gyro integration overlaid; residual vs truth with ±1σ band on the lower axes:

Sinusoidal scenario with EKF tracking truth inside its +/-1 sigma band

Mounting — calibration geometry: a level hull with the IMU triad rotated by the mount offset and the GNSS baseline arrow:

Mounting view showing a tilted IMU triad and offset GNSS baseline

Simulate — animated 3D boat over a 50 s run; truth (blue), EKF estimate (orange), IMU raw attitude (green), rendered as a GIF. Final frame:

Final frame of the 3D boat animation showing truth, EKF estimate, and IMU raw hulls

A static pose filmstrip is also available via --view pose on the CLI:

Pose filmstrip of a tack in waves

make sim                                        # interactive picker
make sim SCENARIO=wave_tack VIEW=timeseries     # skip the picker
make sim SCENARIO=wave_tack VIEW=simulate
make sim-test                                   # pytest suite
make sim-format                                 # ruff format + check

Direct CLI with noise, EKF, and calibration flags:

cd sim
uv run python -m plrs_sim sim wave_tack --view simulate \
    --duration 50 --seed 7 \
    --gyro-bias 0.02 --gnss-std 2.0 --gnss-dropout 0.1 \
    --q-heading 0.05 \
    --mount-roll 8 --baseline-offset 20 \
    --save /tmp/wave_tack.gif

A 0 for any --gyro-*, --gnss-std, or --mti-attitude-std flag disables that effect. Pass --no-show for headless runs. See python -m plrs_sim sim --help for the full flag list.

Git hooks

Pre-push hooks are tracked in hooks/ and mirror the CI checks (clang-format

  • native tests). If you use direnv, they are installed automatically when you enter the directory. Without direnv, install them once manually:
ln -sf ../../hooks/pre-push .git/hooks/pre-push

Coding style

See CONTRIBUTING.md.

Overview

The goal is heading accuracy of ≤2° on Polaris by fusing IMU and GNSS measurements through a Kalman filter (likely an Extended Kalman Filter given time constraints).

Reference Projects

TinyEKF: Lightweight C/C++ Extended Kalman Filter.

Tuning

See docs/tuning.md for theory, tradeoffs, and the record-and-replay workflow. Summary:

The filter has four parameters in TinyEkfFilter::Config.

q_heading_deg2 and q_bias_deg2_s2 are the load-bearing knobs. Derive starting values from the MTi-3 datasheet rather than guessing:

  • q_heading — gyro noise density (deg/s/√Hz) squared, scaled by dt
  • q_bias — in-run bias stability (deg/s, from the Allan deviation plot) squared

p0_heading_deg2 and p0_bias_deg2_s2 only affect convergence from startup; set them large.

The efficient tuning workflow: capture a session with the serial logger (milestone 1), replay it through the Python sim (milestone 2) with different configs, then flash once.

To diagnose a live filter, log the innovation (gnss_heading - filter_heading). Zero-mean innovations indicate a well-tuned filter; persistently large innovations mean Q is too small.

Hardware

MCU: Raspberry Pi RP2040

MEMS IMU (accelerometer, gyroscope, magnetometer): Xsens MTi-3-5A-T

GNSS kit (dual antenna): Septentrio mosaic-go H

Firmware

FreeRTOS

Roadmap

Milestone Issues
Python Logger Serial capture script, log format, replay utility
Python EKF Sim pybind11 bindings, synthetic data generator, sim runner, plotter
HIL Testing On-device test suite, PIO Remote agent, CI integration

License

GNU General Public License v3.0

About

Polaris' IMU Sensor Fusion Project

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors