2 * Copyright (C) 2011 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "SensorDevice.h"
18 #include "SensorFusion.h"
19 #include "SensorService.h"
22 // ---------------------------------------------------------------------------
24 ANDROID_SINGLETON_STATIC_INSTANCE(SensorFusion)
26 SensorFusion::SensorFusion()
27 : mSensorDevice(SensorDevice::getInstance()),
28 mEnabled(false), mGyroTime(0)
31 Sensor uncalibratedGyro;
32 ssize_t count = mSensorDevice.getSensorList(&list);
34 for (size_t i=0 ; i<size_t(count) ; i++) {
35 if (list[i].type == SENSOR_TYPE_ACCELEROMETER) {
36 mAcc = Sensor(list + i);
38 if (list[i].type == SENSOR_TYPE_MAGNETIC_FIELD) {
39 mMag = Sensor(list + i);
41 if (list[i].type == SENSOR_TYPE_GYROSCOPE) {
42 mGyro = Sensor(list + i);
44 if (list[i].type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED) {
45 uncalibratedGyro = Sensor(list + i);
49 // Use the uncalibrated gyroscope for sensor fusion when available
50 if (uncalibratedGyro.getType() == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED) {
51 mGyro = uncalibratedGyro;
54 // 200 Hz for gyro events is a good compromise between precision
55 // and power/cpu usage.
56 mEstimatedGyroRate = 200;
57 mTargetDelayNs = 1000000000LL/mEstimatedGyroRate;
62 void SensorFusion::process(const sensors_event_t& event) {
63 if (event.type == mGyro.getType()) {
65 const float dT = (event.timestamp - mGyroTime) / 1000000000.0f;
66 mFusion.handleGyro(vec3_t(event.data), dT);
67 // here we estimate the gyro rate (useful for debugging)
68 const float freq = 1 / dT;
69 if (freq >= 100 && freq<1000) { // filter values obviously wrong
70 const float alpha = 1 / (1 + dT); // 1s time-constant
71 mEstimatedGyroRate = freq + (mEstimatedGyroRate - freq)*alpha;
74 mGyroTime = event.timestamp;
75 } else if (event.type == SENSOR_TYPE_MAGNETIC_FIELD) {
76 const vec3_t mag(event.data);
77 mFusion.handleMag(mag);
78 } else if (event.type == SENSOR_TYPE_ACCELEROMETER) {
79 const vec3_t acc(event.data);
80 mFusion.handleAcc(acc);
81 mAttitude = mFusion.getAttitude();
85 template <typename T> inline T min(T a, T b) { return a<b ? a : b; }
86 template <typename T> inline T max(T a, T b) { return a>b ? a : b; }
88 status_t SensorFusion::activate(void* ident, bool enabled) {
90 ALOGD_IF(DEBUG_CONNECTIONS,
91 "SensorFusion::activate(ident=%p, enabled=%d)",
94 const ssize_t idx = mClients.indexOf(ident);
101 mClients.removeItemsAt(idx);
105 mSensorDevice.activate(ident, mAcc.getHandle(), enabled);
106 mSensorDevice.activate(ident, mMag.getHandle(), enabled);
107 mSensorDevice.activate(ident, mGyro.getHandle(), enabled);
109 const bool newState = mClients.size() != 0;
110 if (newState != mEnabled) {
120 status_t SensorFusion::setDelay(void* ident, int64_t ns) {
121 mSensorDevice.setDelay(ident, mAcc.getHandle(), ns);
122 mSensorDevice.setDelay(ident, mMag.getHandle(), ms2ns(20));
123 mSensorDevice.setDelay(ident, mGyro.getHandle(), mTargetDelayNs);
128 float SensorFusion::getPowerUsage() const {
129 float power = mAcc.getPowerUsage() +
130 mMag.getPowerUsage() +
131 mGyro.getPowerUsage();
135 int32_t SensorFusion::getMinDelay() const {
136 return mAcc.getMinDelay();
139 void SensorFusion::dump(String8& result) {
140 const Fusion& fusion(mFusion);
141 result.appendFormat("9-axis fusion %s (%d clients), gyro-rate=%7.2fHz, "
142 "q=< %g, %g, %g, %g > (%g), "
143 "b=< %g, %g, %g >\n",
144 mEnabled ? "enabled" : "disabled",
147 fusion.getAttitude().x,
148 fusion.getAttitude().y,
149 fusion.getAttitude().z,
150 fusion.getAttitude().w,
151 length(fusion.getAttitude()),
157 // ---------------------------------------------------------------------------
158 }; // namespace android