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  * This module provides a containing class (NanoSensorCal) for dynamic runtime
19  * calibration algorithms that affect the following sensors:
20  *       - Accelerometer (offset)
21  *       - Gyroscope (offset, with over-temperature compensation)
22  *       - Magnetometer (offset)
23  *
24  * Sensor Units:
25  *       - Accelerometer [meters/sec^2]
26  *       - Gyroscope     [radian/sec]
27  *       - Magnetometer  [micro Tesla, uT]
28  *       - Temperature   [Celsius].
29  *
30  * NOTE1: Define NANO_SENSOR_CAL_DBG_ENABLED to enable debug messaging.
31  *
32  * NOTE2: This module uses pointers to runtime calibration algorithm objects.
33  * These must be constructed and initialized outside of this class. The owner
34  * bares the burden of managing the lifetime of these objects with respect to
35  * the NanoSensorCal class which depends on these objects and handles their
36  * interaction with the Android ASH/CHRE system. This arrangement makes it
37  * convenient to modify the specific algorithm implementations (i.e., choice of
38  * calibration algorithm, parameter tuning, etc.) at the nanoapp level without
39  * the need to specialize the standard functionality implemented here.
40  */
41 
42 #ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_NANO_CALIBRATION_NANO_CALIBRATION_H_
43 #define LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_NANO_CALIBRATION_NANO_CALIBRATION_H_
44 
45 #include <ash.h>
46 #include <chre.h>
47 #include <stdbool.h>
48 #include <stdint.h>
49 
50 #include <cstdint>
51 
52 #include "calibration/online_calibration/common_data/calibration_callback.h"
53 #include "calibration/online_calibration/common_data/calibration_data.h"
54 #include "calibration/online_calibration/common_data/online_calibration.h"
55 #include "calibration/online_calibration/common_data/result_callback_interface.h"
56 #include "calibration/online_calibration/common_data/sensor_data.h"
57 #include "common/math/macros.h"
58 
59 namespace nano_calibration {
60 
61 /*
62  * NanoSensorCal is a container class for dynamic runtime calibration sensor
63  * algorithms used by the IMU_Cal CHRE nanoapp. The main purpose of this class
64  * is to transfer sensor data to the sensor calibration algorithms and provide
65  * calibration updates to CHRE using the ASH API.
66  */
67 class NanoSensorCal {
68  public:
69   // Alias used to reference the three-axis OnlineCalibration baseclass used by
70   // the runtime calibration sensor wrappers. This is for convenience and to
71   // help with code readability.
72   using OnlineCalibrationThreeAxis = online_calibration::OnlineCalibration<
73       online_calibration::CalibrationDataThreeAxis>;
74 
75   NanoSensorCal() = default;
76 
77   // Sets the sensor calibration object pointers and initializes the algorithms
78   // using runtime values recalled using Android Sensor Hub (ASH). A nullptr may
79   // be passed in to disable a particular sensor calibration.
80   void Initialize(OnlineCalibrationThreeAxis *accel_cal,
81                   OnlineCalibrationThreeAxis *gyro_cal,
82                   OnlineCalibrationThreeAxis *mag_cal);
83 
84   // Sends new sensor samples to the calibration algorithms.
85   void HandleSensorSamples(uint16_t event_type,
86                            const chreSensorThreeAxisData *event_data);
87 
88   // Provides temperature updates to the calibration algorithms.
89   void HandleTemperatureSamples(uint16_t event_type,
90                                 const chreSensorFloatData *event_data);
91 
set_result_callback(online_calibration::ResultCallbackInterface * result_callback)92   void set_result_callback(
93       online_calibration::ResultCallbackInterface *result_callback) {
94     result_callback_ = result_callback;
95   }
96 
97  private:
98   // Passes sensor data to the runtime calibration algorithms.
99   void ProcessSample(const online_calibration::SensorData &sample);
100 
101   // Loads runtime calibration data using the Android Sensor Hub API. Returns
102   // 'true' when runtime calibration values were successfully recalled and used
103   // for algorithm initialization. 'sensor_tag' is a string that identifies a
104   // sensor-specific identifier for log messages. Updates 'flags' to indicate
105   // which runtime calibration parameters were recalled.
106   bool LoadAshCalibration(uint8_t chreSensorType,
107                           OnlineCalibrationThreeAxis *online_cal,
108                           online_calibration::CalibrationTypeFlags *flags,
109                           const char *sensor_tag);
110 
111   // Provides sensor calibration updates using the ASH API for the specified
112   // sensor type. 'cal_data' contains the new calibration data. 'flags' is used
113   // to indicate all of the valid calibration values that should be provided
114   // with the update. Returns 'true' with a successful ASH update.
115   bool NotifyAshCalibration(
116       uint8_t chreSensorType,
117       const online_calibration::CalibrationDataThreeAxis &cal_data,
118       online_calibration::CalibrationTypeFlags flags, const char *sensor_tag);
119 
120   // Checks whether 'ash_cal_parameters' is a valid set of runtime calibration
121   // data and can be used for algorithm initialization. Updates 'flags' to
122   // indicate which runtime calibration parameters were detected.
123   bool DetectRuntimeCalibration(uint8_t chreSensorType, const char *sensor_tag,
124                                 online_calibration::CalibrationTypeFlags *flags,
125                                 ashCalParams *ash_cal_parameters);
126 
127   // Helper functions for logging calibration information.
128   void PrintAshCalParams(const ashCalParams &cal_params,
129                          const char *sensor_tag);
130 
131   void PrintCalibration(
132       const online_calibration::CalibrationDataThreeAxis &cal_data,
133       online_calibration::CalibrationTypeFlags flags, const char *sensor_tag);
134 
135   bool HandleGyroLogMessage(uint64_t timestamp_nanos);
136 
137   // Pointer to the accelerometer runtime calibration object.
138   OnlineCalibrationThreeAxis *accel_cal_ = nullptr;
139 
140   // Pointer to the gyroscope runtime calibration object.
141   OnlineCalibrationThreeAxis *gyro_cal_ = nullptr;
142 
143   // Limits the log messaging update rate for the gyro calibrations since these
144   // can occur frequently with rapid temperature changes.
145   uint64_t gyro_notification_time_nanos_ = 0;
146   uint64_t initialization_start_time_nanos_ = 0;
147 
148   // Pointer to the magnetometer runtime calibration object.
149   OnlineCalibrationThreeAxis *mag_cal_ = nullptr;
150 
151   // Flags that determine which calibration elements are updated with the ASH
152   // API. These are reset during initialization, and latched when a particular
153   // calibration update is detected upon a valid recall of parameters and/or
154   // during runtime. The latching behavior is used to start sending calibration
155   // values of a given type (e.g., bias, over-temp model, etc.) once they are
156   // detected and thereafter.
157   online_calibration::CalibrationTypeFlags accel_cal_update_flags_ =
158       online_calibration::CalibrationTypeFlags::NONE;
159   online_calibration::CalibrationTypeFlags gyro_cal_update_flags_ =
160       online_calibration::CalibrationTypeFlags::NONE;
161   online_calibration::CalibrationTypeFlags mag_cal_update_flags_ =
162       online_calibration::CalibrationTypeFlags::NONE;
163 
164   // Pointer to telemetry logger.
165   online_calibration::ResultCallbackInterface *result_callback_ = nullptr;
166 };
167 
168 }  // namespace nano_calibration
169 
170 #endif  // LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_NANO_CALIBRATION_NANO_CALIBRATION_H_
171