Home | History | Annotate | Download | only in over_temp
      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