1 /* 2 * Copyright (C) 2017 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 /* 18 * [OTC Sensor Offset Calibration] 19 * This module implements a runtime algorithm for provisioning over-temperature 20 * compensated (OTC) estimates of a 3-axis sensor's offset (i.e., bias): 21 * 22 * 1) Estimates of sensor offset with associated temperature are consumed, 23 * {offset, offset_temperature}. 24 * 25 * 2) A linear temperature dependence model is extracted from the collected 26 * set of data pairs. 27 * 28 * 3) The linear model is used for compensation when no other model points 29 * (e.g., nearest-temperature, or the latest received offset estimate) can 30 * be used as a better reference to construct the OTC offset. 31 * 32 * 4) The linear model is used as an extrapolator to provide better 33 * compensated offset estimates with rapid changes in temperature. 34 * 35 * 5) Other key features of this algorithm: 36 * a) Jump Detection - The model may contain old data having a variety of 37 * different thermal histories (hysteresis) which could produce 38 * discontinuities when using nearest-temperature compensation. If a 39 * "jump" is detected in comparison to the linear model (or current 40 * compensation vector, depending on the age of the model), then the 41 * discontinuity may be minimized by selecting the alternative. 42 * 43 * b) Outlier Detection - This checks new offset estimates against the 44 * available linear model. If deviations exceeed a specified limit, 45 * then the estimate is rejected. 46 * 47 * c) Model Data Pruning - Old model data that age beyond a specified 48 * limit is eventually removed from the data set. 49 * 50 * d) Model Parameter Limits - Bounds on the linear model parameters may 51 * be specified to qualify acceptable models. 52 * 53 * e) Offset Update Rate Limits - To minimize computational burden, a 54 * temporal limit is placed on offset updates prompted from an 55 * arbitrarily high temperature sampling rate; and a minimum offset 56 * change is applied to gate small variations in offset during stable 57 * periods. 58 * 59 * f) Model-Weighting Based on Age - The least-squares fit uses a 60 * weighting function based on the age of the model estimate data to 61 * favor recent estimates and emphasize localized OTC model fitting 62 * when new updates arrive. 63 * 64 * General Compensation Model Equation: 65 * sensor_out = sensor_in - compensated_offset 66 * 67 * When the linear model is used, 68 * compensated_offset = (temp_sensitivity * current_temp + sensor_intercept) 69 * 70 * NOTE - 'current_temp' is the current measured temperature. 71 * 'temp_sensitivity' is the modeled temperature sensitivity (i.e., linear 72 * slope). 'sensor_intercept' is linear model intercept. 73 * 74 * When the nearest-temperature or latest-offset is used as a "reference", 75 * delta_temp = current_temp - reference_offset_temperature 76 * extrapolation_term = temp_sensitivity * delta_temp 77 * compensated_offset = reference_offset + extrapolation_term 78 * 79 * Assumptions: 80 * 1) Sensor offset temperature dependence is sufficiently "linear". 81 * 2) Impact of sensor hysteresis is small relative to thermal sensitivity. 82 * 3) The impact of long-term offset drift/aging compared to the magnitude of 83 * deviation resulting from the thermal sensitivity of the offset is 84 * relatively small. 85 * 86 * Sensor Input and Units: 87 * - General 3-axis sensor data. 88 * - Temperature measurements [Celsius]. 89 * 90 * NOTE: Arrays are all 3-dimensional with indices: 0=x, 1=y, 2=z. 91 * 92 * #define OVERTEMPCAL_DBG_ENABLED to enable debug printout statements. 93 * #define OVERTEMPCAL_DBG_LOG_TEMP to periodically printout sensor temperature. 94 */ 95 96 #ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_OVER_TEMP_OVER_TEMP_CAL_H_ 97 #define LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_OVER_TEMP_OVER_TEMP_CAL_H_ 98 99 #include <stdbool.h> 100 #include <stddef.h> 101 #include <stdint.h> 102 103 #include "calibration/over_temp/over_temp_model.h" 104 #include "common/math/macros.h" 105 106 #ifdef __cplusplus 107 extern "C" { 108 #endif 109 110 // A common sensor operating temperature at which to begin the model jump-start 111 // data. 112 #define JUMPSTART_START_TEMP_CELSIUS (30.0f) 113 114 // The maximum number of successive outliers that may be rejected. 115 #define OTC_MAX_OUTLIER_COUNT (3) 116 117 // The 'temp_sensitivity' parameters are set to this value to indicate that the 118 // model is in its initial state. 119 #define OTC_INITIAL_SENSITIVITY (1e6f) 120 121 // Valid sensor temperature operating range. 122 #define OTC_TEMP_MIN_CELSIUS (-40.0f) 123 #define OTC_TEMP_MAX_CELSIUS (85.0f) 124 125 // Number of time-interval levels used to define the least-squares weighting 126 // function. 127 #define OTC_NUM_WEIGHT_LEVELS (2) 128 129 // The time interval used to update the model data age. 130 #define OTC_MODEL_AGE_UPDATE_NANOS (MIN_TO_NANOS(1)) 131 132 // Rate-limits the check of old data to every 2 hours. 133 #define OTC_STALE_CHECK_TIME_NANOS (HRS_TO_NANOS(2)) 134 135 // Time duration in which to enforce using the last offset estimate for 136 // compensation (30 seconds). 137 #define OTC_USE_RECENT_OFFSET_TIME_NANOS (SEC_TO_NANOS(30)) 138 139 // The age at which an offset estimate is considered stale (30 minutes). 140 #define OTC_OFFSET_IS_STALE_NANOS (MIN_TO_NANOS(30)) 141 142 // The refresh interval for the OTC model (30 seconds). 143 #define OTC_REFRESH_MODEL_NANOS (SEC_TO_NANOS(30)) 144 145 // Defines a weighting function value for the linear model fit routine. 146 struct OverTempCalWeight { 147 // The age limit below which an offset will use this weight value. 148 uint64_t offset_age_nanos; 149 150 // The weighting applied (>0). 151 float weight; 152 }; 153 154 #ifdef OVERTEMPCAL_DBG_ENABLED 155 // Debug printout state enumeration. 156 enum OverTempCalDebugState { 157 OTC_IDLE = 0, 158 OTC_WAIT_STATE, 159 OTC_PRINT_OFFSET, 160 OTC_PRINT_MODEL_PARAMETERS, 161 OTC_PRINT_MODEL_ERROR, 162 OTC_PRINT_MODEL_DATA 163 }; 164 165 // OverTempCal debug information/data tracking structure. 166 struct DebugOverTempCal { 167 // The latest received offset estimate data. 168 struct OverTempModelThreeAxis latest_offset; 169 170 // The maximum model error over all model_data points. 171 float max_error[3]; 172 173 float temp_sensitivity[3]; 174 float sensor_intercept[3]; 175 size_t num_model_pts; 176 }; 177 #endif // OVERTEMPCAL_DBG_ENABLED 178 179 // OverTempCal algorithm parameters (see OverTempCal for details). 180 struct OverTempCalParameters { 181 uint64_t min_temp_update_period_nanos; 182 uint64_t age_limit_nanos; 183 float delta_temp_per_bin; // [Celsius/bin] 184 float jump_tolerance; // [sensor units] 185 float outlier_limit; // [sensor units/Celsius] 186 float temp_sensitivity_limit; // [sensor units/Celsius] 187 float sensor_intercept_limit; // [sensor units] 188 float significant_offset_change; // [sensor units] 189 size_t min_num_model_pts; 190 bool over_temp_enable; 191 }; 192 193 // The following data structure contains all of the necessary components for 194 // modeling a sensor's temperature dependency and providing over-temperature 195 // offset corrections. 196 struct OverTempCal { 197 // Storage for over-temperature model data. 198 struct OverTempModelThreeAxis model_data[OTC_MODEL_SIZE]; 199 200 // Implements a weighting function to emphasize fitting a linear model to 201 // younger offset estimates. 202 struct OverTempCalWeight weighting_function[OTC_NUM_WEIGHT_LEVELS]; 203 204 // The active over-temperature compensated offset estimate data. Contains the 205 // current sensor temperature at which offset compensation is performed. 206 struct OverTempModelThreeAxis compensated_offset; 207 208 // Timer used to limit the rate at which old estimates are removed from 209 // the 'model_data' collection. 210 uint64_t stale_data_timer_nanos; 211 212 // Duration beyond which data will be removed to avoid corrupting the model 213 // with drift-compromised data. 214 uint64_t age_limit_nanos; 215 216 // Timestamp of the last OTC offset compensation update. 217 uint64_t last_offset_update_nanos; 218 219 // Timestamp of the last OTC model update. 220 uint64_t last_model_update_nanos; 221 222 // Timestamp of the last OTC model dataset age update. 223 uint64_t last_age_update_nanos; 224 225 // Limit on the minimum interval for offset update calculations resulting from 226 // an arbitrarily high temperature sampling rate. 227 uint64_t min_temp_update_period_nanos; 228 229 ///// Online Model Identification Parameters //////////////////////////////// 230 // 231 // The rules for determining whether a new model fit is computed and the 232 // resulting fit parameters are accepted are: 233 // 1) A minimum number of data points must have been collected: 234 // num_model_pts >= min_num_model_pts 235 // NOTE: Collecting 'num_model_pts' and given that only one point is 236 // kept per temperature bin (spanning a thermal range specified by 237 // 'delta_temp_per_bin'), implies that model data covers at least, 238 // model_temp_span >= 'num_model_pts' * delta_temp_per_bin 239 // 2) A new set of model parameters are accepted if: 240 // i. The model fit parameters must be within certain absolute bounds: 241 // a. |temp_sensitivity| < temp_sensitivity_limit 242 // b. |sensor_intercept| < sensor_intercept_limit 243 float temp_sensitivity_limit; // [sensor units/Celsius] 244 float sensor_intercept_limit; // [sensor units] 245 size_t min_num_model_pts; 246 247 // Pointer to the offset estimate closest to the current sensor temperature. 248 struct OverTempModelThreeAxis *nearest_offset; 249 250 // Pointer to the most recent offset estimate. 251 struct OverTempModelThreeAxis *latest_offset; 252 253 // Modeled temperature sensitivity, dOffset/dTemp [sensor_units/Celsius]. 254 float temp_sensitivity[3]; 255 256 // Sensor model equation intercept [sensor_units]. 257 float sensor_intercept[3]; 258 259 // A limit on the error between nearest-temperature estimate and the model fit 260 // above which the model fit is preferred for providing offset compensation 261 // (also applies to checks between the nearest-temperature and the current 262 // compensated estimate). 263 float jump_tolerance; // [sensor units] 264 265 // A limit used to reject new offset estimates that deviate from the current 266 // model fit. 267 float outlier_limit; // [sensor units] 268 269 // This parameter is used to detect offset changes that require updates to 270 // system calibration and persistent memory storage. 271 float significant_offset_change; // [sensor units] 272 273 // Used to track the previous significant change in temperature. 274 float last_temp_check_celsius; 275 276 // The rules for accepting new offset estimates into the 'model_data' 277 // collection: 278 // 1) The temperature domain is divided into bins each spanning 279 // 'delta_temp_per_bin'. 280 // 2) Find and replace the i'th 'model_data' estimate data if: 281 // Let, bin_num = floor(current_temp / delta_temp_per_bin) 282 // temp_lo_check = bin_num * delta_temp_per_bin 283 // temp_hi_check = (bin_num + 1) * delta_temp_per_bin 284 // Check condition: 285 // temp_lo_check <= model_data[i].offset_temp_celsius < temp_hi_check 286 // 3) If nothing was replaced, and the 'model_data' buffer is not full then 287 // add the sensor offset estimate to the array. 288 // 4) Otherwise (nothing was replaced and buffer is full), replace the 289 // oldest data with the incoming one. 290 // This approach ensures a uniform spread of collected data, keeps the most 291 // recent estimates in cases where they arrive frequently near a given 292 // temperature, and prevents model oversampling (i.e., dominance of estimates 293 // concentrated at a given set of temperatures). 294 float delta_temp_per_bin; // [Celsius/bin] 295 296 // Total number of model data points collected. 297 size_t num_model_pts; 298 299 // The number of successive outliers rejected in a row. This is used to 300 // prevent the possibility of a bad state where an initial poor model fit 301 // causes good data to be continually rejected. 302 size_t num_outliers; 303 304 // Flag set by user to control whether over-temp compensation is used. 305 bool over_temp_enable; 306 307 // True when new compensation model values have been computed; and reset when 308 // overTempCalNewModelUpdateAvailable() is called. This variable indicates 309 // that the following should be stored in persistent system memory: 310 // 1) 'temp_sensitivity' and 'sensor_intercept'. 311 // 2) The 'compensated_offset' offset data. 312 bool new_overtemp_model_available; 313 314 // True when a new offset estimate has been computed and registers as a 315 // significant change (i.e., any of the axis offsets change by more than 316 // 'significant_offset_change'); and reset when 317 // overTempCalNewOffsetAvailable() is called. This variable indicates that new 318 // offset data should be stored in persistent system memory. 319 bool new_overtemp_offset_available; 320 321 #ifdef OVERTEMPCAL_DBG_ENABLED 322 struct DebugOverTempCal debug_overtempcal; // Debug data structure. 323 enum OverTempCalDebugState debug_state; // Debug printout state machine. 324 enum OverTempCalDebugState next_state; // Debug state machine next state. 325 uint64_t wait_timer_nanos; // Debug message throttle timer. 326 327 #ifdef OVERTEMPCAL_DBG_LOG_TEMP 328 uint64_t temperature_print_timer; 329 #endif // OVERTEMPCAL_DBG_LOG_TEMP 330 331 size_t model_counter; // Model output print counter. 332 float otc_unit_conversion; // Unit conversion for debug display. 333 char otc_unit_tag[16]; // Unit descriptor (e.g., "mDPS"). 334 char otc_sensor_tag[16]; // OTC sensor descriptor (e.g., "GYRO"). 335 char otc_debug_tag[32]; // Temporary string descriptor. 336 size_t debug_num_model_updates; // Total number of model updates. 337 size_t debug_num_estimates; // Total number of offset estimates. 338 bool debug_print_trigger; // Flag used to trigger data printout. 339 #endif // OVERTEMPCAL_DBG_ENABLED 340 }; 341 342 /////// FUNCTION PROTOTYPES /////////////////////////////////////////////////// 343 344 /* 345 * Initializes the over-temp calibration model identification parameters. 346 * 347 * INPUTS: 348 * over_temp_cal: Over-temp main data structure. 349 * parameters: An algorithm parameters that contains the 350 * following initialization variables. 351 * [parameters]: 352 * min_num_model_pts: Minimum number of model points per model 353 * calculation update. 354 * min_temp_update_period_nanos: Limits the rate of offset updates due to an 355 * arbitrarily high temperature sampling rate. 356 * delta_temp_per_bin: Temperature span that defines the spacing of 357 * collected model estimates. 358 * jump_tolerance: Tolerance on acceptable jumps in offset updates. 359 * outlier_limit: Outlier offset estimate rejection tolerance. 360 * age_limit_nanos: Sets the age limit beyond which a offset 361 * estimate is removed from 'model_data'. 362 * temp_sensitivity_limit: Values that define the upper limits for the 363 * sensor_intercept_limit: model parameters. The acceptance of new model 364 * parameters must satisfy: 365 * i. |temp_sensitivity| < temp_sensitivity_limit 366 * ii. |sensor_intercept| < sensor_intercept_limit 367 * significant_offset_change Minimum limit that triggers offset updates. 368 * over_temp_enable: Flag that determines whether over-temp sensor 369 * offset compensation is applied. 370 */ 371 void overTempCalInit(struct OverTempCal *over_temp_cal, 372 const struct OverTempCalParameters *parameters); 373 374 /* 375 * Sets the over-temp calibration model parameters. 376 * 377 * INPUTS: 378 * over_temp_cal: Over-temp main data structure. 379 * offset: Update values for the latest offset estimate (array). 380 * offset_temp_celsius: Measured temperature for the offset estimate. 381 * timestamp_nanos: Timestamp for the offset estimate [nanoseconds]. 382 * temp_sensitivity: Modeled temperature sensitivity (array). 383 * sensor_intercept: Linear model intercept for the over-temp model (array). 384 * jump_start_model: When 'true' populates an empty 'model_data' array using 385 * valid input model parameters. 386 * 387 * NOTE: Arrays are all 3-dimensional with indices: 0=x, 1=y, 2=z. 388 */ 389 void overTempCalSetModel(struct OverTempCal *over_temp_cal, const float *offset, 390 float offset_temp_celsius, uint64_t timestamp_nanos, 391 const float *temp_sensitivity, 392 const float *sensor_intercept, bool jump_start_model); 393 394 /* 395 * Gets the over-temp calibration model parameters. 396 * 397 * INPUTS: 398 * over_temp_cal: Over-temp data structure. 399 * OUTPUTS: 400 * offset: Offset values for the latest offset estimate (array). 401 * offset_temp_celsius: Measured temperature for the offset estimate. 402 * timestamp_nanos: Timestamp for the offset estimate [nanoseconds]. 403 * temp_sensitivity: Modeled temperature sensitivity (array). 404 * sensor_intercept: Linear model intercept for the over-temp model (array). 405 * 406 * NOTE: Arrays are all 3-dimensional with indices: 0=x, 1=y, 2=z. 407 */ 408 void overTempCalGetModel(struct OverTempCal *over_temp_cal, float *offset, 409 float *offset_temp_celsius, uint64_t *timestamp_nanos, 410 float *temp_sensitivity, float *sensor_intercept); 411 412 /* 413 * Sets the over-temp compensation model data set, and computes new model 414 * parameters provided that 'min_num_model_pts' is satisfied. 415 * 416 * INPUTS: 417 * over_temp_cal: Over-temp main data structure. 418 * model_data: Array of the new model data set. 419 * data_length: Number of model data entries in 'model_data'. 420 * timestamp_nanos: Timestamp for the model estimates [nanoseconds]. 421 * 422 * NOTE: Max array length for 'model_data' is OTC_MODEL_SIZE. 423 */ 424 void overTempCalSetModelData(struct OverTempCal *over_temp_cal, 425 size_t data_length, uint64_t timestamp_nanos, 426 const struct OverTempModelThreeAxis *model_data); 427 428 /* 429 * Gets the over-temp compensation model data set. 430 * 431 * INPUTS: 432 * over_temp_cal: Over-temp main data structure. 433 * OUTPUTS: 434 * model_data: Array containing the model data set. 435 * data_length: Number of model data entries in 'model_data'. 436 * 437 * NOTE: Max array length for 'model_data' is OTC_MODEL_SIZE. 438 */ 439 void overTempCalGetModelData(struct OverTempCal *over_temp_cal, 440 size_t *data_length, 441 struct OverTempModelThreeAxis *model_data); 442 443 /* 444 * Gets the current over-temp compensated offset estimate data. 445 * 446 * INPUTS: 447 * over_temp_cal: Over-temp data structure. 448 * OUTPUTS: 449 * compensated_offset: Temperature compensated offset estimate array. 450 * compensated_offset_temperature_celsius: Compensated offset temperature. 451 * 452 * NOTE: Arrays are all 3-dimensional with indices: 0=x, 1=y, 2=z. 453 */ 454 void overTempCalGetOffset(struct OverTempCal *over_temp_cal, 455 float *compensated_offset_temperature_celsius, 456 float *compensated_offset); 457 458 /* 459 * Removes the over-temp compensated offset from the input sensor data. 460 * 461 * INPUTS: 462 * over_temp_cal: Over-temp data structure. 463 * timestamp_nanos: Timestamp of the sensor estimate update. 464 * xi, yi, zi: 3-axis sensor data to be compensated. 465 * OUTPUTS: 466 * xo, yo, zo: 3-axis sensor data that has been compensated. 467 */ 468 void overTempCalRemoveOffset(struct OverTempCal *over_temp_cal, 469 uint64_t timestamp_nanos, float xi, float yi, 470 float zi, float *xo, float *yo, float *zo); 471 472 // Returns true when a new over-temp model update is available; and the 473 // 'new_overtemp_model_available' flag is reset. 474 bool overTempCalNewModelUpdateAvailable(struct OverTempCal *over_temp_cal); 475 476 // Returns true when a new over-temp over-temperature offset estimate is 477 // available; and the 'new_overtemp_offset_available' flag is reset. 478 bool overTempCalNewOffsetAvailable(struct OverTempCal *over_temp_cal); 479 480 /* 481 * Updates the sensor's offset estimate and conditionally incorporates it into 482 * the over-temp model data set, 'model_data'. Updates the model dataset age. 483 * 484 * INPUTS: 485 * over_temp_cal: Over-temp data structure. 486 * timestamp_nanos: Timestamp of the sensor estimate update. 487 * offset: 3-axis sensor data to be compensated (array). 488 * temperature_celsius: Measured temperature for the new sensor estimate. 489 * 490 * NOTE: Arrays are all 3-dimensional with indices: 0=x, 1=y, 2=z. 491 */ 492 void overTempCalUpdateSensorEstimate(struct OverTempCal *over_temp_cal, 493 uint64_t timestamp_nanos, 494 const float *offset, 495 float temperature_celsius); 496 497 // Updates the temperature at which the offset compensation is performed (i.e., 498 // the current measured temperature value). This function is provided mainly for 499 // flexibility since temperature updates may come in from a source other than 500 // the sensor itself, and at a different rate. Since this function is 501 // periodically called, it is also used to update the age of the model 502 // estimates. 503 void overTempCalSetTemperature(struct OverTempCal *over_temp_cal, 504 uint64_t timestamp_nanos, 505 float temperature_celsius); 506 507 /* 508 * Computes the maximum absolute error between the 'model_data' estimates and 509 * the estimate determined by the input model parameters. 510 * max_error (over all i) 511 * |model_data[i]->offset_xyz - 512 * getCompensatedOffset(model_data[i]->offset_temp_celsius, 513 * temp_sensitivity, sensor_intercept)| 514 * 515 * INPUTS: 516 * over_temp_cal: Over-temp data structure. 517 * temp_sensitivity: Model temperature sensitivity to test (array). 518 * sensor_intercept: Model intercept to test (array). 519 * OUTPUTS: 520 * max_error: Maximum absolute error for the candidate model (array). 521 * 522 * NOTE 1: Arrays are all 3-dimensional with indices: 0=x, 1=y, 2=z. 523 * NOTE 2: This function is provided for testing purposes. 524 */ 525 void overTempGetModelError(const struct OverTempCal *over_temp_cal, 526 const float *temp_sensitivity, 527 const float *sensor_intercept, float *max_error); 528 529 /* 530 * Defines an element in the weighting function that is used to control the 531 * fitting behavior of the simple linear model regression used in this module. 532 * The total number of weighting levels that define this functionality is set by 533 * 'OTC_NUM_WEIGHT_LEVELS'. The weight values are expected to be greater than 534 * zero. A particular weight is assigned to a given offset estimate when it's 535 * age is less than 'offset_age_nanos'. NOTE: The ordering of the 536 * 'offset_age_nanos' values in the weight function array should be 537 * monotonically increasing from lowest index to highest so that weighting 538 * selection can be conveniently evaluated. A simple compliance check is 539 * applied, and 'true' is returned when the input weight is positive and older 540 * than the 'index-1' weight's age. 541 * 542 * INPUTS: 543 * over_temp_cal: Over-temp data structure. 544 * index: Weighting function index. 545 * new_otc_weight: Pointer to the settings for the new non-zero weighting 546 * value and corresponding age limit below which an offset 547 * will use the weight. 548 */ 549 bool overTempValidateAndSetWeight( 550 struct OverTempCal *over_temp_cal, size_t index, 551 const struct OverTempCalWeight *new_otc_weight); 552 553 #ifdef OVERTEMPCAL_DBG_ENABLED 554 // This debug printout function assumes the input sensor data is a gyroscope 555 // [rad/sec]. 'timestamp_nanos' is the current system time. 556 void overTempCalDebugPrint(struct OverTempCal *over_temp_cal, 557 uint64_t timestamp_nanos); 558 559 /* 560 * Call this after calling 'overTempCalInit' to set the debug sensor descriptor, 561 * displayed units, and the conversion factor from raw sensor units to the 562 * desired display units. Note the maximum string length allocations. 563 * 564 * INPUTS: 565 * over_temp_cal: Over-temp data structure. 566 * otc_sensor_tag: Sensor descriptor prefixes debug output. 567 * otc_unit_tag: Display unit string. 568 * otc_unit_conversion: Display unit conversion factor from raw sensor units. 569 */ 570 void overTempCalDebugDescriptors(struct OverTempCal *over_temp_cal, 571 const char *otc_sensor_tag, 572 const char *otc_unit_tag, 573 float otc_unit_conversion); 574 #endif // OVERTEMPCAL_DBG_ENABLED 575 576 #ifdef __cplusplus 577 } 578 #endif 579 580 #endif // LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_OVER_TEMP_OVER_TEMP_CAL_H_ 581