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