Compass: a visual compass from GNSS, with the IMU to fill the gaps #16

Open
opened 2026-10-05 11:56:18 +00:00 by twisla · 0 comments
Owner

Idea

A Compass App with a proper compass look:

  • a rotating rose with N/E/S/W and degree ticks
  • a heading readout
  • a course line
  • optionally, a bearing and distance to a target: a saved place, the start of a Track, or a coordinate

GNSS gives the true heading while you move, and the IMU keeps the rose steady and responsive between fixes and when you turn on the spot.

Why

GNSS is the newest hardware we use, and a compass is its most natural visual App. A bearing to a point ("the car is 340 m that way") is the useful part when hiking or looking for something.

What's known

  • No magnetometer. The Cardputer ADV's IMU (a BMI270, per M5Stack's specs, to be confirmed) has an accelerometer and a gyroscope but no magnetometer. So the device can't find north on its own while standing still.
  • GNSS heading.
    • The parser already reads course and speed (lib/gnss/src/nmea_parser.cpp:150), and the GNSS App shows them above 1 km/h.
    • Course over ground from RMC/VTG is the direction of travel, not the way the device points. It's reliable above a walking pace (roughly 2-3 km/h), and noise when standing still.
    • Updates come at 1 Hz from the ATGM336H. Some modules can do 5 or 10 Hz, at a power cost, and that's a $PCAS02 setting to check.
  • The IMU.
    • On the internal I2C bus with the keyboard controller (GPIO 8 and 9, per M2's notes). Through M5Unified as M5.Imu, or a small driver of our own.
    • The gyroscope's yaw rate gives fast, smooth heading changes. Integrated alone, it drifts by a few degrees a minute.
    • Fusion: use the gyroscope for short-term changes, and pull it towards GNSS course whenever you're moving fast enough. That's a simple complementary filter, which can be host-tested with recorded data.
    • The accelerometer gives tilt, which tells whether the device is held flat, and can drive a bubble level.
  • Standing still with no magnetometer, there's no absolute north. Options:
    • Keep the last known heading and let the gyroscope follow turns, with an indication that the reference is ageing.
    • A sun compass: from the time and position (both known), compute the sun's azimuth. Point the top of the device at the sun, and the rose is calibrated. That's pure maths, host-testable, and it fits the device well. The same works with the moon.
    • An external magnetometer on the Grove port (for example a BMM150 or QMC5883L unit). That gives a real compass, at the cost of calibration (hard and soft iron) and tilt compensation.
  • Visuals.
    • A rose drawn with anti-aliased lines on the RGB332 canvas, rotating smoothly. Measure the frame rate: at 20+ fps it feels like a real compass.
    • Readouts: heading in degrees and cardinal points (NNE…), speed, and the heading's source (GNSS, gyro, sun) with its age.
    • Target mode: an arrow to the target, its distance, and an ETA at the current speed. Targets are Tracks' waypoints, a saved place list, or typed coordinates.
  • Power. The GNSS is in standby when nothing uses it (M2). The Compass wakes it like the GNSS App does. The IMU is cheap to run.

Questions for the design round

  1. Should it be an App of its own, or a third view in the GNSS App, next to Position and Sky?
  2. What happens when standing still: hold the last heading with the gyroscope, the sun compass, or both?
  3. Should it support an external magnetometer on Grove now, or later?
  4. Targets: where do they come from (saved places, Tracks, typed coordinates, Gemini links?), and where are they stored?
  5. Should it show the declination (true vs. magnetic north)? It only matters if a magnetometer is added.
  6. Should it ask for a higher GNSS update rate (5 Hz) while the Compass is open?
  7. Extras: a bubble level from the accelerometer, a sunrise/sunset readout?

Related

lib/gnss/src/nmea_parser.cpp (course and speed), src/apps/gnss_app.cpp, src/services/gnss_service.cpp (standby and wake), docs/milestones/M2.md, #9 (Launcher icon), #10 (themes).

## Idea A Compass App with a proper compass look: - a rotating rose with N/E/S/W and degree ticks - a heading readout - a course line - optionally, a bearing and distance to a target: a saved place, the start of a Track, or a coordinate GNSS gives the true heading while you move, and the IMU keeps the rose steady and responsive between fixes and when you turn on the spot. ## Why GNSS is the newest hardware we use, and a compass is its most natural visual App. A bearing to a point ("the car is 340 m that way") is the useful part when hiking or looking for something. ## What's known - **No magnetometer.** The Cardputer ADV's IMU (a BMI270, per M5Stack's specs, to be confirmed) has an accelerometer and a gyroscope but no magnetometer. So the device can't find north on its own while standing still. - **GNSS heading.** - The parser already reads course and speed (`lib/gnss/src/nmea_parser.cpp:150`), and the GNSS App shows them above 1 km/h. - Course over ground from RMC/VTG is the direction of travel, not the way the device points. It's reliable above a walking pace (roughly 2-3 km/h), and noise when standing still. - Updates come at 1 Hz from the ATGM336H. Some modules can do 5 or 10 Hz, at a power cost, and that's a `$PCAS02` setting to check. - **The IMU.** - On the internal I2C bus with the keyboard controller (GPIO 8 and 9, per M2's notes). Through M5Unified as `M5.Imu`, or a small driver of our own. - The gyroscope's yaw rate gives fast, smooth heading changes. Integrated alone, it drifts by a few degrees a minute. - Fusion: use the gyroscope for short-term changes, and pull it towards GNSS course whenever you're moving fast enough. That's a simple complementary filter, which can be host-tested with recorded data. - The accelerometer gives tilt, which tells whether the device is held flat, and can drive a bubble level. - **Standing still with no magnetometer**, there's no absolute north. Options: - Keep the last known heading and let the gyroscope follow turns, with an indication that the reference is ageing. - A sun compass: from the time and position (both known), compute the sun's azimuth. Point the top of the device at the sun, and the rose is calibrated. That's pure maths, host-testable, and it fits the device well. The same works with the moon. - An external magnetometer on the Grove port (for example a BMM150 or QMC5883L unit). That gives a real compass, at the cost of calibration (hard and soft iron) and tilt compensation. - **Visuals.** - A rose drawn with anti-aliased lines on the RGB332 canvas, rotating smoothly. Measure the frame rate: at 20+ fps it feels like a real compass. - Readouts: heading in degrees and cardinal points (NNE…), speed, and the heading's source (GNSS, gyro, sun) with its age. - Target mode: an arrow to the target, its distance, and an ETA at the current speed. Targets are Tracks' waypoints, a saved place list, or typed coordinates. - **Power.** The GNSS is in standby when nothing uses it (M2). The Compass wakes it like the GNSS App does. The IMU is cheap to run. ## Questions for the design round 1. Should it be an App of its own, or a third view in the GNSS App, next to Position and Sky? 2. What happens when standing still: hold the last heading with the gyroscope, the sun compass, or both? 3. Should it support an external magnetometer on Grove now, or later? 4. Targets: where do they come from (saved places, Tracks, typed coordinates, Gemini links?), and where are they stored? 5. Should it show the declination (true vs. magnetic north)? It only matters if a magnetometer is added. 6. Should it ask for a higher GNSS update rate (5 Hz) while the Compass is open? 7. Extras: a bubble level from the accelerometer, a sunrise/sunset readout? ## Related `lib/gnss/src/nmea_parser.cpp` (course and speed), `src/apps/gnss_app.cpp`, `src/services/gnss_service.cpp` (standby and wake), `docs/milestones/M2.md`, #9 (Launcher icon), #10 (themes).
twisla added this to the H1 On-board hardware milestone 2026-10-05 20:14:11 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: twisla/roro9stack#16