• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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