Home | History | Annotate | Download | only in gyroscope
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*
     18  * This module contains the algorithms for producing a gyroscope offset
     19  * calibration. The algorithm looks for periods of stillness as indicated by
     20  * accelerometer, magnetometer and gyroscope, and computes a bias estimate by
     21  * taking the average of the gyroscope during the stillness times.
     22  *
     23  * Currently, this algorithm is tuned such that the device is only considered
     24  * still when the device is on a stationary surface (e.g., not on a person).
     25  *
     26  * NOTE - Time units are agnostic (i.e., determined by the user's application
     27  * and usage). However, typical time units are nanoseconds.
     28  *
     29  * Required Sensors and Units:
     30  *       - Gyroscope     [rad/sec]
     31  *       - Accelerometer [m/sec^2]
     32  *
     33  * Optional Sensors and Units:
     34  *       - Magnetometer  [micro-Tesla, uT]
     35  *       - Temperature   [Celsius]
     36  *
     37  * #define GYRO_CAL_DBG_ENABLED to enable debug printout statements.
     38  */
     39 
     40 #ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_GYROSCOPE_GYRO_CAL_H_
     41 #define LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_GYROSCOPE_GYRO_CAL_H_
     42 
     43 #include "calibration/gyroscope/gyro_stillness_detect.h"
     44 
     45 #ifdef GYRO_CAL_DBG_ENABLED
     46 #include "calibration/sample_rate_estimator/sample_rate_estimator.h"
     47 #endif  // GYRO_CAL_DBG_ENABLED
     48 
     49 #ifdef __cplusplus
     50 extern "C" {
     51 #endif
     52 
     53 #ifdef GYRO_CAL_DBG_ENABLED
     54 // Debug printout state enumeration.
     55 enum GyroCalDebugState {
     56   GYRO_IDLE = 0,
     57   GYRO_WAIT_STATE,
     58   GYRO_PRINT_OFFSET,
     59   GYRO_PRINT_STILLNESS_DATA,
     60   GYRO_PRINT_SAMPLE_RATE_AND_TEMPERATURE,
     61   GYRO_PRINT_GYRO_MINMAX_STILLNESS_MEAN,
     62   GYRO_PRINT_ACCEL_STATS,
     63   GYRO_PRINT_GYRO_STATS,
     64   GYRO_PRINT_MAG_STATS
     65 };
     66 
     67 // Gyro Cal debug information/data tracking structure.
     68 struct DebugGyroCal {
     69   struct SampleRateEstimator sample_rate_estimator;
     70   uint64_t start_still_time_nanos;
     71   uint64_t end_still_time_nanos;
     72   uint64_t stillness_duration_nanos;
     73   float accel_stillness_conf;
     74   float gyro_stillness_conf;
     75   float mag_stillness_conf;
     76   float calibration[3];
     77   float accel_mean[3];
     78   float gyro_mean[3];
     79   float mag_mean[3];
     80   float accel_var[3];
     81   float gyro_var[3];
     82   float mag_var[3];
     83   float gyro_winmean_min[3];
     84   float gyro_winmean_max[3];
     85   float temperature_min_celsius;
     86   float temperature_max_celsius;
     87   float temperature_mean_celsius;
     88   bool using_mag_sensor;
     89 };
     90 #endif  // GYRO_CAL_DBG_ENABLED
     91 
     92 // GyroCal algorithm parameters (see GyroCal and GyroStillDet for details).
     93 struct GyroCalParameters {
     94   uint64_t min_still_duration_nanos;
     95   uint64_t max_still_duration_nanos;
     96   uint64_t calibration_time_nanos;
     97   uint64_t window_time_duration_nanos;
     98   float bias_x;  // units: radians per second
     99   float bias_y;
    100   float bias_z;
    101   float stillness_threshold;         // units: (radians per second)^2
    102   float stillness_mean_delta_limit;  // units: radians per second
    103   float gyro_var_threshold;          // units: (radians per second)^2
    104   float gyro_confidence_delta;       // units: (radians per second)^2
    105   float accel_var_threshold;         // units: (meters per second)^2
    106   float accel_confidence_delta;      // units: (meters per second)^2
    107   float mag_var_threshold;           // units: micro-tesla^2
    108   float mag_confidence_delta;        // units: micro-tesla^2
    109   float temperature_delta_limit_celsius;
    110   bool gyro_calibration_enable;
    111 };
    112 
    113 // Data structure for tracking min/max window mean during device stillness.
    114 struct MinMaxWindowMeanData {
    115   float gyro_winmean_min[3];
    116   float gyro_winmean_max[3];
    117 };
    118 
    119 // Data structure for tracking temperature data during device stillness.
    120 struct TemperatureMeanData {
    121   float temperature_min_celsius;
    122   float temperature_max_celsius;
    123   float latest_temperature_celsius;
    124   float mean_accumulator;
    125   size_t num_points;
    126 };
    127 
    128 struct GyroCal {
    129   // Stillness detectors.
    130   struct GyroStillDet accel_stillness_detect;
    131   struct GyroStillDet mag_stillness_detect;
    132   struct GyroStillDet gyro_stillness_detect;
    133 
    134   // Data for tracking temperature mean during periods of device stillness.
    135   struct TemperatureMeanData temperature_mean_tracker;
    136 
    137   // Data for tracking gyro mean during periods of device stillness.
    138   struct MinMaxWindowMeanData window_mean_tracker;
    139 
    140   // Aggregated sensor stillness threshold required for gyro bias calibration.
    141   float stillness_threshold;
    142 
    143   // Min and max durations for gyro bias calibration.
    144   uint64_t min_still_duration_nanos;
    145   uint64_t max_still_duration_nanos;
    146 
    147   // Duration of the stillness processing windows.
    148   uint64_t window_time_duration_nanos;
    149 
    150   // Timestamp when device started a still period.
    151   uint64_t start_still_time_nanos;
    152 
    153   // Gyro offset estimate, and the associated calibration temperature,
    154   // timestamp, and stillness confidence values.
    155   float bias_x, bias_y, bias_z;  // [rad/sec]
    156   float bias_temperature_celsius;
    157   float stillness_confidence;
    158   uint64_t calibration_time_nanos;
    159 
    160   // Current window end-time for all sensors. Used to assist in keeping
    161   // sensor data collection in sync. On initialization this will be set to
    162   // zero indicating that sensor data will be dropped until a valid end-time
    163   // is set from the first gyro timestamp received.
    164   uint64_t stillness_win_endtime_nanos;
    165 
    166   // Watchdog timer to reset to a known good state when data capture stalls.
    167   uint64_t gyro_watchdog_start_nanos;
    168   uint64_t gyro_watchdog_timeout_duration_nanos;
    169 
    170   // Flag is "true" when the magnetometer is used.
    171   bool using_mag_sensor;
    172 
    173   // Flag set by user to control whether calibrations are used (default:
    174   // "true").
    175   bool gyro_calibration_enable;
    176 
    177   // Flag is 'true' when a new calibration update is ready.
    178   bool new_gyro_cal_available;
    179 
    180   // Flag to indicate if device was previously still.
    181   bool prev_still;
    182 
    183   // Min and maximum stillness window mean. This is used to check the stability
    184   // of the mean values computed for the gyroscope (i.e., provides further
    185   // validation for stillness).
    186   float gyro_winmean_min[3];
    187   float gyro_winmean_max[3];
    188   float stillness_mean_delta_limit;
    189 
    190   // The mean temperature over the stillness period. The limit is used to check
    191   // for temperature stability and provide a gate for when temperature is
    192   // rapidly changing.
    193   float temperature_mean_celsius;
    194   float temperature_delta_limit_celsius;
    195 
    196   //----------------------------------------------------------------
    197 
    198 #ifdef GYRO_CAL_DBG_ENABLED
    199   // Debug info.
    200   struct DebugGyroCal debug_gyro_cal;  // Debug data structure.
    201   enum GyroCalDebugState debug_state;  // Debug printout state machine.
    202   enum GyroCalDebugState next_state;   // Debug state machine next state.
    203   uint64_t wait_timer_nanos;           // Debug message throttle timer.
    204   size_t debug_calibration_count;      // Total number of cals performed.
    205   size_t debug_watchdog_count;         // Total number of watchdog timeouts.
    206   bool debug_print_trigger;            // Flag used to trigger data printout.
    207 #endif                                 // GYRO_CAL_DBG_ENABLED
    208 };
    209 
    210 /////// FUNCTION PROTOTYPES //////////////////////////////////////////
    211 
    212 // Initialize the gyro calibration data structure.
    213 void gyroCalInit(struct GyroCal* gyro_cal,
    214                  const struct GyroCalParameters* parameters);
    215 
    216 // Void all pointers in the gyro calibration data structure.
    217 void gyroCalDestroy(struct GyroCal* gyro_cal);
    218 
    219 // Get the most recent bias calibration value.
    220 void gyroCalGetBias(struct GyroCal* gyro_cal, float* bias_x, float* bias_y,
    221                     float* bias_z, float* temperature_celsius,
    222                     uint64_t* calibration_time_nanos);
    223 
    224 // Set an initial bias calibration value.
    225 void gyroCalSetBias(struct GyroCal* gyro_cal, float bias_x, float bias_y,
    226                     float bias_z, float temperature_celsius,
    227                     uint64_t calibration_time_nanos);
    228 
    229 // Remove gyro bias from the calibration [rad/sec].
    230 void gyroCalRemoveBias(struct GyroCal* gyro_cal, float xi, float yi, float zi,
    231                        float* xo, float* yo, float* zo);
    232 
    233 // Returns true when a new gyro calibration is available.
    234 bool gyroCalNewBiasAvailable(struct GyroCal* gyro_cal);
    235 
    236 // Update the gyro calibration with gyro data [rad/sec].
    237 void gyroCalUpdateGyro(struct GyroCal* gyro_cal, uint64_t sample_time_nanos,
    238                        float x, float y, float z, float temperature_celsius);
    239 
    240 // Update the gyro calibration with mag data [micro Tesla].
    241 void gyroCalUpdateMag(struct GyroCal* gyro_cal, uint64_t sample_time_nanos,
    242                       float x, float y, float z);
    243 
    244 // Update the gyro calibration with accel data [m/sec^2].
    245 void gyroCalUpdateAccel(struct GyroCal* gyro_cal, uint64_t sample_time_nanos,
    246                         float x, float y, float z);
    247 
    248 #ifdef GYRO_CAL_DBG_ENABLED
    249 // Print debug data report.
    250 void gyroCalDebugPrint(struct GyroCal* gyro_cal,
    251                        uint64_t timestamp_nanos_nanos);
    252 #endif
    253 
    254 #ifdef __cplusplus
    255 }
    256 #endif
    257 
    258 #endif  // LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_GYROSCOPE_GYRO_CAL_H_
    259