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  * OTC_STILL_BIAS   - Indicates that a stillness-induced bias update occurred as
52  *                    an input to the over-temperature compensation algorithm
53  *                    NOTE: Stillness bias values (e.g., GyroCal) may be
54  *                    different from the OTC bias. If these bias value are
55  *                    desired, they should be retrieved directly (see related
56  *                    calibration wrappers for access [e.g., GyroOffsetOtcCal]).
57  */
58 enum class CalibrationTypeFlags : uint8_t {
59   NONE = 0x00,
60   BIAS = 0x01,
61   SCALE_FACTOR = 0x02,
62   CROSS_AXIS = 0x04,
63   OVER_TEMP = 0x08,
64   QUALITY_DEGRADED = 0x10,
65   OTC_STILL_BIAS = 0x20,
66   ALL = 0xFF
67 };
68 
69 // Logic operators to assist with common bitmask setting/checking.
70 CalibrationTypeFlags operator|(CalibrationTypeFlags lhs,
71                                CalibrationTypeFlags rhs);
72 
73 bool operator&(CalibrationTypeFlags lhs, CalibrationTypeFlags rhs);
74 
75 CalibrationTypeFlags& operator|=(CalibrationTypeFlags& lhs,
76                                  CalibrationTypeFlags rhs);
77 
78 /*
79  * Defines the calibration data specific to a prototypical three-axis sensing
80  * device (e.g., accelerometer, gyroscope, magnetometer).
81  *
82  * Calibration correction may be applied as:
83  *   corrected_data = scale_skew_matrix * (input_data - offset);
84  *
85  * 'offset' is the sensor bias estimate (with temperature compensation applied
86  * when supported by the underlying calibration algorithm).
87  *
88  * The 'scale_skew_matrix' is assumed to be in lower diagonal form where the
89  * sensor frame reference definition is such that cross-axis sensitivities
90  * cross_axis_xy, cross_axis_xz, and cross_axis_yz are set to zero.
91  *
92  *   scale_skew_matrix = [scale_factor_x    0                 0
93  *                        cross_axis_yx     scale_factor_y    0
94  *                        cross_axis_zx     cross_axis_zy     scale_factor_z]
95  *
96  * NOTE1: If over-temperature compensation is provided, then temperature
97  * compensation is already applied to the 'offset'. Coefficients representative
98  * of the sensor's temperature dependency model are provided, and may be used
99  * for model initialization after a system restart.
100  *
101  *   temp_sensitivity - Modeled temperature sensitivity (i.e., linear slope).
102  *   temp_intercept   - Linear model intercept.
103  *
104  * The model equation for the over-temperature compensated offset:
105  *   compensated_offset = temp_sensitivity * current_temp + temp_intercept
106  *
107  * NOTE2: Unless otherwise stated, 3-dimensional array indices: 0=x, 1=y, 2=z.
108  */
109 struct CalibrationDataThreeAxis {
110   // Timestamp for the most recent calibration update.
111   uint64_t cal_update_time_nanos = 0;
112 
113   // The sensor's offset (i.e., bias) in the x-, y-, z-axes at
114   // 'offset_temp_celsius'.
115   float offset[3];
116 
117   // The temperature associated with the sensor offset.
118   float offset_temp_celsius;
119 
120   // The temperature sensitivity of the offset.
121   float temp_sensitivity[3];  // [sensor_units/Celsius]
122 
123   // The sensor's offset at zero degrees Celsius.
124   float temp_intercept[3];  // [sensor_units]
125 
126   // The sensor's scale factor for each axis.
127   float scale_factor[3];
128 
129   // The cross-axis factors in order: [0=yx, 1=zx, 2=zy].
130   float cross_axis[3];
131 
132   // Metrics used for the reported calibration accuracy. The behavior and
133   // definition depends on the sensor calibration type. See the calibration
134   // algorithm documentation for details.
135   CalibrationQuality calibration_quality;
136 
137   // Indicates the type of sensing device being calibrated.
138   SensorType type = SensorType::kUndefined;
139 
140   // Optional pointer to an array of over-temperature model data (null when not
141   // used).
142   OverTempModelThreeAxis* otc_model_data = nullptr;
143   int16_t num_model_pts = 0;  // Length of otc_model_data array.
144 
145   // Helper function that resets the calibration data to a set of neutral
146   // reference values where no calibration correction would be applied if used.
resetCalibrationDataThreeAxis147   void reset() {
148     otc_model_data = nullptr;
149     calibration_quality.reset();
150     offset_temp_celsius = 0.0f;
151     scale_factor[0] = 1.0f;
152     scale_factor[1] = 1.0f;
153     scale_factor[2] = 1.0f;
154     memset(offset, 0, sizeof(offset));
155     memset(temp_sensitivity, 0, sizeof(temp_sensitivity));
156     memset(temp_intercept, 0, sizeof(temp_intercept));
157     memset(cross_axis, 0, sizeof(cross_axis));
158   }
159 
CalibrationDataThreeAxisCalibrationDataThreeAxis160   CalibrationDataThreeAxis() { reset(); }
161 };
162 
163 /*
164  * Defines the calibration data for single dimensional sensing device (e.g.,
165  * thermometer, barometer).
166  *
167  * Calibration correction may be applied as:
168  *   corrected_data = scale_factor * (input_data - offset);
169  *
170  * 'offset' is the sensor bias estimate (with temperature compensation applied,
171  * if supported by the underlying calibration algorithm).
172  *
173  * NOTE: If over-temperature compensation is provided, then temperature
174  * compensation is already applied to the 'offset'. Coefficients representative
175  * of the sensor's temperature dependency model are provided, and may be used
176  * for model initialization after a system restart.
177  *
178  *   temp_sensitivity - Modeled temperature sensitivity (i.e., linear slope).
179  *   temp_intercept   - Linear model intercept.
180  *
181  * The model equation for the over-temperature compensated offset:
182  *   compensated_offset = temp_sensitivity * current_temp + temp_intercept
183  */
184 struct CalibrationDataSingleAxis {
185   // Timestamp for the most recent calibration update.
186   uint64_t cal_update_time_nanos = 0;
187 
188   // The sensor's offset (i.e., bias) at temperature, 'offset_temp_celsius'.
189   float offset;
190 
191   // The temperature associated with the sensor offset.
192   float offset_temp_celsius;
193 
194   // The temperature sensitivity of the offset.
195   float temp_sensitivity;  // [sensor_units/Celsius]
196 
197   // The sensor's offset at zero degrees Celsius.
198   float temp_intercept;  // [sensor_units]
199 
200   // The sensor's scale factor.
201   float scale_factor;
202 
203   // Metrics used for the reported calibration accuracy. The behavior and
204   // definition depends on the sensor calibration type. See the calibration
205   // algorithm documentation for details.
206   CalibrationQuality calibration_quality;
207 
208   // Indicates the type of sensing device being calibrated.
209   SensorType type = SensorType::kUndefined;
210 
211   // Optional pointer to an array of over-temperature model data (null when not
212   // used).
213   OverTempModelSingleAxis* otc_model_data = nullptr;
214   int16_t num_model_pts = 0;  // Length of otc_model_data array.
215 
216   // Helper function that resets the calibration data to a set of neutral
217   // reference values where no calibration correction would be applied if used.
resetCalibrationDataSingleAxis218   void reset() {
219     otc_model_data = nullptr;
220     calibration_quality.reset();
221     scale_factor = 1.0f;
222     offset_temp_celsius = 0.0f;
223     offset = 0.0f;
224     temp_sensitivity = 0.0f;
225     temp_intercept = 0.0f;
226   }
227 
CalibrationDataSingleAxisCalibrationDataSingleAxis228   CalibrationDataSingleAxis() { reset(); }
229 };
230 
231 }  // namespace online_calibration
232 
233 #endif  // LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_ONLINE_CALIBRATION_COMMON_DATA_CALIBRATION_DATA_H_
234