xref: /aosp_15_r20/frameworks/native/services/sensorservice/Fusion.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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