/* * 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. * #define GYRO_CAL_DBG_TUNE_ENABLED to periodically printout sensor variance * data to assist in tuning the GyroCal parameters. */ #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 __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 { uint64_t start_still_time_nanos; uint64_t end_still_time_nanos; uint64_t stillness_duration_nanos; float mean_sampling_rate_hz; 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_max_celsius[2]; // 0=min; 1=max float temperature_mean_celsius; bool using_mag_sensor; }; #endif struct GyroCal { // Stillness detectors. struct GyroStillDet accel_stillness_detect; struct GyroStillDet mag_stillness_detect; struct GyroStillDet gyro_stillness_detect; // 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; bool gyro_watchdog_timeout; // 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; // Computes the min/max/mean temperature over the stillness period. This is // used to check the temperature stability and provide a gate for when // temperature is rapidly changing. float temperature_min_max_celsius[2]; // 0=min; 1=max 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. 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, uint64_t min_still_duration, uint64_t max_still_duration_nanos, float bias_x, float bias_y, float bias_z, uint64_t calibration_time_nanos, uint64_t window_time_duration_nanos, float gyro_var_threshold, float gyro_confidence_delta, float accel_var_threshold, float accel_confidence_delta, float mag_var_threshold, float mag_confidence_delta, float stillness_threshold, float stillness_mean_delta_limit, float temperature_delta_limit_celsius, bool gyro_calibration_enable); // Void all pointers in the gyro calibration data structure. void gyroCalDestroy(struct GyroCal* gyro_cal); // 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); // Set an initial bias calibration value. void gyroCalSetBias(struct GyroCal* gyro_cal, float bias_x, float bias_y, float bias_z, 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_