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