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