Add persistent magnetometer calibration and docs
This commit is contained in:
@@ -1,13 +1,267 @@
|
||||
# WAVE_ROVER
|
||||
# WAVE_ROVER Firmware
|
||||
|
||||
Firmware project for the Wave Rover ESP32 platform.
|
||||
ESP32 firmware for the Waveshare `WAVE_ROVER` platform.
|
||||
|
||||
Current working version:
|
||||
This repository tracks the `V1.0` source tree and is the main place for future versioning, fixes, and feature work.
|
||||
|
||||
- `1.0`
|
||||
## Current State
|
||||
|
||||
Highlights in this repo:
|
||||
- Base firmware updated from the local `V0.9` source tree toward the observed `0.95` factory behavior
|
||||
- Internal firmware version set to `1.00`
|
||||
- IMU stack reworked for better stability
|
||||
- Web UI updated
|
||||
- Persistent magnetometer calibration added
|
||||
|
||||
- IMU fixes and calibration improvements
|
||||
- Web UI updates
|
||||
- ESP32 Arduino sketch source for ongoing versioning
|
||||
## Main Changes In V1.0
|
||||
|
||||
- Fixed several IMU/AHRS bugs in the quaternion filter
|
||||
- Hardened QMI8658 and AK09918 I2C reads
|
||||
- Added proper IMU temperature reporting
|
||||
- Added working IMU offset get/set commands
|
||||
- Added runtime magnetometer calibration with flash persistence
|
||||
- Added automatic reload of saved mag offsets on boot
|
||||
- Added IMU calibration state flags to feedback JSON
|
||||
|
||||
## Repository Layout
|
||||
|
||||
- `WAVE_ROVER_V1.0.ino`
|
||||
Main Arduino sketch
|
||||
- `IMU.cpp`, `IMU.h`, `IMU_ctrl.h`
|
||||
IMU fusion, calibration, and command handling
|
||||
- `QMI8658.cpp`, `QMI8658.h`
|
||||
6-axis accelerometer/gyro driver
|
||||
- `AK09918.cpp`, `AK09918.h`
|
||||
Magnetometer driver
|
||||
- `web_page.h`
|
||||
Built-in web UI and JSON helper panel
|
||||
- `data/`
|
||||
Example LittleFS content such as `devConfig.json` and `wifiConfig.json`
|
||||
|
||||
## Build Requirements
|
||||
|
||||
Recommended setup:
|
||||
|
||||
- `Arduino IDE 2.x`
|
||||
- `ESP32` board support by Espressif
|
||||
- Board target: `ESP32 Dev Module`
|
||||
|
||||
ESP32 board manager URL:
|
||||
|
||||
- `https://espressif.github.io/arduino-esp32/package_esp32_index.json`
|
||||
|
||||
Libraries used by this project:
|
||||
|
||||
- `ArduinoJson`
|
||||
- `SCServo`
|
||||
- `Adafruit SSD1306`
|
||||
- `INA219_WE`
|
||||
- `ESP32Encoder`
|
||||
- `PID_v2`
|
||||
- `SimpleKalmanFilter`
|
||||
- `Adafruit ICM20X`
|
||||
- `Adafruit ICM20948`
|
||||
- `Adafruit Unified Sensor`
|
||||
|
||||
Provided by the ESP32 core and normally not installed separately:
|
||||
|
||||
- `WiFi`
|
||||
- `WebServer`
|
||||
- `LittleFS`
|
||||
- `esp_now`
|
||||
- `nvs_flash`
|
||||
- `esp_system`
|
||||
|
||||
## Build And Upload
|
||||
|
||||
### Arduino IDE
|
||||
|
||||
1. Install Arduino IDE 2.x.
|
||||
2. Add the ESP32 board manager URL in Arduino IDE preferences.
|
||||
3. Install `esp32` via Boards Manager.
|
||||
4. Install the libraries listed above with Library Manager.
|
||||
5. Open `WAVE_ROVER_V1.0.ino`.
|
||||
6. Select `ESP32 Dev Module`.
|
||||
7. Select the correct serial port.
|
||||
8. Upload the sketch.
|
||||
|
||||
### LittleFS
|
||||
|
||||
The firmware uses `LittleFS`.
|
||||
|
||||
- `imuConfig.json` is created automatically by the firmware when magnetometer offsets are saved
|
||||
- `data/devConfig.json` and `data/wifiConfig.json` are example files in the repo
|
||||
- If you want the `data/` folder flashed as a filesystem image, use your preferred ESP32 LittleFS upload workflow
|
||||
|
||||
The firmware also calls `LittleFS.begin(true)`, so an empty filesystem can be formatted automatically at boot if needed.
|
||||
|
||||
## IMU And Yaw Guide
|
||||
|
||||
### What Was Fixed
|
||||
|
||||
The original IMU path had multiple issues that could produce unstable or misleading `yaw`:
|
||||
|
||||
- filter integrator terms were not preserved correctly
|
||||
- sample timing was effectively fixed instead of using real elapsed time
|
||||
- quaternion integration used unsafe update ordering
|
||||
- I2C reads for the IMU sensors were fragile
|
||||
- magnetometer offsets were not handled in a reliable workflow
|
||||
|
||||
### Current Yaw Behavior
|
||||
|
||||
`yaw` now works in two stages:
|
||||
|
||||
- relative orientation from the gyro/fusion path
|
||||
- absolute heading correction from the magnetometer when a valid mag calibration is available
|
||||
|
||||
Without a valid magnetometer calibration, `yaw` can still move, but absolute heading quality will be poor.
|
||||
|
||||
## Magnetometer Calibration
|
||||
|
||||
### Goal
|
||||
|
||||
Create a good heading calibration once, save it to flash, and automatically reload it on every boot.
|
||||
|
||||
### Start Calibration
|
||||
|
||||
Send:
|
||||
|
||||
```json
|
||||
{"T":145}
|
||||
```
|
||||
|
||||
This starts a magnetometer calibration session.
|
||||
|
||||
### During Calibration
|
||||
|
||||
For about 12 seconds:
|
||||
|
||||
- rotate the rover slowly through a full turn
|
||||
- change orientation gently so the sensor sees different magnetic angles
|
||||
- avoid fast shaking
|
||||
- avoid strong magnets, steel tables, speakers, power bricks, or large metal objects nearby
|
||||
|
||||
### Check Progress
|
||||
|
||||
Send:
|
||||
|
||||
```json
|
||||
{"T":126}
|
||||
```
|
||||
|
||||
Important feedback fields:
|
||||
|
||||
- `magCal`
|
||||
`1` means a valid heading calibration is active
|
||||
- `magSaved`
|
||||
`1` means offsets were saved to flash
|
||||
- `magCalRunning`
|
||||
`1` while calibration is still collecting data
|
||||
- `magCalProgress`
|
||||
progress from `0` to `100`
|
||||
|
||||
### Successful Result
|
||||
|
||||
After a successful run:
|
||||
|
||||
- offsets are written to `/imuConfig.json`
|
||||
- saved offsets are loaded automatically at boot
|
||||
- manual rotation on every startup is no longer required
|
||||
|
||||
### If Calibration Fails
|
||||
|
||||
If `magCal` stays `0`:
|
||||
|
||||
- run `{"T":145}` again
|
||||
- rotate slower
|
||||
- cover more angles
|
||||
- move away from magnetic or metal interference
|
||||
|
||||
If `magSaved` is `0` after a good calibration:
|
||||
|
||||
- check that `LittleFS` mounted successfully
|
||||
- reflash and retry
|
||||
|
||||
## IMU JSON Commands
|
||||
|
||||
### Read IMU Data
|
||||
|
||||
```json
|
||||
{"T":126}
|
||||
```
|
||||
|
||||
Returns roll, pitch, yaw, accel, gyro, mag, temperature, and calibration state flags.
|
||||
|
||||
### Recalibrate Gyro/Accel Bias
|
||||
|
||||
Keep the rover still on a stable surface, then send:
|
||||
|
||||
```json
|
||||
{"T":127}
|
||||
```
|
||||
|
||||
This is not the same as a full magnetometer calibration.
|
||||
|
||||
### Get Current Magnetometer Offsets
|
||||
|
||||
```json
|
||||
{"T":128}
|
||||
```
|
||||
|
||||
### Set Magnetometer Offsets Manually
|
||||
|
||||
```json
|
||||
{"T":129,"x":-12,"y":0,"z":0}
|
||||
```
|
||||
|
||||
Manual offsets are also saved to flash automatically in `V1.0`.
|
||||
|
||||
### Start Magnetometer Calibration
|
||||
|
||||
```json
|
||||
{"T":145}
|
||||
```
|
||||
|
||||
## Base Feedback
|
||||
|
||||
Base feedback also exposes the IMU calibration state:
|
||||
|
||||
```json
|
||||
{"T":130}
|
||||
```
|
||||
|
||||
Useful fields:
|
||||
|
||||
- `r`
|
||||
- `p`
|
||||
- `y`
|
||||
- `magCal`
|
||||
- `magSaved`
|
||||
- `magCalRunning`
|
||||
- `magCalProgress`
|
||||
- `temp`
|
||||
|
||||
## Yaw Troubleshooting
|
||||
|
||||
If `yaw` still looks wrong:
|
||||
|
||||
1. Run `{"T":145}`.
|
||||
2. Rotate the rover slowly until calibration completes.
|
||||
3. Check `{"T":126}` and confirm:
|
||||
- `magCal = 1`
|
||||
- `magSaved = 1`
|
||||
- `magCalRunning = 0`
|
||||
4. Reboot and verify the values are still loaded.
|
||||
|
||||
If `yaw` is stable but mirrored or rotated by a fixed amount, the next thing to tune is axis convention or declination, not the calibration storage itself.
|
||||
|
||||
## Notes
|
||||
|
||||
- Build artifacts such as `build/`, `*.bin`, `*.elf`, and `*.map` are ignored in Git
|
||||
- `imuConfig.json` is generated on-device and is not meant to be versioned in this repo
|
||||
- This repo currently tracks source, not release binaries
|
||||
|
||||
## Official References
|
||||
|
||||
- Arduino IDE: <https://docs.arduino.cc/software/ide/>
|
||||
- Arduino-ESP32 install guide: <https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html>
|
||||
- esptool install guide: <https://docs.espressif.com/projects/esptool/en/latest/installation.html>
|
||||
|
||||
Reference in New Issue
Block a user