• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <algos/gyro_cal.h>
18 
19 /////// DEFINITIONS AND MACROS ///////////////////////////////////////
20 
21 // Maximum gyro bias correction (should be set based on
22 // expected max bias of the given sensor).
23 #define MAX_GYRO_BIAS 0.096f // [rad/sec]
24 
25 // Helper constants for converting units.
26 #define RAD_TO_MDEG (float)(1e3*180.0/M_PI)
27 #define GRAVITY_TO_G (float)(1.0/9.80665)
28 
29 /////// FORWARD DECLARATIONS /////////////////////////////////////////
30 
31 static void deviceStillnessCheck(struct gyroCal_t* gyro_cal,
32                                  uint64_t sample_time);
33 
34 static void computeGyroCal(struct gyroCal_t* gyro_cal,
35                            uint64_t calibration_time);
36 
37 static void checkWatchdog(struct gyroCal_t* gyro_cal,
38                           uint64_t sample_time);
39 
40 #ifdef GYRO_CAL_DBG_ENABLED
41 static void gyroCalUpdateDebug(struct gyroCal_t* gyro_cal,
42                                struct debugGyroCal_t* debug_gyro_cal);
43 
44 static void gyroCalTuneDebugPrint(struct gyroCal_t* gyro_cal,
45                                   uint64_t sample_time);
46 
47 static void gyroCalDebugPrintData(int count,
48                                   struct debugGyroCal_t *debug_data);
49 
50 // Information print macro.
51 #define GYRO_INFO_PRINT(fmt, ...) do { \
52         osLog(LOG_INFO, "%s " fmt, "[GYRO CAL]", ##__VA_ARGS__); \
53     } while (0);
54 
55 // Macro used to print out floating point numbers.
56 #define GYRO_ENCODE_FLOAT(x, num_digits) ((x < 0) ? "-" : ""), \
57     (int)floorf(fabsf(x)),                                \
58     (int)((fabsf(x) - floorf(fabsf(x))) * powf(10,num_digits))
59 #endif
60 
61 /////// FUNCTION DEFINITIONS /////////////////////////////////////////
62 
63 // Initialize the gyro calibration data structure.
gyroCalInit(struct gyroCal_t * gyro_cal,uint64_t min_still_duration,uint64_t max_still_duration,float bias_x,float bias_y,float bias_z,uint64_t calibration_time,uint64_t window_time_duration,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,int remove_bias_enable)64 void gyroCalInit(struct gyroCal_t* gyro_cal, uint64_t min_still_duration,
65                  uint64_t max_still_duration,
66                  float bias_x, float bias_y, float bias_z,
67                  uint64_t calibration_time,
68                  uint64_t window_time_duration,
69                  float gyro_var_threshold,
70                  float gyro_confidence_delta,
71                  float accel_var_threshold,
72                  float accel_confidence_delta,
73                  float mag_var_threshold,
74                  float mag_confidence_delta,
75                  float stillness_threshold,
76                  int remove_bias_enable) {
77 
78   // Clear gyro_cal structure memory.
79   memset(gyro_cal, 0, sizeof(struct gyroCal_t));
80 
81   // Initialize the stillness detectors.
82   // Gyro parameter input units are [rad/sec]
83   // Accel parameter input units are [m/sec^2]
84   // Magnetometer parameter input units are [uT]
85   gyroStillDetInit(&gyro_cal->gyro_stillness_detect,
86                  gyro_var_threshold,
87                  gyro_confidence_delta);
88   gyroStillDetInit(&gyro_cal->accel_stillness_detect,
89                  accel_var_threshold,
90                  accel_confidence_delta);
91   gyroStillDetInit(&gyro_cal->mag_stillness_detect,
92                  mag_var_threshold,
93                  mag_confidence_delta);
94 
95   // Reset stillness flag and start timestamp.
96   gyro_cal->prev_still = false;
97   gyro_cal->start_still_time = 0;
98 
99   // Set the min and max window stillness duration.
100   gyro_cal->min_still_duration = min_still_duration;
101   gyro_cal->max_still_duration = max_still_duration;
102 
103   // Sets the duration of the stillness processing windows.
104   gyro_cal->window_time_duration = window_time_duration;
105 
106   // Set the watchdog timeout duration.
107   gyro_cal->gyro_watchdog_timeout_duration =
108       2 * window_time_duration;
109 
110   // Load the last valid cal from system memory.
111   gyro_cal->bias_x = bias_x; // [rad/sec]
112   gyro_cal->bias_y = bias_y; // [rad/sec]
113   gyro_cal->bias_z = bias_z; // [rad/sec]
114   gyro_cal->calibration_time = calibration_time;
115 
116   // Set the stillness threshold required for gyro bias calibration.
117   gyro_cal->stillness_threshold = stillness_threshold;
118 
119   // Current window end time used to assist in keeping sensor data
120   // collection in sync. Setting this to zero signals that sensor data
121   // will be dropped until a valid end time is set from the first gyro
122   // timestamp received.
123   gyro_cal->stillness_win_endtime = 0;
124 
125   // Gyro calibrations will be applied (see, gyroCalRemoveBias()).
126   gyro_cal->gyro_calibration_enable = (remove_bias_enable > 0);
127 
128 #ifdef GYRO_CAL_DBG_ENABLED
129   GYRO_INFO_PRINT("Gyro Cal: Initialized.");
130 #endif
131 }
132 
133 // Void all pointers in the gyro calibration data structure
134 // (prevents compiler warnings).
gyroCalDestroy(struct gyroCal_t * gyro_cal)135 void gyroCalDestroy(struct gyroCal_t* gyro_cal) {
136   (void)gyro_cal;
137 }
138 
139 // Get the most recent bias calibration value.
gyroCalGetBias(struct gyroCal_t * gyro_cal,float * bias_x,float * bias_y,float * bias_z)140 void gyroCalGetBias(struct gyroCal_t* gyro_cal,
141                     float* bias_x, float* bias_y, float* bias_z) {
142   if (gyro_cal->gyro_calibration_enable) {
143     *bias_x = gyro_cal->bias_x;
144     *bias_y = gyro_cal->bias_y;
145     *bias_z = gyro_cal->bias_z;
146   }
147 }
148 
149 // Set an initial bias calibration value.
gyroCalSetBias(struct gyroCal_t * gyro_cal,float bias_x,float bias_y,float bias_z,uint64_t calibration_time)150 void gyroCalSetBias(struct gyroCal_t* gyro_cal,
151                     float bias_x, float bias_y, float bias_z,
152                     uint64_t calibration_time) {
153   gyro_cal->bias_x = bias_x;
154   gyro_cal->bias_y = bias_y;
155   gyro_cal->bias_z = bias_z;
156   gyro_cal->calibration_time = calibration_time;
157 }
158 
159 // Remove bias from a gyro measurement [rad/sec].
gyroCalRemoveBias(struct gyroCal_t * gyro_cal,float xi,float yi,float zi,float * xo,float * yo,float * zo)160 void gyroCalRemoveBias(struct gyroCal_t* gyro_cal,
161                        float xi, float yi, float zi,
162                        float* xo, float* yo, float* zo) {
163   if (gyro_cal->gyro_calibration_enable) {
164     *xo = xi - gyro_cal->bias_x;
165     *yo = yi - gyro_cal->bias_y;
166     *zo = zi - gyro_cal->bias_z;
167   }
168 }
169 
170 // Returns true when a new gyro calibration is available.
gyroCalNewBiasAvailable(struct gyroCal_t * gyro_cal)171 bool gyroCalNewBiasAvailable(struct gyroCal_t* gyro_cal) {
172   bool new_gyro_cal_available =
173       (gyro_cal->gyro_calibration_enable &&
174        gyro_cal->new_gyro_cal_available);
175 
176   // Clear the flag.
177   gyro_cal->new_gyro_cal_available = false;
178 
179   return new_gyro_cal_available;
180 }
181 
182 // Update the gyro calibration with gyro data [rad/sec].
gyroCalUpdateGyro(struct gyroCal_t * gyro_cal,uint64_t sample_time,float x,float y,float z,float temperature)183 void gyroCalUpdateGyro(struct gyroCal_t* gyro_cal,
184                        uint64_t sample_time,
185                        float x, float y, float z,
186                        float temperature) {
187 
188   // Make sure that a valid window end time is set,
189   // and start the watchdog timer.
190   if (gyro_cal->stillness_win_endtime <= 0) {
191     gyro_cal->stillness_win_endtime =
192         sample_time + gyro_cal->window_time_duration;
193 
194     // Start the watchdog timer.
195     gyro_cal->gyro_watchdog_start = sample_time;
196   }
197 
198   // Record the latest temperture sample.
199   gyro_cal->latest_temperature_celcius = temperature;
200 
201   // Pass gyro data to stillness detector
202   gyroStillDetUpdate(&gyro_cal->gyro_stillness_detect,
203                      gyro_cal->stillness_win_endtime,
204                      sample_time, x, y, z);
205 
206   // Perform a device stillness check, set next window end time, and
207   // possibly do a gyro bias calibration and stillness detector reset.
208   deviceStillnessCheck(gyro_cal, sample_time);
209 }
210 
211 // Update the gyro calibration with mag data [micro Tesla].
gyroCalUpdateMag(struct gyroCal_t * gyro_cal,uint64_t sample_time,float x,float y,float z)212 void gyroCalUpdateMag(struct gyroCal_t* gyro_cal,
213                       uint64_t sample_time,
214                       float x, float y, float z) {
215 
216   // Pass magnetometer data to stillness detector.
217   gyroStillDetUpdate(&gyro_cal->mag_stillness_detect,
218                      gyro_cal->stillness_win_endtime,
219                      sample_time, x, y, z);
220 
221   // Received a magnetometer sample; incorporate it into detection.
222   gyro_cal->using_mag_sensor = true;
223 
224   // Perform a device stillness check, set next window end time, and
225   // possibly do a gyro bias calibration and stillness detector reset.
226   deviceStillnessCheck(gyro_cal, sample_time);
227 }
228 
229 // Update the gyro calibration with accel data [m/sec^2].
gyroCalUpdateAccel(struct gyroCal_t * gyro_cal,uint64_t sample_time,float x,float y,float z)230 void gyroCalUpdateAccel(struct gyroCal_t* gyro_cal,
231                         uint64_t sample_time,
232                         float x, float y, float z) {
233   // Pass accelerometer data to stillnesss detector.
234   gyroStillDetUpdate(&gyro_cal->accel_stillness_detect,
235                      gyro_cal->stillness_win_endtime,
236                      sample_time, x, y, z);
237 
238   // Perform a device stillness check, set next window end time, and
239   // possibly do a gyro bias calibration and stillness detector reset.
240   deviceStillnessCheck(gyro_cal, sample_time);
241 }
242 
243 // Checks the state of all stillness detectors to determine
244 // whether the device is "still".
deviceStillnessCheck(struct gyroCal_t * gyro_cal,uint64_t sample_time)245 void deviceStillnessCheck(struct gyroCal_t* gyro_cal,
246                           uint64_t sample_time) {
247 
248   bool stillness_duration_exceeded = false;
249   bool stillness_duration_too_short = false;
250   bool device_is_still = false;
251   float conf_not_rot = 0;
252   float conf_not_accel = 0;
253   float conf_still = 0;
254 
255   // Check the watchdog timer.
256   checkWatchdog(gyro_cal, sample_time);
257 
258   // Is there enough data to do a stillness calculation?
259   if ((!gyro_cal->mag_stillness_detect.stillness_window_ready &&
260        gyro_cal->using_mag_sensor) ||
261       !gyro_cal->accel_stillness_detect.stillness_window_ready ||
262       !gyro_cal->gyro_stillness_detect.stillness_window_ready) {
263     return; // Not yet, wait for more data.
264   }
265 
266   // Set the next window end time for the stillness detectors.
267   gyro_cal->stillness_win_endtime =
268       sample_time + gyro_cal->window_time_duration;
269 
270   // Update the confidence scores for all sensors.
271   gyroStillDetCompute(&gyro_cal->accel_stillness_detect);
272   gyroStillDetCompute(&gyro_cal->gyro_stillness_detect);
273   if (gyro_cal->using_mag_sensor) {
274     gyroStillDetCompute(&gyro_cal->mag_stillness_detect);
275   } else {
276     // Not using magnetometer, force stillness confidence to 100%.
277     gyro_cal->mag_stillness_detect.stillness_confidence = 1.0f;
278   }
279 
280   // Determine motion confidence scores (rotation, accelerating, and stillness).
281   conf_not_rot = gyro_cal->gyro_stillness_detect.stillness_confidence *
282       gyro_cal->mag_stillness_detect.stillness_confidence;
283   conf_not_accel = gyro_cal->accel_stillness_detect.stillness_confidence;
284   conf_still = conf_not_rot * conf_not_accel;
285 
286   // determine if the device is currently still.
287   device_is_still = (conf_still > gyro_cal->stillness_threshold);
288 
289   if (device_is_still) {
290 
291     // Device is still logic:
292     // If not previously still, then record the start time.
293     // If stillness period is too long, then do a calibration.
294     // Otherwise, continue collecting stillness data.
295 
296     // If device was not previously still, set new start timestamp.
297     if (!gyro_cal->prev_still) {
298 
299       // Record the starting timestamp of the current stillness window.
300       // This enables the calculation of total duration of the stillness period.
301       gyro_cal->start_still_time =
302           gyro_cal->gyro_stillness_detect.window_start_time;
303     }
304 
305     // Check to see if current stillness period exceeds the desired limit
306     // to avoid corrupting the .
307     stillness_duration_exceeded =
308         ((gyro_cal->gyro_stillness_detect.last_sample_time -
309           gyro_cal->start_still_time) >
310           gyro_cal->max_still_duration);
311 
312     if (stillness_duration_exceeded) {
313 
314       // The current stillness has gone too long. Do a calibration with the
315       // current data and reset.
316 
317       // Update the gyro bias estimate with the current window data and
318       // reset the stats.
319       gyroStillDetReset(&gyro_cal->accel_stillness_detect, true);
320       gyroStillDetReset(&gyro_cal->gyro_stillness_detect, true);
321       gyroStillDetReset(&gyro_cal->mag_stillness_detect, true);
322 
323       // Perform calibration.
324       computeGyroCal(gyro_cal,
325                      gyro_cal->gyro_stillness_detect.last_sample_time);
326 
327       // Update stillness flag. Force the start of a new stillness period.
328       gyro_cal->prev_still = false;
329     } else {
330 
331       // Continue collecting stillness data.
332 
333       // Reset stillness detectors, and extend stillness period.
334       gyroStillDetReset(&gyro_cal->accel_stillness_detect, false);
335       gyroStillDetReset(&gyro_cal->gyro_stillness_detect, false);
336       gyroStillDetReset(&gyro_cal->mag_stillness_detect, false);
337 
338       // Update stillness flag.
339       gyro_cal->prev_still = true;
340     }
341   } else {
342 
343     // Device is NOT still; motion detected.
344 
345     // If device was previously still and the total stillness duration is not
346     // "too short", then do a calibration with the data accumulated thus far.
347     stillness_duration_too_short =
348         ((gyro_cal->gyro_stillness_detect.window_start_time -
349           gyro_cal->start_still_time) < gyro_cal->min_still_duration);
350 
351     if (gyro_cal->prev_still && !stillness_duration_too_short) {
352       computeGyroCal(gyro_cal,
353                      gyro_cal->gyro_stillness_detect.window_start_time);
354     }
355 
356     // Reset stillness detectors and the stats.
357     gyroStillDetReset(&gyro_cal->accel_stillness_detect, true);
358     gyroStillDetReset(&gyro_cal->gyro_stillness_detect, true);
359     gyroStillDetReset(&gyro_cal->mag_stillness_detect, true);
360 
361     // Update stillness flag.
362     gyro_cal->prev_still = false;
363   }
364 
365   // Reset the watchdog timer after we have processed data.
366   gyro_cal->gyro_watchdog_start = sample_time;
367 
368 #ifdef GYRO_CAL_DBG_ENABLED
369   // Debug information available.
370   gyro_cal->debug_processed_data_available = true;
371   gyro_cal->debug_processed_data_time = sample_time;
372 #endif
373 }
374 
375 // Calculates a new gyro bias offset calibration value.
computeGyroCal(struct gyroCal_t * gyro_cal,uint64_t calibration_time)376 void computeGyroCal(struct gyroCal_t* gyro_cal,
377                     uint64_t calibration_time) {
378 
379   // Current calibration duration.
380   uint64_t cur_cal_dur =
381       calibration_time - gyro_cal->start_still_time;
382 
383   // Check to see if new calibration values is within acceptable range.
384   if (!(gyro_cal->gyro_stillness_detect.prev_mean_x < MAX_GYRO_BIAS &&
385         gyro_cal->gyro_stillness_detect.prev_mean_x >-MAX_GYRO_BIAS &&
386         gyro_cal->gyro_stillness_detect.prev_mean_y < MAX_GYRO_BIAS &&
387         gyro_cal->gyro_stillness_detect.prev_mean_y >-MAX_GYRO_BIAS &&
388         gyro_cal->gyro_stillness_detect.prev_mean_z < MAX_GYRO_BIAS &&
389         gyro_cal->gyro_stillness_detect.prev_mean_z >-MAX_GYRO_BIAS)) {
390     // Outside of range. Ignore, reset, and continue.
391     return;
392   }
393 
394   // Record new gyro bias offset calibration.
395   gyro_cal->bias_x = gyro_cal->gyro_stillness_detect.prev_mean_x;
396   gyro_cal->bias_y = gyro_cal->gyro_stillness_detect.prev_mean_y;
397   gyro_cal->bias_z = gyro_cal->gyro_stillness_detect.prev_mean_z;
398 
399   // Record final stillness confidence.
400   gyro_cal->stillness_confidence =
401       gyro_cal->gyro_stillness_detect.prev_stillness_confidence *
402       gyro_cal->accel_stillness_detect.prev_stillness_confidence *
403       gyro_cal->mag_stillness_detect.prev_stillness_confidence;
404 
405   // Store calibration stillness duration.
406   gyro_cal->calibration_time_duration = cur_cal_dur;
407 
408   // Store calibration time stamp.
409   gyro_cal->calibration_time = calibration_time;
410 
411   // Set flag to indicate a new gyro calibration value is available.
412   gyro_cal->new_gyro_cal_available = true;
413 
414 #ifdef GYRO_CAL_DBG_ENABLED
415   // Increment the total count of calibration updates.
416   gyro_cal->debug_calibration_count++;
417 
418   // Store the last 'DEBUG_GYRO_SHORTTERM_NUM_CAL' calibration debug data
419   // in a circular buffer, 'debug_cal_data[]'. 'debug_head' is the index
420   // of the last valid calibration.
421   gyro_cal->debug_head++;
422   if (gyro_cal->debug_head >= DEBUG_GYRO_SHORTTERM_NUM_CAL) {
423     gyro_cal->debug_head = 0;
424   }
425   if (gyro_cal->debug_num_cals < DEBUG_GYRO_SHORTTERM_NUM_CAL) {
426     gyro_cal->debug_num_cals++;
427   }
428 
429   // Update the calibration debug information.
430   gyroCalUpdateDebug(gyro_cal,
431                      &gyro_cal->debug_cal_data[gyro_cal->debug_head]);
432 
433   // Improve the collection of historic calibrations. Limit frequency to
434   // every N hours.
435   if ((gyro_cal->debug_num_cals_hist <= 0) ||
436       (calibration_time -
437        gyro_cal->
438        debug_cal_data_hist[gyro_cal->debug_head_hist].calibration_time)
439       >= DEBUG_GYRO_CAL_LIMIT) {
440     gyro_cal->debug_head_hist++;
441     if (gyro_cal->debug_head_hist >= DEBUG_GYRO_LONGTERM_NUM_CAL) {
442       gyro_cal->debug_head_hist = 0;
443     }
444     if (gyro_cal->debug_num_cals_hist < DEBUG_GYRO_LONGTERM_NUM_CAL) {
445       gyro_cal->debug_num_cals_hist++;
446     }
447 
448     // Update the calibration debug information.
449     gyroCalUpdateDebug(gyro_cal,
450                        &gyro_cal->
451                        debug_cal_data_hist[gyro_cal->debug_head_hist]);
452   }
453 #endif
454 }
455 
456 // Check for a watchdog timeout condition.
checkWatchdog(struct gyroCal_t * gyro_cal,uint64_t sample_time)457 void checkWatchdog(struct gyroCal_t* gyro_cal, uint64_t sample_time) {
458 
459   bool watchdog_timeout;
460 
461   // Check for initialization of the watchdog time (=0).
462   if (gyro_cal->gyro_watchdog_start <= 0) {
463     return;
464   }
465 
466   // Check for timeout condition of watchdog.
467   watchdog_timeout = ((sample_time - gyro_cal->gyro_watchdog_start) >
468                       gyro_cal->gyro_watchdog_timeout_duration);
469 
470   // If a timeout occurred then reset to known good state.
471   if (watchdog_timeout) {
472 
473     // Reset stillness detectors and restart data capture.
474     gyroStillDetReset(&gyro_cal->accel_stillness_detect, true);
475     gyroStillDetReset(&gyro_cal->gyro_stillness_detect, true);
476     gyroStillDetReset(&gyro_cal->mag_stillness_detect, true);
477     gyro_cal->mag_stillness_detect.stillness_confidence = 0;
478     gyro_cal->stillness_win_endtime = 0;
479 
480     // Force stillness confidence to zero.
481     gyro_cal->accel_stillness_detect.prev_stillness_confidence = 0;
482     gyro_cal->gyro_stillness_detect.prev_stillness_confidence = 0;
483     gyro_cal->mag_stillness_detect.prev_stillness_confidence = 0;
484     gyro_cal->stillness_confidence = 0;
485     gyro_cal->prev_still = false;
486 
487     // If there are no magnetometer samples being received then
488     // operate the calibration algorithm without this sensor.
489     if (!gyro_cal->mag_stillness_detect.stillness_window_ready &&
490        gyro_cal->using_mag_sensor) {
491       gyro_cal->using_mag_sensor = false;
492     }
493 
494     // Assert watchdog timeout flags.
495     gyro_cal->gyro_watchdog_timeout |= watchdog_timeout;
496     gyro_cal->gyro_watchdog_start = 0;
497 #ifdef GYRO_CAL_DBG_ENABLED
498     gyro_cal->debug_watchdog_count++;
499 #endif
500   }
501 }
502 
503 #ifdef GYRO_CAL_DBG_ENABLED
504 // Update the calibration debug information.
gyroCalUpdateDebug(struct gyroCal_t * gyro_cal,struct debugGyroCal_t * debug_gyro_cal)505 void gyroCalUpdateDebug(struct gyroCal_t* gyro_cal,
506                         struct debugGyroCal_t* debug_gyro_cal) {
507   // Probability of stillness (acc, rot, still), duration, timestamp.
508   debug_gyro_cal->accel_stillness_conf =
509       gyro_cal->accel_stillness_detect.prev_stillness_confidence;
510   debug_gyro_cal->gyro_stillness_conf =
511       gyro_cal->gyro_stillness_detect.prev_stillness_confidence;
512   debug_gyro_cal->mag_stillness_conf =
513       gyro_cal->mag_stillness_detect.prev_stillness_confidence;
514 
515   // Magnetometer usage.
516   debug_gyro_cal->used_mag_sensor = gyro_cal->using_mag_sensor;
517 
518   // Temperature at calibration time.
519   debug_gyro_cal->temperature_celcius =
520       gyro_cal->latest_temperature_celcius;
521 
522   // Calibration time and stillness duration.
523   debug_gyro_cal->calibration_time_duration =
524       gyro_cal->calibration_time_duration;
525   debug_gyro_cal->calibration_time =
526       gyro_cal->calibration_time;
527 
528   // Record the current calibration values
529   debug_gyro_cal->calibration[0] = gyro_cal->bias_x;
530   debug_gyro_cal->calibration[1] = gyro_cal->bias_y;
531   debug_gyro_cal->calibration[2] = gyro_cal->bias_z;
532 
533   // Record the previous window means
534   debug_gyro_cal->accel_mean[0] =
535       gyro_cal->accel_stillness_detect.prev_mean_x;
536   debug_gyro_cal->accel_mean[1] =
537       gyro_cal->accel_stillness_detect.prev_mean_y;
538   debug_gyro_cal->accel_mean[2] =
539       gyro_cal->accel_stillness_detect.prev_mean_z;
540 
541   debug_gyro_cal->gyro_mean[0] =
542       gyro_cal->gyro_stillness_detect.prev_mean_x;
543   debug_gyro_cal->gyro_mean[1] =
544       gyro_cal->gyro_stillness_detect.prev_mean_y;
545   debug_gyro_cal->gyro_mean[2] =
546       gyro_cal->gyro_stillness_detect.prev_mean_z;
547 
548   debug_gyro_cal->mag_mean[0] =
549       gyro_cal->mag_stillness_detect.prev_mean_x;
550   debug_gyro_cal->mag_mean[1] =
551       gyro_cal->mag_stillness_detect.prev_mean_y;
552   debug_gyro_cal->mag_mean[2] =
553       gyro_cal->mag_stillness_detect.prev_mean_z;
554 
555   // Record the variance data.
556   debug_gyro_cal->accel_var[0] =
557       gyro_cal->accel_stillness_detect.win_var_x;
558   debug_gyro_cal->accel_var[1] =
559       gyro_cal->accel_stillness_detect.win_var_y;
560   debug_gyro_cal->accel_var[2] =
561       gyro_cal->accel_stillness_detect.win_var_z;
562 
563   debug_gyro_cal->gyro_var[0] =
564       gyro_cal->gyro_stillness_detect.win_var_x;
565   debug_gyro_cal->gyro_var[1] =
566       gyro_cal->gyro_stillness_detect.win_var_y;
567   debug_gyro_cal->gyro_var[2] =
568       gyro_cal->gyro_stillness_detect.win_var_z;
569 
570   debug_gyro_cal->mag_var[0] =
571       gyro_cal->mag_stillness_detect.win_var_x;
572   debug_gyro_cal->mag_var[1] =
573       gyro_cal->mag_stillness_detect.win_var_y;
574   debug_gyro_cal->mag_var[2] =
575       gyro_cal->mag_stillness_detect.win_var_z;
576 }
577 
578 // Helper function to print debug statements.
gyroCalDebugPrintData(int count,struct debugGyroCal_t * debug_data)579 void gyroCalDebugPrintData(int count,
580                        struct debugGyroCal_t *debug_data) {
581   GYRO_INFO_PRINT(
582       "#%d Gyro Bias Calibration = {%s%d.%06d, %s%d.%06d, %s%d.%06d} [mdps]\n",
583       count,
584       GYRO_ENCODE_FLOAT(debug_data->calibration[0] * RAD_TO_MDEG, 6),
585       GYRO_ENCODE_FLOAT(debug_data->calibration[1] * RAD_TO_MDEG, 6),
586       GYRO_ENCODE_FLOAT(debug_data->calibration[2] * RAD_TO_MDEG, 6)
587                   );
588 
589   if (debug_data->used_mag_sensor) {
590     GYRO_INFO_PRINT("   Using Magnetometer.\n");
591   } else {
592     GYRO_INFO_PRINT("   Not Using Magnetometer.\n");
593   }
594 
595   GYRO_INFO_PRINT("   Temperature = %s%d.%06d [C]\n",
596                   GYRO_ENCODE_FLOAT(debug_data->temperature_celcius, 6));
597 
598   GYRO_INFO_PRINT("   Calibration Timestamp = %llu [nsec]\n",
599                   debug_data->calibration_time);
600 
601   GYRO_INFO_PRINT("   Stillness Duration = %llu [nsec]\n",
602                   debug_data->calibration_time_duration);
603 
604   GYRO_INFO_PRINT("   Accel Mean = {%s%d.%06d, %s%d.%06d, %s%d.%06d} [g]\n",
605                   GYRO_ENCODE_FLOAT(debug_data->accel_mean[0] *
606                                     GRAVITY_TO_G, 6),
607                   GYRO_ENCODE_FLOAT(debug_data->accel_mean[1] *
608                                     GRAVITY_TO_G, 6),
609                   GYRO_ENCODE_FLOAT(debug_data->accel_mean[2] *
610                                     GRAVITY_TO_G, 6));
611 
612   GYRO_INFO_PRINT("   Mag Mean = {%s%d.%06d, %s%d.%06d, %s%d.%06d} [uT]\n",
613                   GYRO_ENCODE_FLOAT(debug_data->mag_mean[0], 6),
614                   GYRO_ENCODE_FLOAT(debug_data->mag_mean[1], 6),
615                   GYRO_ENCODE_FLOAT(debug_data->mag_mean[2], 6)
616                   );
617 }
618 
619 // Print Debug data useful for tuning the stillness detectors.
gyroCalTuneDebugPrint(struct gyroCal_t * gyro_cal,uint64_t sample_time)620 void gyroCalTuneDebugPrint(struct gyroCal_t* gyro_cal, uint64_t sample_time) {
621 
622   static uint64_t counter = 0;
623 
624   // Output sensor variance levels to assist with tuning thresholds
625   // every N seconds.
626   if ((sample_time - counter) > 10000000000) { //nsec
627     GYRO_INFO_PRINT("");
628     GYRO_INFO_PRINT(
629         "   Gyro Variance = {%s%d.%08d, %s%d.%08d, %s%d.%08d} [rad/sec]^2\n",
630                     GYRO_ENCODE_FLOAT(
631                         gyro_cal->gyro_stillness_detect.win_var_x, 8),
632                     GYRO_ENCODE_FLOAT(
633                         gyro_cal->gyro_stillness_detect.win_var_y, 8),
634                     GYRO_ENCODE_FLOAT(
635                         gyro_cal->gyro_stillness_detect.win_var_z, 8));
636     GYRO_INFO_PRINT(
637         "   Accel Variance = {%s%d.%08d, %s%d.%08d, %s%d.%08d} [m/sec^2]^2\n",
638                     GYRO_ENCODE_FLOAT(
639                         gyro_cal->accel_stillness_detect.win_var_x, 8),
640                     GYRO_ENCODE_FLOAT(
641                         gyro_cal->accel_stillness_detect.win_var_y, 8),
642                     GYRO_ENCODE_FLOAT(
643                         gyro_cal->accel_stillness_detect.win_var_z, 8));
644     GYRO_INFO_PRINT(
645         "   Mag Variance = {%s%d.%06d, %s%d.%06d, %s%d.%06d} [uT]^2\n",
646                     GYRO_ENCODE_FLOAT(
647                         gyro_cal->mag_stillness_detect.win_var_x, 6),
648                     GYRO_ENCODE_FLOAT(
649                         gyro_cal->mag_stillness_detect.win_var_y, 6),
650                     GYRO_ENCODE_FLOAT(
651                         gyro_cal->mag_stillness_detect.win_var_z, 6));
652     GYRO_INFO_PRINT(
653         "   Stillness = {G%s%d.%06d, A%s%d.%06d, M%s%d.%06d}\n",
654                     GYRO_ENCODE_FLOAT(
655                         gyro_cal->
656                         gyro_stillness_detect.stillness_confidence, 6),
657                     GYRO_ENCODE_FLOAT(
658                         gyro_cal->
659                         accel_stillness_detect.stillness_confidence, 6),
660                     GYRO_ENCODE_FLOAT(
661                         gyro_cal->
662                         mag_stillness_detect.stillness_confidence, 6));
663     GYRO_INFO_PRINT(
664         "   Temperature = %s%d.%06d [C]\n",
665                     GYRO_ENCODE_FLOAT(
666                         gyro_cal->latest_temperature_celcius, 6));
667     GYRO_INFO_PRINT("Total Gyro Calibrations: %lu\n",
668                     gyro_cal->debug_calibration_count);
669     counter = sample_time; //reset
670   }
671 }
672 
673 // Print Debug data report.
gyroCalDebugPrint(struct gyroCal_t * gyro_cal,int * state,uint64_t sample_time)674 void gyroCalDebugPrint(struct gyroCal_t* gyro_cal,
675                        int* state,
676                        uint64_t sample_time) {
677 
678   static int head_index;
679   static int i, j;
680 
681   if (gyro_cal->debug_num_cals == 0) {
682     *state = -1; // idle state.
683   }
684 
685   // State machine to control reporting out debug print data.
686   switch (*state) {
687 
688     case 0:
689       // STATE 0 : Print out header
690       GYRO_INFO_PRINT("");
691       GYRO_INFO_PRINT(
692           "---DEBUG REPORT-------------------------------------\n");
693       GYRO_INFO_PRINT("Gyro Calibrations To Report (newest to oldest): %d\n",
694                       gyro_cal->debug_num_cals);
695       head_index = gyro_cal->debug_head;
696       i = 1; // initialize report count
697       *state = 1; // set next state.
698       break;
699 
700     case 1:
701       // STATE 1: Print out past N recent calibrations.
702       if (i <= gyro_cal->debug_num_cals) {
703 
704         // Print the data.
705         gyroCalDebugPrintData(i, &gyro_cal->debug_cal_data[head_index]);
706 
707         // Move to the previous calibration data set.
708         head_index--;
709         if (head_index < 0) {
710           head_index = DEBUG_GYRO_SHORTTERM_NUM_CAL-1;
711         }
712 
713         // Increment the report count.
714         i++;
715 
716         // Go to wait state.
717         j = 0;
718         *state = 2;
719 
720       } else {
721         // Print out the footer data.
722         *state = 3;
723       }
724       break;
725 
726     case 2:
727       // STATE 2 : Wait state.
728       // Wait for N cycles of gyro samples before printing out more data.
729       // This helps throttle the print statements.
730       if (j <= 50) {
731         j++;
732       } else {
733         *state = 1;
734       }
735       break;
736 
737     case 3:
738       // STATE 3 : Print the end of the debug report.
739       GYRO_INFO_PRINT("Total Gyro Calibrations: %lu\n",
740                       gyro_cal->debug_calibration_count);
741 
742       GYRO_INFO_PRINT("Total Watchdog Timeouts: %lu\n",
743                       gyro_cal->debug_watchdog_count);
744 
745       GYRO_INFO_PRINT(
746           "---END DEBUG REPORT---------------------------------\n");
747       *state = 4;
748       break;
749 
750     case 4:
751       // STATE 4 : Print out header (historic data)
752       GYRO_INFO_PRINT("");
753       GYRO_INFO_PRINT(
754           "---DEBUG REPORT (HISTORY)---------------------------\n");
755       GYRO_INFO_PRINT("Gyro Calibrations To Report (newest to oldest): %d\n",
756                       gyro_cal->debug_num_cals_hist);
757       head_index = gyro_cal->debug_head_hist;
758       i = 1; // initialize report count
759       *state = 5; // set next state.
760       break;
761 
762     case 5:
763       // STATE 5: Print out past N historic calibrations.
764       if (i <= gyro_cal->debug_num_cals_hist) {
765 
766         // Print the data.
767         gyroCalDebugPrintData(i, &gyro_cal->debug_cal_data_hist[head_index]);
768 
769         // Move to the previous calibration data set.
770         head_index--;
771         if (head_index < 0) {
772           head_index = DEBUG_GYRO_LONGTERM_NUM_CAL-1;
773         }
774 
775         // Increment the report count.
776         i++;
777 
778         // Go to wait state.
779         j = 0;
780         *state = 6;
781 
782       } else {
783         // Print out the footer data.
784         *state = 7;
785       }
786       break;
787 
788     case 6:
789       // STATE 6 : Wait state.
790       // Wait for N cycles of gyro samples before printing out more data.
791       // This helps throttle the print statements.
792       if (j <= 50) {
793         j++;
794       } else {
795         *state = 5;
796       }
797       break;
798 
799     case 7:
800       // STATE 3 : Print the end of the debug report.
801       GYRO_INFO_PRINT("Total Gyro Calibrations: %lu\n",
802                       gyro_cal->debug_calibration_count);
803 
804       GYRO_INFO_PRINT("Total Watchdog Timeouts: %lu\n",
805                       gyro_cal->debug_watchdog_count);
806 
807       GYRO_INFO_PRINT(
808           "---END DEBUG REPORT---------------------------------\n");
809       *state = -1;
810       break;
811 
812     default :
813       // Idle state.
814       *state = -1;
815 
816       // Report periodic data useful for tuning the stillness detectors.
817       //gyroCalTuneDebugPrint(gyro_cal, sample_time);
818     }
819 }
820 #endif
821