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 "calibration/gyroscope/gyro_cal.h"
18
19 #include <float.h>
20 #include <inttypes.h>
21 #include <math.h>
22 #include <string.h>
23
24 #ifdef GYRO_CAL_DBG_ENABLED
25 #include "calibration/util/cal_log.h"
26 #endif // GYRO_CAL_DBG_ENABLED
27
28 #include "common/math/macros.h"
29
30 /////// DEFINITIONS AND MACROS ///////////////////////////////////////
31
32 // Maximum gyro bias correction (should be set based on expected max bias
33 // of the given sensor).
34 #define MAX_GYRO_BIAS (0.2f) // [rad/sec]
35
36 // Watchdog timeout value (5 seconds). Monitors dropouts in sensor data and
37 // resets when exceeded.
38 #define GYRO_WATCHDOG_TIMEOUT_NANOS (SEC_TO_NANOS(5))
39
40 #ifdef GYRO_CAL_DBG_ENABLED
41 // The time value used to throttle debug messaging.
42 #define GYROCAL_WAIT_TIME_NANOS (MSEC_TO_NANOS(100))
43
44 // A debug version label to help with tracking results.
45 #define GYROCAL_DEBUG_VERSION_STRING "[July 05, 2017]"
46
47 // Parameters used for sample rate estimation.
48 #define GYROCAL_DEBUG_SAMPLE_RATE_NUM_INTERVALS (100)
49 #define GYROCAL_DEBUG_SAMPLE_RATE_GAP_SEC (1.0f)
50
51 // Debug log tag string used to identify debug report output data.
52 #define GYROCAL_REPORT_TAG "[GYRO_CAL:REPORT]"
53 #endif // GYRO_CAL_DBG_ENABLED
54
55 /////// FORWARD DECLARATIONS /////////////////////////////////////////
56
57 static void deviceStillnessCheck(struct GyroCal* gyro_cal,
58 uint64_t sample_time_nanos);
59
60 static void computeGyroCal(struct GyroCal* gyro_cal,
61 uint64_t calibration_time_nanos);
62
63 static void checkWatchdog(struct GyroCal* gyro_cal, uint64_t sample_time_nanos);
64
65 // Data tracker command enumeration.
66 enum GyroCalTrackerCommand {
67 DO_RESET = 0, // Resets the local data used for data tracking.
68 DO_UPDATE_DATA, // Updates the local tracking data.
69 DO_STORE_DATA, // Stores intermediate results for later recall.
70 DO_EVALUATE // Computes and provides the results of the gate function.
71 };
72
73 /*
74 * Updates the temperature min/max and mean during the stillness period. Returns
75 * 'true' if the min and max temperature values exceed the range set by
76 * 'temperature_delta_limit_celsius'.
77 *
78 * INPUTS:
79 * gyro_cal: Pointer to the GyroCal data structure.
80 * temperature_celsius: New temperature sample to include.
81 * do_this: Command enumerator that controls function behavior:
82 */
83 static bool gyroTemperatureStatsTracker(struct GyroCal* gyro_cal,
84 float temperature_celsius,
85 enum GyroCalTrackerCommand do_this);
86
87 /*
88 * Tracks the minimum and maximum gyroscope stillness window means.
89 * Returns 'true' when the difference between gyroscope min and max window
90 * means are outside the range set by 'stillness_mean_delta_limit'.
91 *
92 * INPUTS:
93 * gyro_cal: Pointer to the GyroCal data structure.
94 * do_this: Command enumerator that controls function behavior.
95 */
96 static bool gyroStillMeanTracker(struct GyroCal* gyro_cal,
97 enum GyroCalTrackerCommand do_this);
98
99 #ifdef GYRO_CAL_DBG_ENABLED
100 // Defines the type of debug data to print.
101 enum DebugPrintData {
102 OFFSET = 0,
103 STILLNESS_DATA,
104 SAMPLE_RATE_AND_TEMPERATURE,
105 GYRO_MINMAX_STILLNESS_MEAN,
106 ACCEL_STATS,
107 GYRO_STATS,
108 MAG_STATS,
109 ACCEL_STATS_TUNING,
110 GYRO_STATS_TUNING,
111 MAG_STATS_TUNING
112 };
113
114 // Updates the information used for debug printouts.
115 static void gyroCalUpdateDebug(struct GyroCal* gyro_cal);
116
117 // Helper function for printing out common debug data.
118 static void gyroCalDebugPrintData(const struct GyroCal* gyro_cal,
119 char* debug_tag,
120 enum DebugPrintData print_data);
121 #endif // GYRO_CAL_DBG_ENABLED
122
123 /////// FUNCTION DEFINITIONS /////////////////////////////////////////
124
125 // Initialize the gyro calibration data structure.
gyroCalInit(struct GyroCal * gyro_cal,const struct GyroCalParameters * parameters)126 void gyroCalInit(struct GyroCal* gyro_cal,
127 const struct GyroCalParameters* parameters) {
128 // Clear gyro_cal structure memory.
129 memset(gyro_cal, 0, sizeof(struct GyroCal));
130
131 // Initialize the stillness detectors.
132 // Gyro parameter input units are [rad/sec].
133 // Accel parameter input units are [m/sec^2].
134 // Magnetometer parameter input units are [uT].
135 gyroStillDetInit(&gyro_cal->gyro_stillness_detect,
136 parameters->gyro_var_threshold,
137 parameters->gyro_confidence_delta);
138 gyroStillDetInit(&gyro_cal->accel_stillness_detect,
139 parameters->accel_var_threshold,
140 parameters->accel_confidence_delta);
141 gyroStillDetInit(&gyro_cal->mag_stillness_detect,
142 parameters->mag_var_threshold,
143 parameters->mag_confidence_delta);
144
145 // Reset stillness flag and start timestamp.
146 gyro_cal->prev_still = false;
147 gyro_cal->start_still_time_nanos = 0;
148
149 // Set the min and max window stillness duration.
150 gyro_cal->min_still_duration_nanos = parameters->min_still_duration_nanos;
151 gyro_cal->max_still_duration_nanos = parameters->max_still_duration_nanos;
152
153 // Sets the duration of the stillness processing windows.
154 gyro_cal->window_time_duration_nanos = parameters->window_time_duration_nanos;
155
156 // Set the watchdog timeout duration.
157 gyro_cal->gyro_watchdog_timeout_duration_nanos = GYRO_WATCHDOG_TIMEOUT_NANOS;
158
159 // Load the last valid cal from system memory.
160 gyro_cal->bias_x = parameters->bias_x; // [rad/sec]
161 gyro_cal->bias_y = parameters->bias_y; // [rad/sec]
162 gyro_cal->bias_z = parameters->bias_z; // [rad/sec]
163 gyro_cal->calibration_time_nanos = parameters->calibration_time_nanos;
164
165 // Set the stillness threshold required for gyro bias calibration.
166 gyro_cal->stillness_threshold = parameters->stillness_threshold;
167
168 // Current window end-time used to assist in keeping sensor data collection in
169 // sync. Setting this to zero signals that sensor data will be dropped until a
170 // valid end-time is set from the first gyro timestamp received.
171 gyro_cal->stillness_win_endtime_nanos = 0;
172
173 // Gyro calibrations will be applied (see, gyroCalRemoveBias()).
174 gyro_cal->gyro_calibration_enable = (parameters->gyro_calibration_enable > 0);
175
176 // Sets the stability limit for the stillness window mean acceptable delta.
177 gyro_cal->stillness_mean_delta_limit = parameters->stillness_mean_delta_limit;
178
179 // Sets the min/max temperature delta limit for the stillness period.
180 gyro_cal->temperature_delta_limit_celsius =
181 parameters->temperature_delta_limit_celsius;
182
183 // Ensures that the data tracking functionality is reset.
184 gyroStillMeanTracker(gyro_cal, DO_RESET);
185 gyroTemperatureStatsTracker(gyro_cal, 0.0f, DO_RESET);
186
187 #ifdef GYRO_CAL_DBG_ENABLED
188 if (gyro_cal->gyro_calibration_enable) {
189 CAL_DEBUG_LOG("[GYRO_CAL:INIT]", "Online gyroscope calibration ENABLED.");
190 } else {
191 CAL_DEBUG_LOG("[GYRO_CAL:INIT]", "Online gyroscope calibration DISABLED.");
192 }
193
194 // Initializes the gyro sampling rate estimator.
195 sampleRateEstimatorInit(&gyro_cal->debug_gyro_cal.sample_rate_estimator,
196 GYROCAL_DEBUG_SAMPLE_RATE_NUM_INTERVALS,
197 GYROCAL_DEBUG_SAMPLE_RATE_GAP_SEC);
198 #endif // GYRO_CAL_DBG_ENABLED
199 }
200
201 // Get the most recent bias calibration value.
gyroCalGetBias(struct GyroCal * gyro_cal,float * bias_x,float * bias_y,float * bias_z,float * temperature_celsius,uint64_t * calibration_time_nanos)202 void gyroCalGetBias(struct GyroCal* gyro_cal, float* bias_x, float* bias_y,
203 float* bias_z, float* temperature_celsius,
204 uint64_t* calibration_time_nanos) {
205 *bias_x = gyro_cal->bias_x;
206 *bias_y = gyro_cal->bias_y;
207 *bias_z = gyro_cal->bias_z;
208 *calibration_time_nanos = gyro_cal->calibration_time_nanos;
209 *temperature_celsius = gyro_cal->bias_temperature_celsius;
210 }
211
212 // Set an initial bias calibration value.
gyroCalSetBias(struct GyroCal * gyro_cal,float bias_x,float bias_y,float bias_z,float temperature_celsius,uint64_t calibration_time_nanos)213 void gyroCalSetBias(struct GyroCal* gyro_cal, float bias_x, float bias_y,
214 float bias_z, float temperature_celsius,
215 uint64_t calibration_time_nanos) {
216 gyro_cal->bias_x = bias_x;
217 gyro_cal->bias_y = bias_y;
218 gyro_cal->bias_z = bias_z;
219 gyro_cal->calibration_time_nanos = calibration_time_nanos;
220 gyro_cal->bias_temperature_celsius = temperature_celsius;
221
222 #ifdef GYRO_CAL_DBG_ENABLED
223 CAL_DEBUG_LOG("[GYRO_CAL:SET BIAS]",
224 "Offset|Temp|Time [mDPS|C|nsec]: " CAL_FORMAT_3DIGITS_TRIPLET
225 ", " CAL_FORMAT_3DIGITS ", %" PRIu64,
226 CAL_ENCODE_FLOAT(bias_x * RAD_TO_MDEG, 3),
227 CAL_ENCODE_FLOAT(bias_y * RAD_TO_MDEG, 3),
228 CAL_ENCODE_FLOAT(bias_z * RAD_TO_MDEG, 3),
229 CAL_ENCODE_FLOAT(temperature_celsius, 3),
230 calibration_time_nanos);
231 #endif // GYRO_CAL_DBG_ENABLED
232 }
233
234 // Remove bias from a gyro measurement [rad/sec].
gyroCalRemoveBias(struct GyroCal * gyro_cal,float xi,float yi,float zi,float * xo,float * yo,float * zo)235 void gyroCalRemoveBias(struct GyroCal* gyro_cal, float xi, float yi, float zi,
236 float* xo, float* yo, float* zo) {
237 if (gyro_cal->gyro_calibration_enable) {
238 *xo = xi - gyro_cal->bias_x;
239 *yo = yi - gyro_cal->bias_y;
240 *zo = zi - gyro_cal->bias_z;
241 }
242 }
243
244 // Returns true when a new gyro calibration is available.
gyroCalNewBiasAvailable(struct GyroCal * gyro_cal)245 bool gyroCalNewBiasAvailable(struct GyroCal* gyro_cal) {
246 bool new_gyro_cal_available =
247 (gyro_cal->gyro_calibration_enable && gyro_cal->new_gyro_cal_available);
248
249 // Clear the flag.
250 gyro_cal->new_gyro_cal_available = false;
251
252 return new_gyro_cal_available;
253 }
254
255 // Update the gyro calibration with gyro data [rad/sec].
gyroCalUpdateGyro(struct GyroCal * gyro_cal,uint64_t sample_time_nanos,float x,float y,float z,float temperature_celsius)256 void gyroCalUpdateGyro(struct GyroCal* gyro_cal, uint64_t sample_time_nanos,
257 float x, float y, float z, float temperature_celsius) {
258 // Make sure that a valid window end-time is set, and start the watchdog
259 // timer.
260 if (gyro_cal->stillness_win_endtime_nanos <= 0) {
261 gyro_cal->stillness_win_endtime_nanos =
262 sample_time_nanos + gyro_cal->window_time_duration_nanos;
263
264 // Start the watchdog timer.
265 gyro_cal->gyro_watchdog_start_nanos = sample_time_nanos;
266 }
267
268 // Update the temperature statistics.
269 gyroTemperatureStatsTracker(gyro_cal, temperature_celsius, DO_UPDATE_DATA);
270
271 #ifdef GYRO_CAL_DBG_ENABLED
272 // Update the gyro sampling rate estimate.
273 sampleRateEstimatorUpdate(&gyro_cal->debug_gyro_cal.sample_rate_estimator,
274 sample_time_nanos);
275 #endif // GYRO_CAL_DBG_ENABLED
276
277 // Pass gyro data to stillness detector
278 gyroStillDetUpdate(&gyro_cal->gyro_stillness_detect,
279 gyro_cal->stillness_win_endtime_nanos, sample_time_nanos,
280 x, y, z);
281
282 // Perform a device stillness check, set next window end-time, and
283 // possibly do a gyro bias calibration and stillness detector reset.
284 deviceStillnessCheck(gyro_cal, sample_time_nanos);
285 }
286
287 // Update the gyro calibration with mag data [micro Tesla].
gyroCalUpdateMag(struct GyroCal * gyro_cal,uint64_t sample_time_nanos,float x,float y,float z)288 void gyroCalUpdateMag(struct GyroCal* gyro_cal, uint64_t sample_time_nanos,
289 float x, float y, float z) {
290 // Pass magnetometer data to stillness detector.
291 gyroStillDetUpdate(&gyro_cal->mag_stillness_detect,
292 gyro_cal->stillness_win_endtime_nanos, sample_time_nanos,
293 x, y, z);
294
295 // Received a magnetometer sample; incorporate it into detection.
296 gyro_cal->using_mag_sensor = true;
297
298 // Perform a device stillness check, set next window end-time, and
299 // possibly do a gyro bias calibration and stillness detector reset.
300 deviceStillnessCheck(gyro_cal, sample_time_nanos);
301 }
302
303 // Update the gyro calibration with accel data [m/sec^2].
gyroCalUpdateAccel(struct GyroCal * gyro_cal,uint64_t sample_time_nanos,float x,float y,float z)304 void gyroCalUpdateAccel(struct GyroCal* gyro_cal, uint64_t sample_time_nanos,
305 float x, float y, float z) {
306 // Pass accelerometer data to stillnesss detector.
307 gyroStillDetUpdate(&gyro_cal->accel_stillness_detect,
308 gyro_cal->stillness_win_endtime_nanos, sample_time_nanos,
309 x, y, z);
310
311 // Perform a device stillness check, set next window end-time, and
312 // possibly do a gyro bias calibration and stillness detector reset.
313 deviceStillnessCheck(gyro_cal, sample_time_nanos);
314 }
315
316 // TODO: Consider breaking this function up to improve readability.
317 // Checks the state of all stillness detectors to determine
318 // whether the device is "still".
deviceStillnessCheck(struct GyroCal * gyro_cal,uint64_t sample_time_nanos)319 void deviceStillnessCheck(struct GyroCal* gyro_cal,
320 uint64_t sample_time_nanos) {
321 bool stillness_duration_exceeded = false;
322 bool stillness_duration_too_short = false;
323 bool min_max_temp_exceeded = false;
324 bool mean_not_stable = false;
325 bool device_is_still = false;
326 float conf_not_rot = 0;
327 float conf_not_accel = 0;
328 float conf_still = 0;
329
330 // Check the watchdog timer.
331 checkWatchdog(gyro_cal, sample_time_nanos);
332
333 // Is there enough data to do a stillness calculation?
334 if ((!gyro_cal->mag_stillness_detect.stillness_window_ready &&
335 gyro_cal->using_mag_sensor) ||
336 !gyro_cal->accel_stillness_detect.stillness_window_ready ||
337 !gyro_cal->gyro_stillness_detect.stillness_window_ready) {
338 return; // Not yet, wait for more data.
339 }
340
341 // Set the next window end-time for the stillness detectors.
342 gyro_cal->stillness_win_endtime_nanos =
343 sample_time_nanos + gyro_cal->window_time_duration_nanos;
344
345 // Update the confidence scores for all sensors.
346 gyroStillDetCompute(&gyro_cal->accel_stillness_detect);
347 gyroStillDetCompute(&gyro_cal->gyro_stillness_detect);
348 if (gyro_cal->using_mag_sensor) {
349 gyroStillDetCompute(&gyro_cal->mag_stillness_detect);
350 } else {
351 // Not using magnetometer, force stillness confidence to 100%.
352 gyro_cal->mag_stillness_detect.stillness_confidence = 1.0f;
353 }
354
355 // Updates the mean tracker data.
356 gyroStillMeanTracker(gyro_cal, DO_UPDATE_DATA);
357
358 // Determine motion confidence scores (rotation, accelerating, and stillness).
359 conf_not_rot = gyro_cal->gyro_stillness_detect.stillness_confidence *
360 gyro_cal->mag_stillness_detect.stillness_confidence;
361 conf_not_accel = gyro_cal->accel_stillness_detect.stillness_confidence;
362 conf_still = conf_not_rot * conf_not_accel;
363
364 // Evaluate the mean and temperature gate functions.
365 mean_not_stable = gyroStillMeanTracker(gyro_cal, DO_EVALUATE);
366 min_max_temp_exceeded =
367 gyroTemperatureStatsTracker(gyro_cal, 0.0f, DO_EVALUATE);
368
369 // Determines if the device is currently still.
370 device_is_still = (conf_still > gyro_cal->stillness_threshold) &&
371 !mean_not_stable && !min_max_temp_exceeded;
372
373 if (device_is_still) {
374 // Device is "still" logic:
375 // If not previously still, then record the start time.
376 // If stillness period is too long, then do a calibration.
377 // Otherwise, continue collecting stillness data.
378
379 // If device was not previously still, set new start timestamp.
380 if (!gyro_cal->prev_still) {
381 // Record the starting timestamp of the current stillness window.
382 // This enables the calculation of total duration of the stillness period.
383 gyro_cal->start_still_time_nanos =
384 gyro_cal->gyro_stillness_detect.window_start_time;
385 }
386
387 // Check to see if current stillness period exceeds the desired limit.
388 stillness_duration_exceeded =
389 (gyro_cal->gyro_stillness_detect.last_sample_time >=
390 gyro_cal->start_still_time_nanos + gyro_cal->max_still_duration_nanos);
391
392 // Track the new stillness mean and temperature data.
393 gyroStillMeanTracker(gyro_cal, DO_STORE_DATA);
394 gyroTemperatureStatsTracker(gyro_cal, 0.0f, DO_STORE_DATA);
395
396 if (stillness_duration_exceeded) {
397 // The current stillness has gone too long. Do a calibration with the
398 // current data and reset.
399
400 // Updates the gyro bias estimate with the current window data and
401 // resets the stats.
402 gyroStillDetReset(&gyro_cal->accel_stillness_detect,
403 /*reset_stats=*/true);
404 gyroStillDetReset(&gyro_cal->gyro_stillness_detect, /*reset_stats=*/true);
405 gyroStillDetReset(&gyro_cal->mag_stillness_detect, /*reset_stats=*/true);
406
407 // Resets the local calculations because the stillness period is over.
408 gyroStillMeanTracker(gyro_cal, DO_RESET);
409 gyroTemperatureStatsTracker(gyro_cal, 0.0f, DO_RESET);
410
411 // Computes a new gyro offset estimate.
412 computeGyroCal(gyro_cal,
413 gyro_cal->gyro_stillness_detect.last_sample_time);
414
415 // Update stillness flag. Force the start of a new stillness period.
416 gyro_cal->prev_still = false;
417 } else {
418 // Continue collecting stillness data.
419
420 // Extend the stillness period.
421 gyroStillDetReset(&gyro_cal->accel_stillness_detect,
422 /*reset_stats=*/false);
423 gyroStillDetReset(&gyro_cal->gyro_stillness_detect,
424 /*reset_stats=*/false);
425 gyroStillDetReset(&gyro_cal->mag_stillness_detect, /*reset_stats=*/false);
426
427 // Update the stillness flag.
428 gyro_cal->prev_still = true;
429 }
430 } else {
431 // Device is NOT still; motion detected.
432
433 // If device was previously still and the total stillness duration is not
434 // "too short", then do a calibration with the data accumulated thus far.
435 stillness_duration_too_short =
436 (gyro_cal->gyro_stillness_detect.window_start_time <
437 gyro_cal->start_still_time_nanos + gyro_cal->min_still_duration_nanos);
438
439 if (gyro_cal->prev_still && !stillness_duration_too_short) {
440 computeGyroCal(gyro_cal,
441 gyro_cal->gyro_stillness_detect.window_start_time);
442 }
443
444 // Reset the stillness detectors and the stats.
445 gyroStillDetReset(&gyro_cal->accel_stillness_detect, /*reset_stats=*/true);
446 gyroStillDetReset(&gyro_cal->gyro_stillness_detect, /*reset_stats=*/true);
447 gyroStillDetReset(&gyro_cal->mag_stillness_detect, /*reset_stats=*/true);
448
449 // Resets the temperature and sensor mean data.
450 gyroTemperatureStatsTracker(gyro_cal, 0.0f, DO_RESET);
451 gyroStillMeanTracker(gyro_cal, DO_RESET);
452
453 // Update stillness flag.
454 gyro_cal->prev_still = false;
455 }
456
457 // Reset the watchdog timer after we have processed data.
458 gyro_cal->gyro_watchdog_start_nanos = sample_time_nanos;
459 }
460
461 // Calculates a new gyro bias offset calibration value.
computeGyroCal(struct GyroCal * gyro_cal,uint64_t calibration_time_nanos)462 void computeGyroCal(struct GyroCal* gyro_cal, uint64_t calibration_time_nanos) {
463 // Check to see if new calibration values is within acceptable range.
464 if (!(gyro_cal->gyro_stillness_detect.prev_mean_x < MAX_GYRO_BIAS &&
465 gyro_cal->gyro_stillness_detect.prev_mean_x > -MAX_GYRO_BIAS &&
466 gyro_cal->gyro_stillness_detect.prev_mean_y < MAX_GYRO_BIAS &&
467 gyro_cal->gyro_stillness_detect.prev_mean_y > -MAX_GYRO_BIAS &&
468 gyro_cal->gyro_stillness_detect.prev_mean_z < MAX_GYRO_BIAS &&
469 gyro_cal->gyro_stillness_detect.prev_mean_z > -MAX_GYRO_BIAS)) {
470 #ifdef GYRO_CAL_DBG_ENABLED
471 CAL_DEBUG_LOG(
472 "[GYRO_CAL:REJECT]",
473 "Offset|Temp|Time [mDPS|C|nsec]: " CAL_FORMAT_3DIGITS_TRIPLET
474 ", " CAL_FORMAT_3DIGITS ", %" PRIu64,
475 CAL_ENCODE_FLOAT(
476 gyro_cal->gyro_stillness_detect.prev_mean_x * RAD_TO_MDEG, 3),
477 CAL_ENCODE_FLOAT(
478 gyro_cal->gyro_stillness_detect.prev_mean_y * RAD_TO_MDEG, 3),
479 CAL_ENCODE_FLOAT(
480 gyro_cal->gyro_stillness_detect.prev_mean_z * RAD_TO_MDEG, 3),
481 CAL_ENCODE_FLOAT(gyro_cal->temperature_mean_celsius, 3),
482 calibration_time_nanos);
483 #endif // GYRO_CAL_DBG_ENABLED
484
485 // Outside of range. Ignore, reset, and continue.
486 return;
487 }
488
489 // Record the new gyro bias offset calibration.
490 gyro_cal->bias_x = gyro_cal->gyro_stillness_detect.prev_mean_x;
491 gyro_cal->bias_y = gyro_cal->gyro_stillness_detect.prev_mean_y;
492 gyro_cal->bias_z = gyro_cal->gyro_stillness_detect.prev_mean_z;
493
494 // Store the calibration temperature (using the mean temperature over the
495 // "stillness" period).
496 gyro_cal->bias_temperature_celsius = gyro_cal->temperature_mean_celsius;
497
498 // Store the calibration time stamp.
499 gyro_cal->calibration_time_nanos = calibration_time_nanos;
500
501 // Record the final stillness confidence.
502 gyro_cal->stillness_confidence =
503 gyro_cal->gyro_stillness_detect.prev_stillness_confidence *
504 gyro_cal->accel_stillness_detect.prev_stillness_confidence *
505 gyro_cal->mag_stillness_detect.prev_stillness_confidence;
506
507 // Set flag to indicate a new gyro calibration value is available.
508 gyro_cal->new_gyro_cal_available = true;
509
510 #ifdef GYRO_CAL_DBG_ENABLED
511 // Increment the total count of calibration updates.
512 gyro_cal->debug_calibration_count++;
513
514 // Update the calibration debug information and trigger a printout.
515 gyroCalUpdateDebug(gyro_cal);
516 #endif
517 }
518
519 // Check for a watchdog timeout condition.
checkWatchdog(struct GyroCal * gyro_cal,uint64_t sample_time_nanos)520 void checkWatchdog(struct GyroCal* gyro_cal, uint64_t sample_time_nanos) {
521 bool watchdog_timeout;
522
523 // Check for initialization of the watchdog time (=0).
524 if (gyro_cal->gyro_watchdog_start_nanos <= 0) {
525 return;
526 }
527
528 // Checks for the following watchdog timeout conditions:
529 // i. The current timestamp has exceeded the allowed watchdog duration.
530 // ii. A timestamp was received that has jumped backwards by more than the
531 // allowed watchdog duration (e.g., timestamp clock roll-over).
532 watchdog_timeout =
533 (sample_time_nanos > gyro_cal->gyro_watchdog_timeout_duration_nanos +
534 gyro_cal->gyro_watchdog_start_nanos) ||
535 (sample_time_nanos + gyro_cal->gyro_watchdog_timeout_duration_nanos <
536 gyro_cal->gyro_watchdog_start_nanos);
537
538 // If a timeout occurred then reset to known good state.
539 if (watchdog_timeout) {
540 #ifdef GYRO_CAL_DBG_ENABLED
541 gyro_cal->debug_watchdog_count++;
542 if (sample_time_nanos < gyro_cal->gyro_watchdog_start_nanos) {
543 CAL_DEBUG_LOG("[GYRO_CAL:WATCHDOG]",
544 "Total#, Timestamp | Delta [nsec]: %zu, %" PRIu64
545 ", -%" PRIu64,
546 gyro_cal->debug_watchdog_count, sample_time_nanos,
547 gyro_cal->gyro_watchdog_start_nanos - sample_time_nanos);
548 } else {
549 CAL_DEBUG_LOG("[GYRO_CAL:WATCHDOG]",
550 "Total#, Timestamp | Delta [nsec]: %zu, %" PRIu64
551 ", %" PRIu64,
552 gyro_cal->debug_watchdog_count, sample_time_nanos,
553 sample_time_nanos - gyro_cal->gyro_watchdog_start_nanos);
554 }
555 #endif // GYRO_CAL_DBG_ENABLED
556
557 // Reset stillness detectors and restart data capture.
558 gyroStillDetReset(&gyro_cal->accel_stillness_detect, /*reset_stats=*/true);
559 gyroStillDetReset(&gyro_cal->gyro_stillness_detect, /*reset_stats=*/true);
560 gyroStillDetReset(&gyro_cal->mag_stillness_detect, /*reset_stats=*/true);
561
562 // Resets the temperature and sensor mean data.
563 gyroTemperatureStatsTracker(gyro_cal, 0.0f, DO_RESET);
564 gyroStillMeanTracker(gyro_cal, DO_RESET);
565
566 // Resets the stillness window end-time.
567 gyro_cal->stillness_win_endtime_nanos = 0;
568
569 // Force stillness confidence to zero.
570 gyro_cal->accel_stillness_detect.prev_stillness_confidence = 0;
571 gyro_cal->gyro_stillness_detect.prev_stillness_confidence = 0;
572 gyro_cal->mag_stillness_detect.prev_stillness_confidence = 0;
573 gyro_cal->stillness_confidence = 0;
574 gyro_cal->prev_still = false;
575
576 // If there are no magnetometer samples being received then
577 // operate the calibration algorithm without this sensor.
578 if (!gyro_cal->mag_stillness_detect.stillness_window_ready &&
579 gyro_cal->using_mag_sensor) {
580 gyro_cal->using_mag_sensor = false;
581 }
582
583 // Assert watchdog timeout flags.
584 gyro_cal->gyro_watchdog_start_nanos = 0;
585 }
586 }
587
588 // TODO -- Combine the following two functions into one or consider
589 // implementing a separate helper module for tracking the temperature and mean
590 // statistics.
gyroTemperatureStatsTracker(struct GyroCal * gyro_cal,float temperature_celsius,enum GyroCalTrackerCommand do_this)591 bool gyroTemperatureStatsTracker(struct GyroCal* gyro_cal,
592 float temperature_celsius,
593 enum GyroCalTrackerCommand do_this) {
594 bool min_max_temp_exceeded = false;
595
596 switch (do_this) {
597 case DO_RESET:
598 // Resets the mean accumulator.
599 gyro_cal->temperature_mean_tracker.num_points = 0;
600 gyro_cal->temperature_mean_tracker.mean_accumulator = 0.0f;
601
602 // Initializes the min/max temperatures values.
603 gyro_cal->temperature_mean_tracker.temperature_min_celsius = FLT_MAX;
604 gyro_cal->temperature_mean_tracker.temperature_max_celsius = -FLT_MAX;
605 break;
606
607 case DO_UPDATE_DATA:
608 // Does the mean accumulation.
609 gyro_cal->temperature_mean_tracker.mean_accumulator +=
610 temperature_celsius;
611 gyro_cal->temperature_mean_tracker.num_points++;
612
613 // Tracks the min, max, and latest temperature values.
614 gyro_cal->temperature_mean_tracker.latest_temperature_celsius =
615 temperature_celsius;
616 if (gyro_cal->temperature_mean_tracker.temperature_min_celsius >
617 temperature_celsius) {
618 gyro_cal->temperature_mean_tracker.temperature_min_celsius =
619 temperature_celsius;
620 }
621 if (gyro_cal->temperature_mean_tracker.temperature_max_celsius <
622 temperature_celsius) {
623 gyro_cal->temperature_mean_tracker.temperature_max_celsius =
624 temperature_celsius;
625 }
626 break;
627
628 case DO_STORE_DATA:
629 // Store the most recent temperature statistics data to the GyroCal data
630 // structure. This functionality allows previous results to be recalled
631 // when the device suddenly becomes "not still".
632 if (gyro_cal->temperature_mean_tracker.num_points > 0) {
633 gyro_cal->temperature_mean_celsius =
634 gyro_cal->temperature_mean_tracker.mean_accumulator /
635 gyro_cal->temperature_mean_tracker.num_points;
636 } else {
637 gyro_cal->temperature_mean_celsius =
638 gyro_cal->temperature_mean_tracker.latest_temperature_celsius;
639 #ifdef GYRO_CAL_DBG_ENABLED
640 CAL_DEBUG_LOG("[GYRO_CAL:TEMP_GATE]",
641 "Insufficient statistics (num_points = 0), using latest "
642 "measured temperature as the mean value.");
643 #endif // GYRO_CAL_DBG_ENABLED
644 }
645 #ifdef GYRO_CAL_DBG_ENABLED
646 // Records the min/max and mean temperature values for debug purposes.
647 gyro_cal->debug_gyro_cal.temperature_mean_celsius =
648 gyro_cal->temperature_mean_celsius;
649 gyro_cal->debug_gyro_cal.temperature_min_celsius =
650 gyro_cal->temperature_mean_tracker.temperature_min_celsius;
651 gyro_cal->debug_gyro_cal.temperature_max_celsius =
652 gyro_cal->temperature_mean_tracker.temperature_max_celsius;
653 #endif
654 break;
655
656 case DO_EVALUATE:
657 // Determines if the min/max delta exceeded the set limit.
658 if (gyro_cal->temperature_mean_tracker.num_points > 0) {
659 min_max_temp_exceeded =
660 (gyro_cal->temperature_mean_tracker.temperature_max_celsius -
661 gyro_cal->temperature_mean_tracker.temperature_min_celsius) >
662 gyro_cal->temperature_delta_limit_celsius;
663
664 #ifdef GYRO_CAL_DBG_ENABLED
665 if (min_max_temp_exceeded) {
666 CAL_DEBUG_LOG(
667 "[GYRO_CAL:TEMP_GATE]",
668 "Exceeded the max temperature variation during stillness.");
669 }
670 #endif // GYRO_CAL_DBG_ENABLED
671 }
672 break;
673
674 default:
675 break;
676 }
677
678 return min_max_temp_exceeded;
679 }
680
gyroStillMeanTracker(struct GyroCal * gyro_cal,enum GyroCalTrackerCommand do_this)681 bool gyroStillMeanTracker(struct GyroCal* gyro_cal,
682 enum GyroCalTrackerCommand do_this) {
683 bool mean_not_stable = false;
684
685 switch (do_this) {
686 case DO_RESET:
687 // Resets the min/max window mean values to a default value.
688 for (size_t i = 0; i < 3; i++) {
689 gyro_cal->window_mean_tracker.gyro_winmean_min[i] = FLT_MAX;
690 gyro_cal->window_mean_tracker.gyro_winmean_max[i] = -FLT_MAX;
691 }
692 break;
693
694 case DO_UPDATE_DATA:
695 // Computes the min/max window mean values.
696 if (gyro_cal->window_mean_tracker.gyro_winmean_min[0] >
697 gyro_cal->gyro_stillness_detect.win_mean_x) {
698 gyro_cal->window_mean_tracker.gyro_winmean_min[0] =
699 gyro_cal->gyro_stillness_detect.win_mean_x;
700 }
701 if (gyro_cal->window_mean_tracker.gyro_winmean_max[0] <
702 gyro_cal->gyro_stillness_detect.win_mean_x) {
703 gyro_cal->window_mean_tracker.gyro_winmean_max[0] =
704 gyro_cal->gyro_stillness_detect.win_mean_x;
705 }
706
707 if (gyro_cal->window_mean_tracker.gyro_winmean_min[1] >
708 gyro_cal->gyro_stillness_detect.win_mean_y) {
709 gyro_cal->window_mean_tracker.gyro_winmean_min[1] =
710 gyro_cal->gyro_stillness_detect.win_mean_y;
711 }
712 if (gyro_cal->window_mean_tracker.gyro_winmean_max[1] <
713 gyro_cal->gyro_stillness_detect.win_mean_y) {
714 gyro_cal->window_mean_tracker.gyro_winmean_max[1] =
715 gyro_cal->gyro_stillness_detect.win_mean_y;
716 }
717
718 if (gyro_cal->window_mean_tracker.gyro_winmean_min[2] >
719 gyro_cal->gyro_stillness_detect.win_mean_z) {
720 gyro_cal->window_mean_tracker.gyro_winmean_min[2] =
721 gyro_cal->gyro_stillness_detect.win_mean_z;
722 }
723 if (gyro_cal->window_mean_tracker.gyro_winmean_max[2] <
724 gyro_cal->gyro_stillness_detect.win_mean_z) {
725 gyro_cal->window_mean_tracker.gyro_winmean_max[2] =
726 gyro_cal->gyro_stillness_detect.win_mean_z;
727 }
728 break;
729
730 case DO_STORE_DATA:
731 // Store the most recent "stillness" mean data to the GyroCal data
732 // structure. This functionality allows previous results to be recalled
733 // when the device suddenly becomes "not still".
734 memcpy(gyro_cal->gyro_winmean_min,
735 gyro_cal->window_mean_tracker.gyro_winmean_min,
736 sizeof(gyro_cal->window_mean_tracker.gyro_winmean_min));
737 memcpy(gyro_cal->gyro_winmean_max,
738 gyro_cal->window_mean_tracker.gyro_winmean_max,
739 sizeof(gyro_cal->window_mean_tracker.gyro_winmean_max));
740 break;
741
742 case DO_EVALUATE:
743 // Performs the stability check and returns the 'true' if the difference
744 // between min/max window mean value is outside the stable range.
745 for (size_t i = 0; i < 3; i++) {
746 mean_not_stable |= (gyro_cal->window_mean_tracker.gyro_winmean_max[i] -
747 gyro_cal->window_mean_tracker.gyro_winmean_min[i]) >
748 gyro_cal->stillness_mean_delta_limit;
749 }
750 #ifdef GYRO_CAL_DBG_ENABLED
751 if (mean_not_stable) {
752 CAL_DEBUG_LOG(
753 "[GYRO_CAL:MEAN_STABILITY_GATE]",
754 "Variation Limit|Delta [mDPS]: " CAL_FORMAT_3DIGITS
755 " | " CAL_FORMAT_3DIGITS_TRIPLET,
756 CAL_ENCODE_FLOAT(gyro_cal->stillness_mean_delta_limit * RAD_TO_MDEG,
757 3),
758 CAL_ENCODE_FLOAT(
759 (gyro_cal->window_mean_tracker.gyro_winmean_max[0] -
760 gyro_cal->window_mean_tracker.gyro_winmean_min[0]) *
761 RAD_TO_MDEG,
762 3),
763 CAL_ENCODE_FLOAT(
764 (gyro_cal->window_mean_tracker.gyro_winmean_max[1] -
765 gyro_cal->window_mean_tracker.gyro_winmean_min[1]) *
766 RAD_TO_MDEG,
767 3),
768 CAL_ENCODE_FLOAT(
769 (gyro_cal->window_mean_tracker.gyro_winmean_max[2] -
770 gyro_cal->window_mean_tracker.gyro_winmean_min[2]) *
771 RAD_TO_MDEG,
772 3));
773 }
774 #endif // GYRO_CAL_DBG_ENABLED
775 break;
776
777 default:
778 break;
779 }
780
781 return mean_not_stable;
782 }
783
784 #ifdef GYRO_CAL_DBG_ENABLED
gyroCalUpdateDebug(struct GyroCal * gyro_cal)785 void gyroCalUpdateDebug(struct GyroCal* gyro_cal) {
786 // Only update this data if debug printing is not currently in progress
787 // (i.e., don't want to risk overwriting debug information that is actively
788 // being reported).
789 if (gyro_cal->debug_state != GYRO_IDLE) {
790 return;
791 }
792
793 // Probability of stillness (acc, rot, still), duration, timestamp.
794 gyro_cal->debug_gyro_cal.accel_stillness_conf =
795 gyro_cal->accel_stillness_detect.prev_stillness_confidence;
796 gyro_cal->debug_gyro_cal.gyro_stillness_conf =
797 gyro_cal->gyro_stillness_detect.prev_stillness_confidence;
798 gyro_cal->debug_gyro_cal.mag_stillness_conf =
799 gyro_cal->mag_stillness_detect.prev_stillness_confidence;
800
801 // Magnetometer usage.
802 gyro_cal->debug_gyro_cal.using_mag_sensor = gyro_cal->using_mag_sensor;
803
804 // Stillness start, stop, and duration times.
805 gyro_cal->debug_gyro_cal.start_still_time_nanos =
806 gyro_cal->start_still_time_nanos;
807 gyro_cal->debug_gyro_cal.end_still_time_nanos =
808 gyro_cal->calibration_time_nanos;
809 gyro_cal->debug_gyro_cal.stillness_duration_nanos =
810 gyro_cal->calibration_time_nanos - gyro_cal->start_still_time_nanos;
811
812 // Records the current calibration values.
813 gyro_cal->debug_gyro_cal.calibration[0] = gyro_cal->bias_x;
814 gyro_cal->debug_gyro_cal.calibration[1] = gyro_cal->bias_y;
815 gyro_cal->debug_gyro_cal.calibration[2] = gyro_cal->bias_z;
816
817 // Records the min/max gyroscope window stillness mean values.
818 memcpy(gyro_cal->debug_gyro_cal.gyro_winmean_min, gyro_cal->gyro_winmean_min,
819 sizeof(gyro_cal->gyro_winmean_min));
820 memcpy(gyro_cal->debug_gyro_cal.gyro_winmean_max, gyro_cal->gyro_winmean_max,
821 sizeof(gyro_cal->gyro_winmean_max));
822
823 // Records the previous stillness window means.
824 gyro_cal->debug_gyro_cal.accel_mean[0] =
825 gyro_cal->accel_stillness_detect.prev_mean_x;
826 gyro_cal->debug_gyro_cal.accel_mean[1] =
827 gyro_cal->accel_stillness_detect.prev_mean_y;
828 gyro_cal->debug_gyro_cal.accel_mean[2] =
829 gyro_cal->accel_stillness_detect.prev_mean_z;
830
831 gyro_cal->debug_gyro_cal.gyro_mean[0] =
832 gyro_cal->gyro_stillness_detect.prev_mean_x;
833 gyro_cal->debug_gyro_cal.gyro_mean[1] =
834 gyro_cal->gyro_stillness_detect.prev_mean_y;
835 gyro_cal->debug_gyro_cal.gyro_mean[2] =
836 gyro_cal->gyro_stillness_detect.prev_mean_z;
837
838 gyro_cal->debug_gyro_cal.mag_mean[0] =
839 gyro_cal->mag_stillness_detect.prev_mean_x;
840 gyro_cal->debug_gyro_cal.mag_mean[1] =
841 gyro_cal->mag_stillness_detect.prev_mean_y;
842 gyro_cal->debug_gyro_cal.mag_mean[2] =
843 gyro_cal->mag_stillness_detect.prev_mean_z;
844
845 // Records the variance data.
846 // NOTE: These statistics include the final captured window, which may be
847 // outside of the "stillness" period. Therefore, these values may exceed the
848 // stillness thresholds.
849 gyro_cal->debug_gyro_cal.accel_var[0] =
850 gyro_cal->accel_stillness_detect.win_var_x;
851 gyro_cal->debug_gyro_cal.accel_var[1] =
852 gyro_cal->accel_stillness_detect.win_var_y;
853 gyro_cal->debug_gyro_cal.accel_var[2] =
854 gyro_cal->accel_stillness_detect.win_var_z;
855
856 gyro_cal->debug_gyro_cal.gyro_var[0] =
857 gyro_cal->gyro_stillness_detect.win_var_x;
858 gyro_cal->debug_gyro_cal.gyro_var[1] =
859 gyro_cal->gyro_stillness_detect.win_var_y;
860 gyro_cal->debug_gyro_cal.gyro_var[2] =
861 gyro_cal->gyro_stillness_detect.win_var_z;
862
863 gyro_cal->debug_gyro_cal.mag_var[0] =
864 gyro_cal->mag_stillness_detect.win_var_x;
865 gyro_cal->debug_gyro_cal.mag_var[1] =
866 gyro_cal->mag_stillness_detect.win_var_y;
867 gyro_cal->debug_gyro_cal.mag_var[2] =
868 gyro_cal->mag_stillness_detect.win_var_z;
869
870 // Trigger a printout of the debug information.
871 gyro_cal->debug_print_trigger = true;
872 }
873
gyroCalDebugPrintData(const struct GyroCal * gyro_cal,char * debug_tag,enum DebugPrintData print_data)874 void gyroCalDebugPrintData(const struct GyroCal* gyro_cal, char* debug_tag,
875 enum DebugPrintData print_data) {
876 // Prints out the desired debug data.
877 float mag_data;
878 switch (print_data) {
879 case OFFSET:
880 CAL_DEBUG_LOG(
881 debug_tag,
882 "Cal#|Offset|Temp|Time [mDPS|C|nsec]: "
883 "%zu, " CAL_FORMAT_3DIGITS_TRIPLET ", " CAL_FORMAT_3DIGITS
884 ", %" PRIu64,
885 gyro_cal->debug_calibration_count,
886 CAL_ENCODE_FLOAT(
887 gyro_cal->debug_gyro_cal.calibration[0] * RAD_TO_MDEG, 3),
888 CAL_ENCODE_FLOAT(
889 gyro_cal->debug_gyro_cal.calibration[1] * RAD_TO_MDEG, 3),
890 CAL_ENCODE_FLOAT(
891 gyro_cal->debug_gyro_cal.calibration[2] * RAD_TO_MDEG, 3),
892 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.temperature_mean_celsius,
893 3),
894 gyro_cal->debug_gyro_cal.end_still_time_nanos);
895 break;
896
897 case STILLNESS_DATA:
898 mag_data = (gyro_cal->debug_gyro_cal.using_mag_sensor)
899 ? gyro_cal->debug_gyro_cal.mag_stillness_conf
900 : -1.0f; // Signals that magnetometer was not used.
901 CAL_DEBUG_LOG(
902 debug_tag,
903 "Cal#|Stillness|Confidence [nsec]: %zu, "
904 "%" PRIu64 ", " CAL_FORMAT_3DIGITS_TRIPLET,
905 gyro_cal->debug_calibration_count,
906 gyro_cal->debug_gyro_cal.end_still_time_nanos -
907 gyro_cal->debug_gyro_cal.start_still_time_nanos,
908 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.gyro_stillness_conf, 3),
909 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.accel_stillness_conf, 3),
910 CAL_ENCODE_FLOAT(mag_data, 3));
911 break;
912
913 case SAMPLE_RATE_AND_TEMPERATURE:
914 CAL_DEBUG_LOG(
915 debug_tag,
916 "Cal#|Mean|Min|Max|Delta|Sample Rate [C|Hz]: "
917 "%zu, " CAL_FORMAT_3DIGITS_TRIPLET ", " CAL_FORMAT_3DIGITS
918 ", " CAL_FORMAT_3DIGITS,
919 gyro_cal->debug_calibration_count,
920 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.temperature_mean_celsius,
921 3),
922 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.temperature_min_celsius, 3),
923 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.temperature_max_celsius, 3),
924 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.temperature_max_celsius -
925 gyro_cal->debug_gyro_cal.temperature_min_celsius,
926 3),
927 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.sample_rate_estimator
928 .mean_sampling_rate_estimate_hz,
929 3));
930 break;
931
932 case GYRO_MINMAX_STILLNESS_MEAN:
933 CAL_DEBUG_LOG(
934 debug_tag,
935 "Cal#|Gyro Peak Stillness Variation [mDPS]: "
936 "%zu, " CAL_FORMAT_3DIGITS_TRIPLET,
937 gyro_cal->debug_calibration_count,
938 CAL_ENCODE_FLOAT((gyro_cal->debug_gyro_cal.gyro_winmean_max[0] -
939 gyro_cal->debug_gyro_cal.gyro_winmean_min[0]) *
940 RAD_TO_MDEG,
941 3),
942 CAL_ENCODE_FLOAT((gyro_cal->debug_gyro_cal.gyro_winmean_max[1] -
943 gyro_cal->debug_gyro_cal.gyro_winmean_min[1]) *
944 RAD_TO_MDEG,
945 3),
946 CAL_ENCODE_FLOAT((gyro_cal->debug_gyro_cal.gyro_winmean_max[2] -
947 gyro_cal->debug_gyro_cal.gyro_winmean_min[2]) *
948 RAD_TO_MDEG,
949 3));
950 break;
951
952 case ACCEL_STATS:
953 CAL_DEBUG_LOG(debug_tag,
954 "Cal#|Accel Mean|Var [m/sec^2|(m/sec^2)^2]: "
955 "%zu, " CAL_FORMAT_3DIGITS_TRIPLET
956 ", " CAL_FORMAT_6DIGITS_TRIPLET,
957 gyro_cal->debug_calibration_count,
958 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.accel_mean[0], 3),
959 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.accel_mean[1], 3),
960 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.accel_mean[2], 3),
961 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.accel_var[0], 6),
962 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.accel_var[1], 6),
963 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.accel_var[2], 6));
964 break;
965
966 case GYRO_STATS:
967 CAL_DEBUG_LOG(
968 debug_tag,
969 "Cal#|Gyro Mean|Var [mDPS|mDPS^2]: %zu, " CAL_FORMAT_3DIGITS_TRIPLET
970 ", " CAL_FORMAT_3DIGITS_TRIPLET,
971 gyro_cal->debug_calibration_count,
972 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.gyro_mean[0] * RAD_TO_MDEG,
973 3),
974 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.gyro_mean[1] * RAD_TO_MDEG,
975 3),
976 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.gyro_mean[2] * RAD_TO_MDEG,
977 3),
978 CAL_ENCODE_FLOAT(
979 gyro_cal->debug_gyro_cal.gyro_var[0] * RAD_TO_MDEG * RAD_TO_MDEG,
980 3),
981 CAL_ENCODE_FLOAT(
982 gyro_cal->debug_gyro_cal.gyro_var[1] * RAD_TO_MDEG * RAD_TO_MDEG,
983 3),
984 CAL_ENCODE_FLOAT(
985 gyro_cal->debug_gyro_cal.gyro_var[2] * RAD_TO_MDEG * RAD_TO_MDEG,
986 3));
987 break;
988
989 case MAG_STATS:
990 if (gyro_cal->debug_gyro_cal.using_mag_sensor) {
991 CAL_DEBUG_LOG(
992 debug_tag,
993 "Cal#|Mag Mean|Var [uT|uT^2]: %zu, " CAL_FORMAT_3DIGITS_TRIPLET
994 ", " CAL_FORMAT_6DIGITS_TRIPLET,
995 gyro_cal->debug_calibration_count,
996 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.mag_mean[0], 3),
997 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.mag_mean[1], 3),
998 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.mag_mean[2], 3),
999 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.mag_var[0], 6),
1000 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.mag_var[1], 6),
1001 CAL_ENCODE_FLOAT(gyro_cal->debug_gyro_cal.mag_var[2], 6));
1002 } else {
1003 CAL_DEBUG_LOG(debug_tag,
1004 "Cal#|Mag Mean|Var [uT|uT^2]: %zu, 0, 0, 0, -1.0, -1.0, "
1005 "-1.0",
1006 gyro_cal->debug_calibration_count);
1007 }
1008 break;
1009
1010 default:
1011 break;
1012 }
1013 }
1014
gyroCalDebugPrint(struct GyroCal * gyro_cal,uint64_t timestamp_nanos)1015 void gyroCalDebugPrint(struct GyroCal* gyro_cal, uint64_t timestamp_nanos) {
1016 // This is a state machine that controls the reporting out of debug data.
1017 switch (gyro_cal->debug_state) {
1018 case GYRO_IDLE:
1019 // Wait for a trigger and start the debug printout sequence.
1020 if (gyro_cal->debug_print_trigger) {
1021 CAL_DEBUG_LOG(GYROCAL_REPORT_TAG, "");
1022 CAL_DEBUG_LOG(GYROCAL_REPORT_TAG, "Debug Version: %s",
1023 GYROCAL_DEBUG_VERSION_STRING);
1024 gyro_cal->debug_print_trigger = false; // Resets trigger.
1025 gyro_cal->debug_state = GYRO_PRINT_OFFSET;
1026 } else {
1027 gyro_cal->debug_state = GYRO_IDLE;
1028 }
1029 break;
1030
1031 case GYRO_WAIT_STATE:
1032 // This helps throttle the print statements.
1033 if (NANO_TIMER_CHECK_T1_GEQUAL_T2_PLUS_DELTA(timestamp_nanos,
1034 gyro_cal->wait_timer_nanos,
1035 GYROCAL_WAIT_TIME_NANOS)) {
1036 gyro_cal->debug_state = gyro_cal->next_state;
1037 }
1038 break;
1039
1040 case GYRO_PRINT_OFFSET:
1041 gyroCalDebugPrintData(gyro_cal, GYROCAL_REPORT_TAG, OFFSET);
1042 gyro_cal->wait_timer_nanos = timestamp_nanos; // Starts the wait timer.
1043 gyro_cal->next_state = GYRO_PRINT_STILLNESS_DATA; // Sets the next state.
1044 gyro_cal->debug_state = GYRO_WAIT_STATE; // First, go to wait state.
1045 break;
1046
1047 case GYRO_PRINT_STILLNESS_DATA:
1048 gyroCalDebugPrintData(gyro_cal, GYROCAL_REPORT_TAG, STILLNESS_DATA);
1049 gyro_cal->wait_timer_nanos = timestamp_nanos; // Starts the wait timer.
1050 gyro_cal->next_state =
1051 GYRO_PRINT_SAMPLE_RATE_AND_TEMPERATURE; // Sets next state.
1052 gyro_cal->debug_state = GYRO_WAIT_STATE; // First, go to wait state.
1053 break;
1054
1055 case GYRO_PRINT_SAMPLE_RATE_AND_TEMPERATURE:
1056 gyroCalDebugPrintData(gyro_cal, GYROCAL_REPORT_TAG,
1057 SAMPLE_RATE_AND_TEMPERATURE);
1058 gyro_cal->wait_timer_nanos = timestamp_nanos; // Starts the wait timer.
1059 gyro_cal->next_state =
1060 GYRO_PRINT_GYRO_MINMAX_STILLNESS_MEAN; // Sets next state.
1061 gyro_cal->debug_state = GYRO_WAIT_STATE; // First, go to wait state.
1062 break;
1063
1064 case GYRO_PRINT_GYRO_MINMAX_STILLNESS_MEAN:
1065 gyroCalDebugPrintData(gyro_cal, GYROCAL_REPORT_TAG,
1066 GYRO_MINMAX_STILLNESS_MEAN);
1067 gyro_cal->wait_timer_nanos = timestamp_nanos; // Starts the wait timer.
1068 gyro_cal->next_state = GYRO_PRINT_ACCEL_STATS; // Sets the next state.
1069 gyro_cal->debug_state = GYRO_WAIT_STATE; // First, go to wait state.
1070 break;
1071
1072 case GYRO_PRINT_ACCEL_STATS:
1073 gyroCalDebugPrintData(gyro_cal, GYROCAL_REPORT_TAG, ACCEL_STATS);
1074 gyro_cal->wait_timer_nanos = timestamp_nanos; // Starts the wait timer.
1075 gyro_cal->next_state = GYRO_PRINT_GYRO_STATS; // Sets the next state.
1076 gyro_cal->debug_state = GYRO_WAIT_STATE; // First, go to wait state.
1077 break;
1078
1079 case GYRO_PRINT_GYRO_STATS:
1080 gyroCalDebugPrintData(gyro_cal, GYROCAL_REPORT_TAG, GYRO_STATS);
1081 gyro_cal->wait_timer_nanos = timestamp_nanos; // Starts the wait timer.
1082 gyro_cal->next_state = GYRO_PRINT_MAG_STATS; // Sets the next state.
1083 gyro_cal->debug_state = GYRO_WAIT_STATE; // First, go to wait state.
1084 break;
1085
1086 case GYRO_PRINT_MAG_STATS:
1087 gyroCalDebugPrintData(gyro_cal, GYROCAL_REPORT_TAG, MAG_STATS);
1088 gyro_cal->wait_timer_nanos = timestamp_nanos; // Starts the wait timer.
1089 gyro_cal->next_state = GYRO_IDLE; // Sets the next state.
1090 gyro_cal->debug_state = GYRO_WAIT_STATE; // First, go to wait state.
1091 break;
1092
1093 default:
1094 // Sends this state machine to its idle state.
1095 gyro_cal->wait_timer_nanos = timestamp_nanos; // Starts the wait timer.
1096 gyro_cal->debug_state = GYRO_IDLE; // Go to idle state.
1097 }
1098 }
1099 #endif // GYRO_CAL_DBG_ENABLED
1100