1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker #ifndef ANDROID_FUSION_H 18*38e8c45fSAndroid Build Coastguard Worker #define ANDROID_FUSION_H 19*38e8c45fSAndroid Build Coastguard Worker 20*38e8c45fSAndroid Build Coastguard Worker #include <utils/Errors.h> 21*38e8c45fSAndroid Build Coastguard Worker 22*38e8c45fSAndroid Build Coastguard Worker #include "quat.h" 23*38e8c45fSAndroid Build Coastguard Worker #include "mat.h" 24*38e8c45fSAndroid Build Coastguard Worker #include "vec.h" 25*38e8c45fSAndroid Build Coastguard Worker 26*38e8c45fSAndroid Build Coastguard Worker namespace android { 27*38e8c45fSAndroid Build Coastguard Worker 28*38e8c45fSAndroid Build Coastguard Worker typedef mat<float, 3, 4> mat34_t; 29*38e8c45fSAndroid Build Coastguard Worker 30*38e8c45fSAndroid Build Coastguard Worker enum FUSION_MODE{ 31*38e8c45fSAndroid Build Coastguard Worker FUSION_9AXIS, // use accel gyro mag 32*38e8c45fSAndroid Build Coastguard Worker FUSION_NOMAG, // use accel gyro (game rotation, gravity) 33*38e8c45fSAndroid Build Coastguard Worker FUSION_NOGYRO, // use accel mag (geomag rotation) 34*38e8c45fSAndroid Build Coastguard Worker NUM_FUSION_MODE 35*38e8c45fSAndroid Build Coastguard Worker }; 36*38e8c45fSAndroid Build Coastguard Worker 37*38e8c45fSAndroid Build Coastguard Worker class Fusion { 38*38e8c45fSAndroid Build Coastguard Worker /* 39*38e8c45fSAndroid Build Coastguard Worker * the state vector is made of two sub-vector containing respectively: 40*38e8c45fSAndroid Build Coastguard Worker * - modified Rodrigues parameters 41*38e8c45fSAndroid Build Coastguard Worker * - the estimated gyro bias 42*38e8c45fSAndroid Build Coastguard Worker */ 43*38e8c45fSAndroid Build Coastguard Worker quat_t x0; 44*38e8c45fSAndroid Build Coastguard Worker vec3_t x1; 45*38e8c45fSAndroid Build Coastguard Worker 46*38e8c45fSAndroid Build Coastguard Worker /* 47*38e8c45fSAndroid Build Coastguard Worker * the predicated covariance matrix is made of 4 3x3 sub-matrices and it is 48*38e8c45fSAndroid Build Coastguard Worker * semi-definite positive. 49*38e8c45fSAndroid Build Coastguard Worker * 50*38e8c45fSAndroid Build Coastguard Worker * P = | P00 P10 | = | P00 P10 | 51*38e8c45fSAndroid Build Coastguard Worker * | P01 P11 | | P10t P11 | 52*38e8c45fSAndroid Build Coastguard Worker * 53*38e8c45fSAndroid Build Coastguard Worker * Since P01 = transpose(P10), the code below never calculates or 54*38e8c45fSAndroid Build Coastguard Worker * stores P01. 55*38e8c45fSAndroid Build Coastguard Worker */ 56*38e8c45fSAndroid Build Coastguard Worker mat<mat33_t, 2, 2> P; 57*38e8c45fSAndroid Build Coastguard Worker 58*38e8c45fSAndroid Build Coastguard Worker /* 59*38e8c45fSAndroid Build Coastguard Worker * the process noise covariance matrix 60*38e8c45fSAndroid Build Coastguard Worker */ 61*38e8c45fSAndroid Build Coastguard Worker mat<mat33_t, 2, 2> GQGt; 62*38e8c45fSAndroid Build Coastguard Worker 63*38e8c45fSAndroid Build Coastguard Worker public: 64*38e8c45fSAndroid Build Coastguard Worker Fusion(); 65*38e8c45fSAndroid Build Coastguard Worker void init(int mode = FUSION_9AXIS); 66*38e8c45fSAndroid Build Coastguard Worker void handleGyro(const vec3_t& w, float dT); 67*38e8c45fSAndroid Build Coastguard Worker status_t handleAcc(const vec3_t& a, float dT); 68*38e8c45fSAndroid Build Coastguard Worker status_t handleMag(const vec3_t& m); 69*38e8c45fSAndroid Build Coastguard Worker vec4_t getAttitude() const; 70*38e8c45fSAndroid Build Coastguard Worker vec3_t getBias() const; 71*38e8c45fSAndroid Build Coastguard Worker mat33_t getRotationMatrix() const; 72*38e8c45fSAndroid Build Coastguard Worker bool hasEstimate() const; 73*38e8c45fSAndroid Build Coastguard Worker 74*38e8c45fSAndroid Build Coastguard Worker private: 75*38e8c45fSAndroid Build Coastguard Worker struct Parameter { 76*38e8c45fSAndroid Build Coastguard Worker float gyroVar; 77*38e8c45fSAndroid Build Coastguard Worker float gyroBiasVar; 78*38e8c45fSAndroid Build Coastguard Worker float accStdev; 79*38e8c45fSAndroid Build Coastguard Worker float magStdev; 80*38e8c45fSAndroid Build Coastguard Worker } mParam; 81*38e8c45fSAndroid Build Coastguard Worker 82*38e8c45fSAndroid Build Coastguard Worker mat<mat33_t, 2, 2> Phi; 83*38e8c45fSAndroid Build Coastguard Worker vec3_t Ba, Bm; 84*38e8c45fSAndroid Build Coastguard Worker uint32_t mInitState; 85*38e8c45fSAndroid Build Coastguard Worker float mGyroRate; 86*38e8c45fSAndroid Build Coastguard Worker vec<vec3_t, 3> mData; 87*38e8c45fSAndroid Build Coastguard Worker size_t mCount[3]; 88*38e8c45fSAndroid Build Coastguard Worker int mMode; 89*38e8c45fSAndroid Build Coastguard Worker 90*38e8c45fSAndroid Build Coastguard Worker enum { ACC=0x1, MAG=0x2, GYRO=0x4 }; 91*38e8c45fSAndroid Build Coastguard Worker bool checkInitComplete(int, const vec3_t& w, float d = 0); 92*38e8c45fSAndroid Build Coastguard Worker void initFusion(const vec4_t& q0, float dT); 93*38e8c45fSAndroid Build Coastguard Worker void checkState(); 94*38e8c45fSAndroid Build Coastguard Worker void predict(const vec3_t& w, float dT); 95*38e8c45fSAndroid Build Coastguard Worker void update(const vec3_t& z, const vec3_t& Bi, float sigma); 96*38e8c45fSAndroid Build Coastguard Worker static mat34_t getF(const vec4_t& p); 97*38e8c45fSAndroid Build Coastguard Worker static vec3_t getOrthogonal(const vec3_t &v); 98*38e8c45fSAndroid Build Coastguard Worker }; 99*38e8c45fSAndroid Build Coastguard Worker 100*38e8c45fSAndroid Build Coastguard Worker }; // namespace android 101*38e8c45fSAndroid Build Coastguard Worker 102*38e8c45fSAndroid Build Coastguard Worker #endif // ANDROID_FUSION_H 103