summaryrefslogtreecommitdiff
path: root/firmware/os/algos/calibration/nano_calibration/nano_calibration.h
blob: 5dad0f68d47f9d8cee1f001617abe8337e57b2bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * This module provides a containing class (NanoSensorCal) for dynamic runtime
 * calibration algorithms that affect the following sensors:
 *       - Accelerometer (offset)
 *       - Gyroscope (offset, with over-temperature compensation)
 *       - Magnetometer (offset)
 *
 * Sensor Units:
 *       - Accelerometer [meters/sec^2]
 *       - Gyroscope     [radian/sec]
 *       - Magnetometer  [micro Tesla, uT]
 *       - Temperature   [Celsius].
 *
 * NOTE1: Define NANO_SENSOR_CAL_DBG_ENABLED to enable debug messaging.
 *
 * NOTE2: This module uses pointers to runtime calibration algorithm objects.
 * These must be constructed and initialized outside of this class. The owner
 * bares the burden of managing the lifetime of these objects with respect to
 * the NanoSensorCal class which depends on these objects and handles their
 * interaction with the Android ASH/CHRE system. This arrangement makes it
 * convenient to modify the specific algorithm implementations (i.e., choice of
 * calibration algorithm, parameter tuning, etc.) at the nanoapp level without
 * the need to specialize the standard functionality implemented here.
 */

#ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_NANO_CALIBRATION_NANO_CALIBRATION_H_
#define LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_NANO_CALIBRATION_NANO_CALIBRATION_H_

#include <stdbool.h>
#include <stdint.h>

#include <ash.h>
#include <chre.h>
#include <cstdint>

#include "calibration/online_calibration/common_data/calibration_callback.h"
#include "calibration/online_calibration/common_data/calibration_data.h"
#include "calibration/online_calibration/common_data/online_calibration.h"
#include "calibration/online_calibration/common_data/sensor_data.h"
#include "common/math/macros.h"

namespace nano_calibration {

/*
 * NanoSensorCal is a container class for dynamic runtime calibration sensor
 * algorithms used by the IMU_Cal CHRE nanoapp. The main purpose of this class
 * is to transfer sensor data to the sensor calibration algorithms and provide
 * calibration updates to CHRE using the ASH API.
 */
class NanoSensorCal {
 public:
  // Alias used to reference the three-axis OnlineCalibration baseclass used by
  // the runtime calibration sensor wrappers. This is for convenience and to
  // help with code readability.
  using OnlineCalibrationThreeAxis = online_calibration::OnlineCalibration<
      online_calibration::CalibrationDataThreeAxis>;

  NanoSensorCal() = default;

  // Sets the sensor calibration object pointers and initializes the algorithms
  // using runtime values recalled using Android Sensor Hub (ASH). A nullptr may
  // be passed in to disable a particular sensor calibration.
  void Initialize(OnlineCalibrationThreeAxis *accel_cal,
                  OnlineCalibrationThreeAxis *gyro_cal,
                  OnlineCalibrationThreeAxis *mag_cal);

  // Sends new sensor samples to the calibration algorithms.
  void HandleSensorSamples(uint16_t event_type,
                           const chreSensorThreeAxisData *event_data);

  // Provides temperature updates to the calibration algorithms.
  void HandleTemperatureSamples(uint16_t event_type,
                                const chreSensorFloatData *event_data);

 private:
  // Passes sensor data to the runtime calibration algorithms.
  void ProcessSample(const online_calibration::SensorData &sample);

  // Loads runtime calibration data using the Android Sensor Hub API. Returns
  // 'true' when runtime calibration values were successfully recalled and used
  // for algorithm initialization. 'sensor_tag' is a string that identifies a
  // sensor-specific identifier for log messages. Updates 'flags' to indicate
  // which runtime calibration parameters were recalled.
  bool LoadAshCalibration(uint8_t chreSensorType,
                          OnlineCalibrationThreeAxis *online_cal,
                          online_calibration::CalibrationTypeFlags* flags,
                          const char *sensor_tag);

  // Provides sensor calibration updates using the ASH API for the specified
  // sensor type. 'cal_data' contains the new calibration data. 'flags' is used
  // to indicate all of the valid calibration values that should be provided
  // with the update. Returns 'true' with a successful ASH update.
  bool NotifyAshCalibration(
      uint8_t chreSensorType,
      const online_calibration::CalibrationDataThreeAxis &cal_data,
      online_calibration::CalibrationTypeFlags flags, const char *sensor_tag);

  // Checks whether 'ash_cal_parameters' is a valid set of runtime calibration
  // data and can be used for algorithm initialization. Updates 'flags' to
  // indicate which runtime calibration parameters were detected.
  bool DetectRuntimeCalibration(uint8_t chreSensorType, const char *sensor_tag,
                                online_calibration::CalibrationTypeFlags *flags,
                                ashCalParams *ash_cal_parameters);

  // Helper functions for logging calibration information.
  void PrintAshCalParams(const ashCalParams &cal_params,
                         const char *sensor_tag);

  void PrintCalibration(
      const online_calibration::CalibrationDataThreeAxis &cal_data,
      online_calibration::CalibrationTypeFlags flags, const char *sensor_tag);

  void HandleGyroLogMessage(uint64_t timestamp_nanos);

  // Pointer to the accelerometer runtime calibration object.
  OnlineCalibrationThreeAxis *accel_cal_ = nullptr;

  // Pointer to the gyroscope runtime calibration object.
  OnlineCalibrationThreeAxis *gyro_cal_ = nullptr;

  // Limits the log messaging update rate for the gyro calibrations since these
  // can occur frequently with rapid temperature changes.
  uint64_t gyro_notification_time_nanos_ = 0;
  uint64_t initialization_start_time_nanos_ = 0;

  // Pointer to the magnetometer runtime calibration object.
  OnlineCalibrationThreeAxis *mag_cal_ = nullptr;

  // Flags that determine which calibration elements are updated with the ASH
  // API. These are reset during initialization, and latched when a particular
  // calibration update is detected upon a valid recall of parameters and/or
  // during runtime. The latching behavior is used to start sending calibration
  // values of a given type (e.g., bias, over-temp model, etc.) once they are
  // detected and thereafter.
  online_calibration::CalibrationTypeFlags accel_cal_update_flags_ =
      online_calibration::CalibrationTypeFlags::NONE;
  online_calibration::CalibrationTypeFlags gyro_cal_update_flags_ =
      online_calibration::CalibrationTypeFlags::NONE;
  online_calibration::CalibrationTypeFlags mag_cal_update_flags_ =
      online_calibration::CalibrationTypeFlags::NONE;
};

}  // namespace nano_calibration

#endif  // LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_NANO_CALIBRATION_NANO_CALIBRATION_H_