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 runtime
19 * calibration algorithms that affect the following sensors:
20 *       - Accelerometer (offset)
21 *       - Gyroscope (offset, with optional over-temperature compensation)
22 *       - Magnetometer (offset, with optional scale factor and cross-axis)
23 *
24 * Sensor Units:
25 *       - Accelerometer [meters/sec^2]
26 *       - Gyroscope [radian/sec]
27 *       - Magnetometer [micro Tesla, uT]
28 *       - Temperature [Celsius].
29 *
30 * NOTE: Define NANO_SENSOR_CAL_DBG_ENABLED to show debug messages.
31 */
32
33#ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_NANO_CALIBRATION_NANO_CALIBRATION_H_
34#define LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_NANO_CALIBRATION_NANO_CALIBRATION_H_
35
36#include <ash.h>
37
38#ifdef ACCEL_CAL_ENABLED
39#include "calibration/accelerometer/accel_cal.h"
40#endif  // ACCEL_CAL_ENABLED
41
42#ifdef GYRO_CAL_ENABLED
43#include "calibration/gyroscope/gyro_cal.h"
44#ifdef OVERTEMPCAL_GYRO_ENABLED
45#include "calibration/over_temp/over_temp_cal.h"
46#endif  // OVERTEMPCAL_GYRO_ENABLED
47#endif  // GYRO_CAL_ENABLED
48
49#ifdef MAG_CAL_ENABLED
50#include "calibration/magnetometer/mag_cal.h"
51#ifdef SPHERE_FIT_ENABLED
52#include "calibration/magnetometer/mag_sphere_fit.h"
53#endif  // SPHERE_FIT_ENABLED
54#endif  // MAG_CAL_ENABLED
55
56#include <chre.h>
57
58namespace nano_calibration {
59
60// Data struct for sample rate estimate fuction. Visible for the class in order
61// to allow usage in all algorithms.
62struct SampleRateData {
63  uint64_t last_timestamp_nanos;
64  uint64_t time_delta_accumulator;
65  size_t num_samples;
66};
67
68// TODO: move typedef to mag_cal.h.
69typedef uint32_t MagUpdateFlags;
70
71/*
72 * Class Definition:  NanoSensorCal.
73 */
74class NanoSensorCal {
75 public:
76  // Default constructor.
77  NanoSensorCal();
78
79  // Virtual destructor.
80  virtual ~NanoSensorCal() {}
81
82  // Initializes the sensor calibration algorithms.
83  void Initialize();
84
85  // Sends new sensor samples to the calibration algorithms.
86  void HandleSensorSamples(uint16_t event_type,
87                           const chreSensorThreeAxisData *event_data);
88
89  // Provides temperature updates to the calibration algorithms.
90  void HandleTemperatureSamples(uint16_t event_type,
91                                const chreSensorFloatData *event_data);
92
93  // Returns the availability of new calibration data (useful for polling).
94  bool is_accel_calibration_ready() { return accel_calibration_ready_; }
95  bool is_gyro_calibration_ready()  { return gyro_calibration_ready_; }
96  bool is_mag_calibration_ready()   { return mag_calibration_ready_; }
97
98  // Returns true if the NanoSensorCal object has been initialized.
99  bool is_initialized() { return nanosensorcal_initialized_; }
100
101  // Calibration data accessor functions useful, in conjunction with the
102  // 'is_calibration_ready' functions, to poll for changes in calibration
103  // parameters. Calling these functions returns the calibration parameters and
104  // resets the calibration ready flags.
105  void GetAccelerometerCalibration(struct ashCalParams *accel_cal_params) const;
106  void GetGyroscopeCalibration(struct ashCalParams *gyro_cal_params) const;
107  void GetMagnetometerCalibration(struct ashCalParams *mag_cal_params) const ;
108
109 private:
110  // Sends new sensor samples to the AccelCal.
111  void HandleSensorSamplesAccelCal(uint16_t event_type,
112                                   const chreSensorThreeAxisData *event_data);
113
114  // Sends new sensor samples to the GyroCal/OTC. GyroCal utilizes multiple
115  // sensor types (i.e., accel/gyro/mag).
116  void HandleSensorSamplesGyroCal(uint16_t event_type,
117                                  const chreSensorThreeAxisData *event_data);
118
119  // Sends new sensor samples to the MagCal.
120  void HandleSensorSamplesMagCal(uint16_t event_type,
121                                 const chreSensorThreeAxisData *event_data);
122
123  // Updates the local calibration parameters containers.
124  void UpdateAccelCalParams();
125  void UpdateGyroCalParams();
126  void UpdateMagCalParams(MagUpdateFlags new_update);
127
128  // Loads persistent calibration data using the ASH API.
129  void LoadAshAccelCal();
130  void LoadAshGyroCal();
131  void LoadAshOtcGyroCal();
132  void LoadAshMagCal();
133
134  // Stores persistent calibration data parameters and updates calibration
135  // information using the ASH API.
136  void NotifyAshAccelCal();
137  void NotifyAshGyroCal();
138  void NotifyAshMagCal(MagUpdateFlags new_update);
139
140#ifdef ACCEL_CAL_ENABLED
141  // Accelerometer runtime calibration.
142  struct AccelCal accel_cal_;
143#endif  // ACCEL_CAL_ENABLED
144
145#ifdef GYRO_CAL_ENABLED
146  // Gyroscope runtime calibration.
147  struct GyroCal gyro_cal_;
148
149  // Used to limit the rate of gyro debug notification messages.
150  uint64_t gyro_notification_time_check_ = 0;
151#ifdef OVERTEMPCAL_GYRO_ENABLED
152  // Gyroscope over-temperature runtime calibration.
153  struct OverTempCal over_temp_gyro_cal_;
154#endif  // OVERTEMPCAL_GYRO_ENABLED
155#endif  // GYRO_CAL_ENABLED
156
157#ifdef MAG_CAL_ENABLED
158  // Magnetometer runtime calibration.
159  struct MagCal mag_cal_;
160#ifdef SPHERE_FIT_ENABLED
161  struct SampleRateData mag_sample_rate_data_;
162  struct MagCalSphere mag_cal_sphere_;
163  float mag_odr_estimate_hz_ = 0;
164#endif  // SPHERE_FIT_ENABLED
165#endif  // MAG_CAL_ENABLED
166
167  // Flag to indicate whether the NanoSensorCal object has been initialized.
168  bool nanosensorcal_initialized_ = false;
169
170  // Flags to indicate availability of new calibration data (polling).
171  mutable bool accel_calibration_ready_ = false;
172  mutable bool gyro_calibration_ready_ = false;
173  mutable bool mag_calibration_ready_ = false;
174
175  // Sensor temperature.
176  float temperature_celsius_;
177
178  // Sensor calibration parameter containers.
179  struct ashCalParams accel_cal_params_;
180  struct ashCalParams gyro_cal_params_;
181  struct ashCalParams mag_cal_params_;
182};
183
184}  // namespace nano_calibration
185
186#endif  // LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_NANO_CALIBRATION_NANO_CALIBRATION_H_
187