-
-
Notifications
You must be signed in to change notification settings - Fork 356
Description
Unfortunately, I don't expect to receive any responses, as this repository and issue are used for tracking developer issues, not for users of this library.
In this case, I would like to ask you to open DISCUSSIONS.
Otherwise, the purpose of a community for this repo is lost, IMHO🙄
I'm testing the calibration algorithm for the ICM45686 and QMC6309 sensors.
The magneto algorithm is ideal for the magnetometer, but I'm having trouble calibrating the accelerometer.
I got the code from here:
magneto_acc->current_calibration(A_BAinv);
But usually, the accelerometer is simply fixed along the X, Y, and Z axes and the sign is changed, resulting in six measurements.
And with a magnetometer, should the magnetometer calibration also be performed in a stationary state, or what?
In any case, we move the accelerometer sensor, and accelerations involuntarily occur, no matter how carefully we try to move the axes along the table.
Values ​​obtained after calibration:
I would like an explanation of the calibration algorithm as it applies to the accelerometer, because in my experience, it has been inaccurate🙂
// ACCELEROMETER CALIBRATION (stationary positions)
AccelCalibration calibrateAccelerometer(const vector<Vector3f>& accelData) {
/*
* The accelerometer is calibrated in STILL positions!
* Expected positions (in g units):
* 1. Z up: (0, 0, 1)
* 2. Z down: (0, 0, -1)
* 3. Y up: (0, 1, 0)
* 4. Y down: (0, -1, 0)
* 5. X up: (1, 0, 0)
* 6. X down: (-1, 0, 0)
*/
int n = accelData.size();
if (n < 6) {
cerr << "Error: At least 6 measurements are required to calibrate the accelerometer" << endl;
return AccelCalibration();
}
// Least-squares method for the accelerometer
// Equation: S * (raw - bias) = ​​reference
// where reference is the known gravity vector (0, 0, ±1g, etc.)
// We assume that the data is already split into positions
// In reality, you need to transmit data separately for each position
// Simplified method: calibrating only the offset and scale
Vector3f minVal(10000, 10000, 10000);
Vector3f maxVal(-10000, -10000, -10000);
for (const auto& point : accelData) {
for (int i = 0; i < 3; i++) {
if (point[i] < minVal[i]) minVal[i] = point[i];
if (point[i] > maxVal[i]) maxVal[i] = point[i];
}
}
AccelCalibration result;
// Bias - midpoint of range
result.bias = (minVal + maxVal) / 2.0f;
// Scale factors
// Range should correspond to ±1g = ±9.8 m/s²
Vector3f range = maxVal - minVal;
// Assume full range = 2g (from -1g to +1g)
// If the accelerometer sensitivity is, for example, 16384 LSB/g
result.scale = Matrix3f::Identity();
result.scale(0,0) = 2.0f / range.x(); // To convert to g
result.scale(1,1) = 2.0f / range.y();
result.scale(2,2) = 2.0f / range.z();
result.invScale = result.scale.inverse();
return result;
}I would be happy to discuss the project and my question @Eirenliel
