Home | History | Annotate | Download | only in algos
      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 #ifndef ACCEL_CAL_H_
     17 #define ACCEL_CAL_H_
     18 #include <algos/mat.h>
     19 #include <algos/mag_cal.h>
     20 #include <stdint.h>
     21 #include <sys/types.h>
     22 #ifdef __cplusplus
     23 extern "C" {
     24 #endif
     25 #define ACCEL_CAL_NUM_TEMP_WINDOWS 2
     26 #ifdef ACCEL_CAL_DBG_ENABLED
     27 #define DGB_HISTORY 10
     28 #define TEMP_HISTOGRAM 25
     29 #endif
     30 /* This module estimates the accelerometer offsets using the KASA sphere fit.
     31  * The algorithm senses stillness and classifies the data into seven sphere caps
     32  * (nx,nxb,ny,nyb,nz,nzb,nle). Once the buckets are full the data is used to
     33  * fit the sphere calculating the offsets and the radius. This can be done,
     34  * because when the accelerometer is still it sees only gravity and hence all
     35  * the vectors should end onto a sphere. Furthermore the offset values are
     36  * subtracted from the accelerometer data calibrating the sensor.
     37  */
     38 
     39 // Data struct for the accel stillness detection.
     40 struct accelStillDet_t {
     41 
     42   // Save accumulate variables to calc. mean and var.
     43   float acc_x, acc_y, acc_z;
     44   float acc_xx, acc_yy, acc_zz;
     45 
     46   // Mean and var.
     47   float mean_x, mean_y, mean_z;
     48   float var_x, var_y, var_z;
     49 
     50   // # of samples used in the stillness detector.
     51   uint32_t nsamples;
     52 
     53   // Start timer for a new still detection (in ns).
     54   uint64_t start_time;
     55 
     56   // Controling the Stillness algo with T0 and Th
     57   // time the sensor must be still to trigger still detection.
     58   uint32_t min_batch_window;
     59   uint32_t max_batch_window;
     60 
     61   // Need a minimum amount of samples, filters out low sample rates.
     62   uint32_t min_batch_size;
     63 
     64   // Setting Th to var_th.
     65   float var_th;
     66 
     67   // Total number of stillness.
     68   uint32_t n_still;
     69 };
     70 
     71 /* Struct for good data function.
     72  * Counts the vectors that fall into the 7
     73  * Sphere caps.
     74  */
     75 struct accelGoodData_t {
     76 
     77   // Bucket counters.
     78   uint32_t nx, nxb, ny, nyb, nz, nzb, nle;
     79 
     80   // Bucket full values.
     81   uint32_t nfx, nfxb, nfy, nfyb, nfz, nfzb, nfle;
     82 
     83   // Temp check (in degree C).
     84   float acc_t, acc_tt;
     85   float var_t, mean_t;
     86 
     87   // Eigen Values.
     88   float e_x,e_y,e_z;
     89 };
     90 #ifdef ACCEL_CAL_DBG_ENABLED
     91 // Struct for stats and debug.
     92 struct accelStatsMem_t {
     93 
     94   // Temp (in degree C).
     95   uint32_t t_hist[TEMP_HISTOGRAM];
     96   uint64_t start_time;
     97 
     98   // Offset update counter.
     99   uint32_t noff;
    100   uint32_t noff_max;
    101 
    102   // Offset history.
    103   float var_t[DGB_HISTORY];
    104   float mean_t[DGB_HISTORY];
    105   float x_o[DGB_HISTORY];
    106   float y_o[DGB_HISTORY];
    107   float z_o[DGB_HISTORY];
    108   float e_x[DGB_HISTORY];
    109   float e_y[DGB_HISTORY];
    110   float e_z[DGB_HISTORY];
    111   float rad[DGB_HISTORY];
    112 
    113   uint8_t n_o;
    114   uint64_t cal_time[DGB_HISTORY];
    115 
    116   // Total Buckets counter.
    117   uint32_t ntx, ntxb, nty, ntyb, ntz, ntzb, ntle;
    118 };
    119 #endif
    120 // Struct for an accel calibration for a single temperature window.
    121 struct accelCalAlgo_t  {
    122   struct accelGoodData_t agd;
    123   struct MagCal amoc;
    124 };
    125 
    126 // Complete accel calibration struct.
    127 struct accelCal_t {
    128   struct accelCalAlgo_t ac1[ACCEL_CAL_NUM_TEMP_WINDOWS];
    129   struct accelStillDet_t asd;
    130 #ifdef ACCEL_CAL_DBG_ENABLED
    131   struct accelStatsMem_t adf;
    132 #endif
    133   // Offsets are only updated while the accelerometer is not running. Hence need to store a new offset,
    134   // which gets updated during a power down event.
    135   float x_bias_new, y_bias_new, z_bias_new;
    136 
    137   // Offset values that get subtracted from live data
    138   float x_bias, y_bias, z_bias;
    139 };
    140 
    141 /* This function runs the accel calibration algorithm.
    142  * sample_time_nsec -> is the  sensor timestamp in ns and
    143  *                     is used to check the stillness time.
    144  * x,y,z            -> is the sensor data (m/s^2) for the three axes.
    145  *                     Data is converted to gs inside the function.
    146  * temp             -> is the temperature of the IMU (degree C).
    147  */
    148 void accelCalRun(struct accelCal_t *acc, uint64_t sample_time_nsec,
    149                    float x, float y, float z, float temp);
    150 
    151 /* This function initializes the accCalRun data struct.
    152  * t0     -> Sets the time how long the accel has to be still in ns.
    153  * n_s    -> Defines the minimum number of samples for the stillness.
    154  * th     -> Sets the threshold for the stillness VAR in (g rms)^2.
    155  * fx,fxb,fy,fyb,fz,fzb,fle -> Defines how many counts of data in the
    156  *                             sphere cap (Bucket) is needed to reach full.
    157  */
    158 void accelCalInit(struct accelCal_t *acc, uint32_t t0, uint32_t n_s,float th,
    159                     uint32_t fx, uint32_t fxb, uint32_t fy, uint32_t fyb,
    160                     uint32_t fz, uint32_t fzb, uint32_t fle);
    161 
    162 void accelCalDestroy(struct accelCal_t *acc);
    163 
    164 // Ensures that the offset is only updated during Sensor power down.
    165 bool accelCalUpdateBias(struct accelCal_t *acc,
    166                         float *x, float *y, float *z);
    167 
    168 void accelCalBiasSet(struct accelCal_t *acc,
    169                      float x, float y, float z);
    170 
    171 void accelCalBiasRemove(struct accelCal_t *acc,
    172                         float *x, float *y, float *z);
    173 
    174 #ifdef ACCEL_CAL_DBG_ENABLED
    175 void accelCalDebPrint(struct accelCal_t *acc,float temp);
    176 #endif
    177 #ifdef __cplusplus
    178 }
    179 #endif
    180 
    181 #endif  // ACCEL_CAL_H_
    182