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