1 /*
2  * Copyright (C) 2018 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  * This module provides the component definitions used to represent sensor
19  * calibration data, labeled flags/enumerators, and the callback functionality
20  * employed by the online sensor calibration algorithms.
21  */
22 
23 #ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_ONLINE_CALIBRATION_COMMON_DATA_CALIBRATION_DATA_H_
24 #define LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_ONLINE_CALIBRATION_COMMON_DATA_CALIBRATION_DATA_H_
25 
26 #include <stdint.h>
27 #include <string.h>
28 #include <sys/types.h>
29 
30 #include "calibration/online_calibration/common_data/calibration_quality.h"
31 #include "calibration/online_calibration/common_data/sensor_data.h"
32 #include "calibration/over_temp/over_temp_model.h"
33 
34 namespace online_calibration {
35 
36 /*
37  * Bitmask used to indicate which calibration values have changed for a given
38  * calibration update.
39  *
40  * [Bit Flag]   | [Affected Sensor Calibration Value]
41  * BIAS             - Quasi-static non-zero sensor output (offset), given
42  *                    conditions where the sensor should ideally output zero.
43  *                    Includes corrections for over-temperature compensation.
44  * SCALE_FACTOR     - Sensor axis scaling (ideally unity).
45  * CROSS_AXIS       - Output sensitivity due to variations of perpendicular
46  *                    sensing axes (ideally zero).
47  * OVER_TEMP        - Model parameters that capture variations in sensor
48  *                    behavior with temperature (e.g., linear bias sensitivity
49  *                    model).
50  * QUALITY_DEGRADED - Indicates a degradation in calibration quality.
51  */
52 enum class CalibrationTypeFlags : uint8_t {
53   NONE = 0x00,
54   BIAS = 0x01,
55   SCALE_FACTOR = 0x02,
56   CROSS_AXIS = 0x04,
57   OVER_TEMP = 0x08,
58   QUALITY_DEGRADED = 0x10,
59   ALL = 0xFF
60 };
61 
62 // Logic operators to assist with common bitmask setting/checking.
63 CalibrationTypeFlags operator|(CalibrationTypeFlags lhs,
64                                CalibrationTypeFlags rhs);
65 
66 bool operator&(CalibrationTypeFlags lhs, CalibrationTypeFlags rhs);
67 
68 CalibrationTypeFlags& operator|=(CalibrationTypeFlags& lhs,
69                                  CalibrationTypeFlags rhs);
70 
71 /*
72  * Defines the calibration data specific to a prototypical three-axis sensing
73  * device (e.g., accelerometer, gyroscope, magnetometer).
74  *
75  * Calibration correction may be applied as:
76  *   corrected_data = scale_skew_matrix * (input_data - offset);
77  *
78  * 'offset' is the sensor bias estimate (with temperature compensation applied
79  * when supported by the underlying calibration algorithm).
80  *
81  * The 'scale_skew_matrix' is assumed to be in lower diagonal form where the
82  * sensor frame reference definition is such that cross-axis sensitivities
83  * cross_axis_xy, cross_axis_xz, and cross_axis_yz are set to zero.
84  *
85  *   scale_skew_matrix = [scale_factor_x    0                 0
86  *                        cross_axis_yx     scale_factor_y    0
87  *                        cross_axis_zx     cross_axis_zy     scale_factor_z]
88  *
89  * NOTE1: If over-temperature compensation is provided, then temperature
90  * compensation is already applied to the 'offset'. Coefficients representative
91  * of the sensor's temperature dependency model are provided, and may be used
92  * for model initialization after a system restart.
93  *
94  *   temp_sensitivity - Modeled temperature sensitivity (i.e., linear slope).
95  *   temp_intercept   - Linear model intercept.
96  *
97  * The model equation for the over-temperature compensated offset:
98  *   compensated_offset = temp_sensitivity * current_temp + temp_intercept
99  *
100  * NOTE2: Unless otherwise stated, 3-dimensional array indices: 0=x, 1=y, 2=z.
101  */
102 struct CalibrationDataThreeAxis {
103   // Timestamp for the most recent calibration update.
104   uint64_t cal_update_time_nanos = 0;
105 
106   // The sensor's offset (i.e., bias) in the x-, y-, z-axes at
107   // 'offset_temp_celsius'.
108   float offset[3];
109 
110   // The temperature associated with the sensor offset.
111   float offset_temp_celsius;
112 
113   // The temperature sensitivity of the offset.
114   float temp_sensitivity[3];  // [sensor_units/Celsius]
115 
116   // The sensor's offset at zero degrees Celsius.
117   float temp_intercept[3];  // [sensor_units]
118 
119   // The sensor's scale factor for each axis.
120   float scale_factor[3];
121 
122   // The cross-axis factors in order: [0=yx, 1=zx, 2=zy].
123   float cross_axis[3];
124 
125   // Metrics used for the reported calibration accuracy. The behavior and
126   // definition depends on the sensor calibration type. See the calibration
127   // algorithm documentation for details.
128   CalibrationQuality calibration_quality;
129 
130   // Indicates the type of sensing device being calibrated.
131   SensorType type = SensorType::kUndefined;
132 
133   // Optional pointer to an array of over-temperature model data (null when not
134   // used). For initialization, populating a model dataset will take precedence
135   // over the linear model parameters provided in the calibration data.
136   OverTempModelThreeAxis* otc_model_data = nullptr;
137   int16_t num_model_pts = 0;
138 
139   // Helper function that resets the calibration data to a set of neutral
140   // reference values where no calibration correction would be applied if used.
resetCalibrationDataThreeAxis141   void reset() {
142     otc_model_data = nullptr;
143     calibration_quality.reset();
144     offset_temp_celsius = 0.0f;
145     scale_factor[0] = 1.0f;
146     scale_factor[1] = 1.0f;
147     scale_factor[2] = 1.0f;
148     memset(offset, 0, sizeof(offset));
149     memset(temp_sensitivity, 0, sizeof(temp_sensitivity));
150     memset(temp_intercept, 0, sizeof(temp_intercept));
151     memset(cross_axis, 0, sizeof(cross_axis));
152   }
153 
CalibrationDataThreeAxisCalibrationDataThreeAxis154   CalibrationDataThreeAxis() { reset(); }
155 };
156 
157 /*
158  * Defines the calibration data for single dimensional sensing device (e.g.,
159  * thermometer, barometer).
160  *
161  * Calibration correction may be applied as:
162  *   corrected_data = scale_factor * (input_data - offset);
163  *
164  * 'offset' is the sensor bias estimate (with temperature compensation applied,
165  * if supported by the underlying calibration algorithm).
166  *
167  * NOTE: If over-temperature compensation is provided, then temperature
168  * compensation is already applied to the 'offset'. Coefficients representative
169  * of the sensor's temperature dependency model are provided, and may be used
170  * for model initialization after a system restart.
171  *
172  *   temp_sensitivity - Modeled temperature sensitivity (i.e., linear slope).
173  *   temp_intercept   - Linear model intercept.
174  *
175  * The model equation for the over-temperature compensated offset:
176  *   compensated_offset = temp_sensitivity * current_temp + temp_intercept
177  */
178 struct CalibrationDataSingleAxis {
179   // Timestamp for the most recent calibration update.
180   uint64_t cal_update_time_nanos = 0;
181 
182   // The sensor's offset (i.e., bias) at temperature, 'offset_temp_celsius'.
183   float offset;
184 
185   // The temperature associated with the sensor offset.
186   float offset_temp_celsius;
187 
188   // The temperature sensitivity of the offset.
189   float temp_sensitivity;  // [sensor_units/Celsius]
190 
191   // The sensor's offset at zero degrees Celsius.
192   float temp_intercept;  // [sensor_units]
193 
194   // The sensor's scale factor.
195   float scale_factor;
196 
197   // Metrics used for the reported calibration accuracy. The behavior and
198   // definition depends on the sensor calibration type. See the calibration
199   // algorithm documentation for details.
200   CalibrationQuality calibration_quality;
201 
202   // Indicates the type of sensing device being calibrated.
203   SensorType type = SensorType::kUndefined;
204 
205   // Optional pointer to an array of over-temperature model data (null when not
206   // used). For initialization, populating a model dataset will take precedence
207   // over the linear model parameters provided in the calibration data.
208   OverTempModelSingleAxis* otc_model_data = nullptr;
209   int16_t num_model_pts = 0;
210 
211   // Helper function that resets the calibration data to a set of neutral
212   // reference values where no calibration correction would be applied if used.
resetCalibrationDataSingleAxis213   void reset() {
214     otc_model_data = nullptr;
215     calibration_quality.reset();
216     scale_factor = 1.0f;
217     offset_temp_celsius = 0.0f;
218     offset = 0.0f;
219     temp_sensitivity = 0.0f;
220     temp_intercept = 0.0f;
221   }
222 
CalibrationDataSingleAxisCalibrationDataSingleAxis223   CalibrationDataSingleAxis() { reset(); }
224 };
225 
226 }  // namespace online_calibration
227 
228 #endif  // LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_ONLINE_CALIBRATION_COMMON_DATA_CALIBRATION_DATA_H_
229