Skip to content

Commit 6881e89

Browse files
author
Zhiquan Yeo
committed
Implement IMU calibration
1 parent 215b996 commit 6881e89

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

include/imu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ void imuSetEnabled(bool enabled);
1414
bool imuIsEnabled();
1515

1616
void imuInit(uint8_t addr, TwoWire *theWire);
17+
void imuCalibrate(unsigned long calibrationTime);
1718

1819
bool imuPeriodic();
1920

src/imu.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "imu.h"
22

3+
#define IMU_DEFAULT_CALIBRATION_TIME_MS 3000
4+
35
namespace xrp {
46

57
unsigned long _imuUpdatePeriod = 1000 / IMU_UPDATE_RATE_HZ;
@@ -40,6 +42,11 @@ void imuInit(uint8_t addr, TwoWire *theWire) {
4042
_imuReady = true;
4143
Serial.println("--- IMU ---");
4244
Serial.println("LSM6DSOX detected");
45+
46+
Serial.println("Setting update rate to 208Hz");
47+
_lsm6.setGyroDataRate(LSM6DS_RATE_208_HZ);
48+
_lsm6.setAccelDataRate(LSM6DS_RATE_208_HZ);
49+
4350
Serial.print("Accel Range: ");
4451
switch (_lsm6.getAccelRange()) {
4552
case LSM6DS_ACCEL_RANGE_2_G:
@@ -79,6 +86,46 @@ void imuInit(uint8_t addr, TwoWire *theWire) {
7986
}
8087
}
8188

89+
void imuCalibrate(unsigned long calibrationTime) {
90+
unsigned long loopDelayTime = 1000 / 208;
91+
92+
if (calibrationTime == 0) {
93+
calibrationTime = IMU_DEFAULT_CALIBRATION_TIME_MS;
94+
}
95+
96+
Serial.printf("[IMU] Beginning calibration. Running for %u ms\n", calibrationTime);
97+
98+
float gyroAvgValues[3] = {0, 0, 0};
99+
int numVals = 0;
100+
101+
unsigned long startTime = millis();
102+
while (millis() < startTime + calibrationTime) {
103+
// Get IMU data
104+
sensors_event_t accel;
105+
sensors_event_t gyro;
106+
sensors_event_t temp;
107+
108+
_lsm6.getEvent(&accel, &gyro, &temp);
109+
110+
gyroAvgValues[0] += _radToDeg(gyro.gyro.x);
111+
gyroAvgValues[1] += _radToDeg(gyro.gyro.y);
112+
gyroAvgValues[2] += _radToDeg(gyro.gyro.z);
113+
114+
numVals++;
115+
delay(loopDelayTime);
116+
}
117+
118+
_gyroOffsetsDegPerSec[0] = gyroAvgValues[0] / numVals;
119+
_gyroOffsetsDegPerSec[1] = gyroAvgValues[1] / numVals;
120+
_gyroOffsetsDegPerSec[2] = gyroAvgValues[2] / numVals;
121+
122+
Serial.printf("[IMU] Offsets: X(%f) Y(%f) Z(%f)\n",
123+
_gyroOffsetsDegPerSec[0],
124+
_gyroOffsetsDegPerSec[1],
125+
_gyroOffsetsDegPerSec[2]);
126+
Serial.println("[IMU] Calibration Complete");
127+
}
128+
82129
bool imuPeriodic() {
83130
if (!_imuReady) return false;
84131
if (!_imuEnabled) return false;

src/main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ void setup() {
108108
Serial.println("[IMU] Initializing IMU");
109109
xrp::imuInit(IMU_I2C_ADDR, &Wire1);
110110

111-
// TODO Calibrate IMU
111+
Serial.println("[IMU] Beginning IMU calibration");
112+
xrp::imuCalibrate(0); // Use the default calibration time
112113

113114
// Busy-loop if there's no WiFi hardware
114115
if (WiFi.status() == WL_NO_MODULE) {

0 commit comments

Comments
 (0)