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 #include "chre/platform/slpi/see/see_cal_helper.h"
18
19 #include "chre/platform/assert.h"
20 #include "chre/platform/log.h"
21 #include "chre/platform/slpi/see/see_helper.h"
22 #include "chre/util/lock_guard.h"
23 #include "chre/util/macros.h"
24
25 namespace chre {
26
applyCalibration(SensorType sensorType,const float input[3],float output[3]) const27 void SeeCalHelper::applyCalibration(SensorType sensorType, const float input[3],
28 float output[3]) const {
29 bool applied = false;
30 size_t index = getCalIndexFromSensorType(sensorType);
31 if (index < ARRAY_SIZE(mCalInfo)) {
32 LockGuard<Mutex> lock(mMutex);
33
34 // TODO: Support compensation matrix and scaling factor calibration
35 if (mCalInfo[index].cal.hasBias) {
36 for (size_t i = 0; i < 3; i++) {
37 output[i] = input[i] - mCalInfo[index].cal.bias[i];
38 }
39 applied = true;
40 }
41 }
42
43 if (!applied) {
44 for (size_t i = 0; i < 3; i++) {
45 output[i] = input[i];
46 }
47 }
48 }
49
getBias(SensorType sensorType,struct chreSensorThreeAxisData * biasData) const50 bool SeeCalHelper::getBias(
51 SensorType sensorType, struct chreSensorThreeAxisData *biasData) const {
52 CHRE_ASSERT(biasData != nullptr);
53
54 bool success = false;
55 if (biasData != nullptr) {
56 size_t index = getCalIndexFromSensorType(sensorType);
57 if (index < ARRAY_SIZE(mCalInfo)) {
58 LockGuard<Mutex> lock(mMutex);
59
60 if (mCalInfo[index].cal.hasBias) {
61 biasData->header.baseTimestamp = mCalInfo[index].cal.timestamp;
62 biasData->header.sensorHandle =
63 getSensorHandleFromSensorType(sensorType);
64 biasData->header.readingCount = 1;
65 biasData->header.accuracy = mCalInfo[index].cal.accuracy;
66 biasData->header.reserved = 0;
67
68 for (size_t i = 0; i < 3; i++) {
69 biasData->readings[0].bias[i] = mCalInfo[index].cal.bias[i];
70 }
71 biasData->readings[0].timestampDelta = 0;
72 success = true;
73 }
74 }
75 }
76
77 return success;
78 }
79
getCalSuidFromSensorType(SensorType sensorType) const80 const sns_std_suid& SeeCalHelper::getCalSuidFromSensorType(
81 SensorType sensorType) const {
82 static sns_std_suid suid = sns_suid_sensor_init_zero;
83
84 // Mutex not needed, SUID is not modified after init
85 size_t calIndex = getCalIndexFromSensorType(sensorType);
86 if (calIndex < ARRAY_SIZE(mCalInfo) && mCalInfo[calIndex].suid.has_value()) {
87 suid = mCalInfo[calIndex].suid.value();
88 }
89 return suid;
90 }
91
registerForCalibrationUpdates(SeeHelper & seeHelper)92 bool SeeCalHelper::registerForCalibrationUpdates(SeeHelper& seeHelper) {
93 bool success = true;
94
95 // Find the cal sensor's SUID, assign it to mCalInfo, and make cal sensor data
96 // request.
97 DynamicVector<sns_std_suid> suids;
98 for (size_t i = 0; i < ARRAY_SIZE(mCalInfo); i++) {
99 const char *calType = getDataTypeForCalSensorIndex(i);
100 if (!seeHelper.findSuidSync(calType, &suids)) {
101 success = false;
102 LOGE("Failed to find sensor '%s'", calType);
103 } else {
104 mCalInfo[i].suid = suids[0];
105 if (!seeHelper.configureOnChangeSensor(suids[0], true /* enable */)) {
106 success = false;
107 LOGE("Failed to request '%s' data", calType);
108 }
109 }
110 }
111
112 return success;
113 }
114
updateCalibration(const sns_std_suid & suid,bool hasBias,float bias[3],bool hasScale,float scale[3],bool hasMatrix,float matrix[9],uint8_t accuracy,uint64_t timestamp)115 void SeeCalHelper::updateCalibration(
116 const sns_std_suid& suid, bool hasBias, float bias[3], bool hasScale,
117 float scale[3], bool hasMatrix, float matrix[9], uint8_t accuracy,
118 uint64_t timestamp) {
119 size_t index = getCalIndexFromSuid(suid);
120 if (index < ARRAY_SIZE(mCalInfo)) {
121 LockGuard<Mutex> lock(mMutex);
122 SeeCalData& calData = mCalInfo[index].cal;
123
124 calData.hasBias = hasBias;
125 if (hasBias) {
126 memcpy(calData.bias, bias, sizeof(calData.bias));
127 }
128
129 calData.hasScale = hasScale;
130 if (hasScale) {
131 memcpy(calData.scale, scale, sizeof(calData.scale));
132 }
133
134 calData.hasMatrix = hasMatrix;
135 if (hasMatrix) {
136 memcpy(calData.matrix, matrix, sizeof(calData.matrix));
137 }
138
139 calData.accuracy = accuracy;
140 calData.timestamp = timestamp;
141 }
142 }
143
getSensorTypeFromSuid(const sns_std_suid & suid) const144 SensorType SeeCalHelper::getSensorTypeFromSuid(const sns_std_suid& suid) const {
145 size_t calSensorIndex = getCalIndexFromSuid(suid);
146 switch (static_cast<SeeCalSensor>(calSensorIndex)) {
147 case SeeCalSensor::AccelCal:
148 return SensorType::Accelerometer;
149 case SeeCalSensor::GyroCal:
150 return SensorType::Gyroscope;
151 case SeeCalSensor::MagCal:
152 return SensorType::GeomagneticField;
153 default:
154 CHRE_ASSERT(false);
155 }
156 return SensorType::Unknown;
157 }
158
getCalIndexFromSensorType(SensorType sensorType)159 size_t SeeCalHelper::getCalIndexFromSensorType(SensorType sensorType) {
160 SeeCalSensor index;
161 switch (sensorType) {
162 case SensorType::Accelerometer:
163 index = SeeCalSensor::AccelCal;
164 break;
165 case SensorType::Gyroscope:
166 index = SeeCalSensor::GyroCal;
167 break;
168 case SensorType::GeomagneticField:
169 index = SeeCalSensor::MagCal;
170 break;
171 default:
172 index = SeeCalSensor::NumCalSensors;
173 }
174 return static_cast<size_t>(index);
175 }
176
getDataTypeForCalSensorIndex(size_t calSensorIndex)177 const char *SeeCalHelper::getDataTypeForCalSensorIndex(size_t calSensorIndex) {
178 switch (static_cast<SeeCalSensor>(calSensorIndex)) {
179 case SeeCalSensor::AccelCal:
180 return "accel_cal";
181 case SeeCalSensor::GyroCal:
182 return "gyro_cal";
183 case SeeCalSensor::MagCal:
184 return "mag_cal";
185 default:
186 CHRE_ASSERT(false);
187 }
188 return nullptr;
189 }
190
getCalIndexFromSuid(const sns_std_suid & suid) const191 size_t SeeCalHelper::getCalIndexFromSuid(const sns_std_suid& suid) const {
192 size_t i = 0;
193 for (; i < ARRAY_SIZE(mCalInfo); i++) {
194 if (mCalInfo[i].suid.has_value()
195 && suidsMatch(suid, mCalInfo[i].suid.value())) {
196 break;
197 }
198 }
199 return i;
200 }
201
202 } // namespace chre
203