STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
IMUCalibration.hpp
Go to the documentation of this file.
1#ifndef IMU_CALIBRATION_HPP
2#define IMU_CALIBRATION_HPP
3
4#include <Eigen/Dense>
5#include <array>
6#include <chrono>
7#include <memory>
8#include <mutex>
9#include <vector>
10
11namespace fsw {
12namespace calibration {
13
14/**
15 * @brief IMU Sensor Calibration System
16 *
17 * Calibrates accelerometers, gyroscopes, and magnetometers using:
18 * - Bias estimation
19 * - Scale factor estimation
20 * - Misalignment correction
21 * - Temperature compensation
22 */
24public:
25 /**
26 * @brief Sensor type
27 */
29
30 /**
31 * @brief Calibration status
32 */
41
42 /**
43 * @brief Calibration parameters
44 */
46 Eigen::Vector3d bias; // Bias vector [sensor units]
47 Eigen::Matrix3d scale_matrix; // Scale factor matrix (includes misalignment)
48 Eigen::Matrix3d misalignment; // Misalignment matrix
49 double temperature_coeff = 0.0; // Temperature coefficient
50 double reference_temperature = 25.0; // Reference temperature [°C]
51
52 // Quality metrics
53 double bias_uncertainty; // Bias uncertainty
54 double scale_uncertainty; // Scale uncertainty
55 double calibration_quality; // Overall quality (0-1)
56 };
57
58 /**
59 * @brief Raw sensor reading
60 */
61 struct RawReading {
62 Eigen::Vector3d value; // Raw sensor reading
63 double temperature; // Temperature [°C]
64 std::chrono::steady_clock::time_point timestamp;
65 };
66
67 /**
68 * @brief Calibrated reading
69 */
71 Eigen::Vector3d value; // Calibrated reading
72 Eigen::Matrix3d covariance; // Uncertainty covariance
73 bool valid; // Validity flag
74 };
75
76 /**
77 * @brief Calibration data point
78 */
81 Eigen::Vector3d reference; // Reference/true value
82 double reference_uncertainty; // Reference uncertainty
83 };
84
87
88 /**
89 * @brief Initialize calibration
90 * @param initial_params Initial calibration parameters (optional)
91 */
92 void initialize(const CalibrationParams& initial_params = CalibrationParams{});
93
94 /**
95 * @brief Add calibration data point
96 * @param point Calibration data point
97 */
98 void addCalibrationPoint(const CalibrationPoint& point);
99
100 /**
101 * @brief Perform calibration
102 * @return true if successful
103 */
104 bool calibrate();
105
106 /**
107 * @brief Calibrate accelerometer using static positions
108 *
109 * Requires measurements at multiple orientations (typically 6+ positions)
110 * where gravity is the only acceleration.
111 */
112 bool calibrateAccelerometer(const std::vector<RawReading>& readings);
113
114 /**
115 * @brief Calibrate gyroscope using rotation rates
116 *
117 * Requires measurements during known rotations or zero-velocity periods.
118 */
119 bool calibrateGyroscope(const std::vector<RawReading>& readings,
120 const std::vector<double>& reference_rates = {});
121
122 /**
123 * @brief Calibrate magnetometer using known field
124 *
125 * Requires measurements at multiple orientations in known magnetic field.
126 */
127 bool calibrateMagnetometer(const std::vector<RawReading>& readings,
128 const Eigen::Vector3d& reference_field);
129
130 /**
131 * @brief Apply calibration to raw reading
132 * @param raw Raw sensor reading
133 * @return Calibrated reading
134 */
135 CalibratedReading calibrateReading(const RawReading& raw) const;
136
137 /**
138 * @brief Get calibration parameters
139 */
140 CalibrationParams getCalibrationParams() const;
141
142 /**
143 * @brief Get calibration status
144 */
146
147 /**
148 * @brief Check if calibration is valid
149 */
150 bool isValid() const;
151
152 /**
153 * @brief Reset calibration
154 */
155 void reset();
156
157private:
158 // Calibration algorithms
159 void estimateBias(const std::vector<RawReading>& readings);
160 void estimateScaleAndMisalignment(const std::vector<CalibrationPoint>& points);
161 void estimateTemperatureCoeff(const std::vector<RawReading>& readings,
162 const std::vector<double>& temperatures);
163
164 // Accelerometer-specific calibration
165 bool calibrateAccelStatic(const std::vector<RawReading>& readings);
166
167 // Gyroscope-specific calibration
168 bool calibrateGyroZeroVelocity(const std::vector<RawReading>& readings);
169 bool calibrateGyroRotation(const std::vector<RawReading>& readings,
170 const std::vector<double>& reference_rates);
171
172 // Magnetometer-specific calibration
173 bool calibrateMagEllipsoidFit(const std::vector<RawReading>& readings);
174
175 // Quality assessment
176 double computeCalibrationQuality() const;
177 bool detectDrift(const RawReading& reading) const;
178
182 std::vector<CalibrationPoint> calibration_data_;
183 mutable std::mutex mutex_;
184
185 // Statistics for drift detection
186 std::vector<RawReading> recent_readings_;
187 static constexpr size_t MAX_RECENT_READINGS = 100;
188};
189
190/**
191 * @brief Complete IMU Calibration System
192 *
193 * Manages calibration for all three IMU sensors.
194 */
196public:
199
200 /**
201 * @brief Get calibrator for specific sensor
202 */
203 std::shared_ptr<IMUCalibration> getCalibrator(SensorType type);
204
205 /**
206 * @brief Calibrate all sensors
207 * @param accel_readings Accelerometer readings
208 * @param gyro_readings Gyroscope readings
209 * @param mag_readings Magnetometer readings
210 * @return true if all calibrations successful
211 */
212 bool calibrateAll(const std::vector<IMUCalibration::RawReading>& accel_readings,
213 const std::vector<IMUCalibration::RawReading>& gyro_readings,
214 const std::vector<IMUCalibration::RawReading>& mag_readings,
215 const Eigen::Vector3d& reference_magnetic_field);
216
217 /**
218 * @brief Apply calibration to IMU reading
219 */
226 const IMUCalibration::RawReading& gyro,
227 const IMUCalibration::RawReading& mag) const;
228
229 /**
230 * @brief Get calibration status for all sensors
231 */
238
239private:
240 std::shared_ptr<IMUCalibration> accel_calibrator_;
241 std::shared_ptr<IMUCalibration> gyro_calibrator_;
242 std::shared_ptr<IMUCalibration> mag_calibrator_;
243 mutable std::mutex mutex_;
244};
245
246} // namespace calibration
247} // namespace fsw
248
249#endif // IMU_CALIBRATION_HPP
std::shared_ptr< IMUCalibration > gyro_calibrator_
std::shared_ptr< IMUCalibration > mag_calibrator_
std::shared_ptr< IMUCalibration > getCalibrator(SensorType type)
Get calibrator for specific sensor.
std::shared_ptr< IMUCalibration > accel_calibrator_
bool calibrateAll(const std::vector< IMUCalibration::RawReading > &accel_readings, const std::vector< IMUCalibration::RawReading > &gyro_readings, const std::vector< IMUCalibration::RawReading > &mag_readings, const Eigen::Vector3d &reference_magnetic_field)
Calibrate all sensors.
CalibratedIMU calibrateIMU(const IMUCalibration::RawReading &accel, const IMUCalibration::RawReading &gyro, const IMUCalibration::RawReading &mag) const
bool calibrate()
Perform calibration.
void reset()
Reset calibration.
bool calibrateMagEllipsoidFit(const std::vector< RawReading > &readings)
void estimateBias(const std::vector< RawReading > &readings)
void estimateScaleAndMisalignment(const std::vector< CalibrationPoint > &points)
std::vector< CalibrationPoint > calibration_data_
bool calibrateGyroZeroVelocity(const std::vector< RawReading > &readings)
bool calibrateMagnetometer(const std::vector< RawReading > &readings, const Eigen::Vector3d &reference_field)
Calibrate magnetometer using known field.
std::vector< RawReading > recent_readings_
bool calibrateGyroscope(const std::vector< RawReading > &readings, const std::vector< double > &reference_rates={})
Calibrate gyroscope using rotation rates.
CalibratedReading calibrateReading(const RawReading &raw) const
Apply calibration to raw reading.
bool detectDrift(const RawReading &reading) const
CalibrationParams getCalibrationParams() const
Get calibration parameters.
void estimateTemperatureCoeff(const std::vector< RawReading > &readings, const std::vector< double > &temperatures)
static constexpr size_t MAX_RECENT_READINGS
CalibrationStatus getStatus() const
Get calibration status.
bool calibrateAccelStatic(const std::vector< RawReading > &readings)
void initialize(const CalibrationParams &initial_params=CalibrationParams{})
Initialize calibration.
bool calibrateGyroRotation(const std::vector< RawReading > &readings, const std::vector< double > &reference_rates)
bool calibrateAccelerometer(const std::vector< RawReading > &readings)
Calibrate accelerometer using static positions.
void addCalibrationPoint(const CalibrationPoint &point)
Add calibration data point.
bool isValid() const
Check if calibration is valid.
Output smoothing for calibrated PT pressure, per sensor uid (ESP32 and LabJack T7 alike).
Motorized ball valve position: raw ADC counts -> % open.
std::chrono::steady_clock::time_point timestamp