| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| * This module contains the algorithms for producing a gyroscope offset |
| * calibration. The algorithm looks for periods of stillness as indicated by |
| * accelerometer, magnetometer and gyroscope, and computes a bias estimate by |
| * taking the average of the gyroscope during the stillness times. |
| * |
| * Currently, this algorithm is tuned such that the device is only considered |
| * still when the device is on a stationary surface (e.g., not on a person). |
| * |
| * NOTE - Time units are agnostic (i.e., determined by the user's application |
| * and usage). However, typical time units are nanoseconds. |
| * |
| * Required Sensors and Units: |
| * - Gyroscope [rad/sec] |
| * - Accelerometer [m/sec^2] |
| * |
| * Optional Sensors and Units: |
| * - Magnetometer [micro-Tesla, uT] |
| * - Temperature [Celsius] |
| * |
| * #define GYRO_CAL_DBG_ENABLED to enable debug printout statements. |
| */ |
| |
| #ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_GYROSCOPE_GYRO_CAL_H_ |
| #define LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_GYROSCOPE_GYRO_CAL_H_ |
| |
| #include "calibration/gyroscope/gyro_stillness_detect.h" |
| |
| #ifdef GYRO_CAL_DBG_ENABLED |
| #include "calibration/sample_rate_estimator/sample_rate_estimator.h" |
| #endif // GYRO_CAL_DBG_ENABLED |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #ifdef GYRO_CAL_DBG_ENABLED |
| // Debug printout state enumeration. |
| enum GyroCalDebugState { |
| GYRO_IDLE = 0, |
| GYRO_WAIT_STATE, |
| GYRO_PRINT_OFFSET, |
| GYRO_PRINT_STILLNESS_DATA, |
| GYRO_PRINT_SAMPLE_RATE_AND_TEMPERATURE, |
| GYRO_PRINT_GYRO_MINMAX_STILLNESS_MEAN, |
| GYRO_PRINT_ACCEL_STATS, |
| GYRO_PRINT_GYRO_STATS, |
| GYRO_PRINT_MAG_STATS |
| }; |
| |
| // Gyro Cal debug information/data tracking structure. |
| struct DebugGyroCal { |
| struct SampleRateEstimator sample_rate_estimator; |
| uint64_t start_still_time_nanos; |
| uint64_t end_still_time_nanos; |
| uint64_t stillness_duration_nanos; |
| float accel_stillness_conf; |
| float gyro_stillness_conf; |
| float mag_stillness_conf; |
| float calibration[3]; |
| float accel_mean[3]; |
| float gyro_mean[3]; |
| float mag_mean[3]; |
| float accel_var[3]; |
| float gyro_var[3]; |
| float mag_var[3]; |
| float gyro_winmean_min[3]; |
| float gyro_winmean_max[3]; |
| float temperature_min_celsius; |
| float temperature_max_celsius; |
| float temperature_mean_celsius; |
| bool using_mag_sensor; |
| }; |
| #endif // GYRO_CAL_DBG_ENABLED |
| |
| // GyroCal algorithm parameters (see GyroCal and GyroStillDet for details). |
| struct GyroCalParameters { |
| uint64_t min_still_duration_nanos; |
| uint64_t max_still_duration_nanos; |
| uint64_t calibration_time_nanos; |
| uint64_t window_time_duration_nanos; |
| float bias_x; // units: radians per second |
| float bias_y; |
| float bias_z; |
| float stillness_threshold; // units: (radians per second)^2 |
| float stillness_mean_delta_limit; // units: radians per second |
| float gyro_var_threshold; // units: (radians per second)^2 |
| float gyro_confidence_delta; // units: (radians per second)^2 |
| float accel_var_threshold; // units: (meters per second)^2 |
| float accel_confidence_delta; // units: (meters per second)^2 |
| float mag_var_threshold; // units: micro-tesla^2 |
| float mag_confidence_delta; // units: micro-tesla^2 |
| float temperature_delta_limit_celsius; |
| bool gyro_calibration_enable; |
| }; |
| |
| // Data structure for tracking min/max window mean during device stillness. |
| struct MinMaxWindowMeanData { |
| float gyro_winmean_min[3]; |
| float gyro_winmean_max[3]; |
| }; |
| |
| // Data structure for tracking temperature data during device stillness. |
| struct TemperatureMeanData { |
| float temperature_min_celsius; |
| float temperature_max_celsius; |
| float latest_temperature_celsius; |
| float mean_accumulator; |
| size_t num_points; |
| }; |
| |
| struct GyroCal { |
| // Stillness detectors. |
| struct GyroStillDet accel_stillness_detect; |
| struct GyroStillDet mag_stillness_detect; |
| struct GyroStillDet gyro_stillness_detect; |
| |
| // Data for tracking temperature mean during periods of device stillness. |
| struct TemperatureMeanData temperature_mean_tracker; |
| |
| // Data for tracking gyro mean during periods of device stillness. |
| struct MinMaxWindowMeanData window_mean_tracker; |
| |
| // Aggregated sensor stillness threshold required for gyro bias calibration. |
| float stillness_threshold; |
| |
| // Min and max durations for gyro bias calibration. |
| uint64_t min_still_duration_nanos; |
| uint64_t max_still_duration_nanos; |
| |
| // Duration of the stillness processing windows. |
| uint64_t window_time_duration_nanos; |
| |
| // Timestamp when device started a still period. |
| uint64_t start_still_time_nanos; |
| |
| // Gyro offset estimate, and the associated calibration temperature, |
| // timestamp, and stillness confidence values. |
| float bias_x, bias_y, bias_z; // [rad/sec] |
| float bias_temperature_celsius; |
| float stillness_confidence; |
| uint64_t calibration_time_nanos; |
| |
| // Current window end-time for all sensors. Used to assist in keeping |
| // sensor data collection in sync. On initialization this will be set to |
| // zero indicating that sensor data will be dropped until a valid end-time |
| // is set from the first gyro timestamp received. |
| uint64_t stillness_win_endtime_nanos; |
| |
| // Watchdog timer to reset to a known good state when data capture stalls. |
| uint64_t gyro_watchdog_start_nanos; |
| uint64_t gyro_watchdog_timeout_duration_nanos; |
| |
| // Flag is "true" when the magnetometer is used. |
| bool using_mag_sensor; |
| |
| // Flag set by user to control whether calibrations are used (default: |
| // "true"). |
| bool gyro_calibration_enable; |
| |
| // Flag is 'true' when a new calibration update is ready. |
| bool new_gyro_cal_available; |
| |
| // Flag to indicate if device was previously still. |
| bool prev_still; |
| |
| // Min and maximum stillness window mean. This is used to check the stability |
| // of the mean values computed for the gyroscope (i.e., provides further |
| // validation for stillness). |
| float gyro_winmean_min[3]; |
| float gyro_winmean_max[3]; |
| float stillness_mean_delta_limit; |
| |
| // The mean temperature over the stillness period. The limit is used to check |
| // for temperature stability and provide a gate for when temperature is |
| // rapidly changing. |
| float temperature_mean_celsius; |
| float temperature_delta_limit_celsius; |
| |
| //---------------------------------------------------------------- |
| |
| #ifdef GYRO_CAL_DBG_ENABLED |
| // Debug info. |
| struct DebugGyroCal debug_gyro_cal; // Debug data structure. |
| enum GyroCalDebugState debug_state; // Debug printout state machine. |
| enum GyroCalDebugState next_state; // Debug state machine next state. |
| uint64_t wait_timer_nanos; // Debug message throttle timer. |
| size_t debug_calibration_count; // Total number of cals performed. |
| size_t debug_watchdog_count; // Total number of watchdog timeouts. |
| bool debug_print_trigger; // Flag used to trigger data printout. |
| #endif // GYRO_CAL_DBG_ENABLED |
| }; |
| |
| /////// FUNCTION PROTOTYPES ////////////////////////////////////////// |
| |
| // Initialize the gyro calibration data structure. |
| void gyroCalInit(struct GyroCal* gyro_cal, |
| const struct GyroCalParameters* parameters); |
| |
| // Get the most recent bias calibration value. |
| void gyroCalGetBias(struct GyroCal* gyro_cal, float* bias_x, float* bias_y, |
| float* bias_z, float* temperature_celsius, |
| uint64_t* calibration_time_nanos); |
| |
| // Set an initial bias calibration value. |
| void gyroCalSetBias(struct GyroCal* gyro_cal, float bias_x, float bias_y, |
| float bias_z, float temperature_celsius, |
| uint64_t calibration_time_nanos); |
| |
| // Remove gyro bias from the calibration [rad/sec]. |
| void gyroCalRemoveBias(struct GyroCal* gyro_cal, float xi, float yi, float zi, |
| float* xo, float* yo, float* zo); |
| |
| // Returns true when a new gyro calibration is available. |
| bool gyroCalNewBiasAvailable(struct GyroCal* gyro_cal); |
| |
| // Update the gyro calibration with gyro data [rad/sec]. |
| void gyroCalUpdateGyro(struct GyroCal* gyro_cal, uint64_t sample_time_nanos, |
| float x, float y, float z, float temperature_celsius); |
| |
| // Update the gyro calibration with mag data [micro Tesla]. |
| void gyroCalUpdateMag(struct GyroCal* gyro_cal, uint64_t sample_time_nanos, |
| float x, float y, float z); |
| |
| // Update the gyro calibration with accel data [m/sec^2]. |
| void gyroCalUpdateAccel(struct GyroCal* gyro_cal, uint64_t sample_time_nanos, |
| float x, float y, float z); |
| |
| #ifdef GYRO_CAL_DBG_ENABLED |
| // Print debug data report. |
| void gyroCalDebugPrint(struct GyroCal* gyro_cal, |
| uint64_t timestamp_nanos_nanos); |
| #endif |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif // LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_GYROSCOPE_GYRO_CAL_H_ |