xyControl  0.1
Quadrotor Flight Controller on AVR Basis
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups
kalman.c
Go to the documentation of this file.
1 /*
2  * kalman.c
3  *
4  * Copyright Linus Helgesson
5  * http://www.linushelgesson.se/2012/04/pitch-and-roll-estimating-kalman-filter-for-stabilizing-quadrocopters/
6  *
7  * Copyright (c) 2013, Thomas Buck <xythobuz@me.com>
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * - Redistributions of source code must retain the above copyright notice,
14  * this list of conditions and the following disclaimer.
15  *
16  * - Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in the
18  * documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 #include <stdint.h>
33 #include <avr/io.h>
34 
35 #include <kalman.h>
36 #include <config.h>
37 
47 // Setup the kalman data struct
48 void kalmanInit(Kalman *data) {
49  data->x1 = 0.0f;
50  data->x2 = 0.0f;
51  data->x3 = 0.0f;
52 
53  // Init P to diagonal matrix with large values since
54  // the initial state is not known
55  data->p11 = 1000.0f;
56  data->p12 = 0.0f;
57  data->p13 = 0.0f;
58  data->p21 = 0.0f;
59  data->p22 = 1000.0f;
60  data->p23 = 0.0f;
61  data->p31 = 0.0f;
62  data->p32 = 0.0f;
63  data->p33 = 1000.0f;
64 }
65 
66 void kalmanInnovate(Kalman *data, double z1, double z2) {
67  double y1, y2;
68  double a, b, c;
69  double sDet;
70  double s11, s12, s21, s22;
71  double k11, k12, k21, k22, k31, k32;
72  double p11, p12, p13, p21, p22, p23, p31, p32, p33;
73 
74  // Step 1
75  // x(k) = Fx(k-1) + Bu + w:
76  data->x1 = data->x1 + DT*data->x2 - DT*data->x3;
77  //x2 = x2;
78  //x3 = x3;
79 
80  // Step 2
81  // P = FPF'+Q
82  a = data->p11 + data->p21*DT - data->p31*DT;
83  b = data->p12 + data->p22*DT - data->p32*DT;
84  c = data->p13 + data->p23*DT - data->p33*DT;
85  data->p11 = a + b*DT - c*DT + Q1;
86  data->p12 = b;
87  data->p13 = c;
88  data->p21 = data->p21 + data->p22*DT - data->p23*DT;
89  data->p22 = data->p22 + Q2;
90  //p23 = p23;
91  data->p31 = data->p31 + data->p32*DT - data->p33*DT;
92  //p32 = p32;
93  data->p33 = data->p33 + Q3;
94 
95  // Step 3
96  // y = z(k) - Hx(k)
97  y1 = z1-data->x1;
98  y2 = z2-data->x2;
99 
100  // Step 4
101  // S = HPT' + R
102  s11 = data->p11 + R1;
103  s12 = data->p12;
104  s21 = data->p21;
105  s22 = data->p22 + R2;
106 
107  // Step 5
108  // K = PH*inv(S)
109  sDet = 1/(s11*s22 - s12*s21);
110  k11 = (data->p11*s22 - data->p12*s21)*sDet;
111  k12 = (data->p12*s11 - data->p11*s12)*sDet;
112  k21 = (data->p21*s22 - data->p22*s21)*sDet;
113  k22 = (data->p22*s11 - data->p21*s12)*sDet;
114  k31 = (data->p31*s22 - data->p32*s21)*sDet;
115  k32 = (data->p32*s11 - data->p31*s12)*sDet;
116 
117  // Step 6
118  // x = x + Ky
119  data->x1 = data->x1 + k11*y1 + k12*y2;
120  data->x2 = data->x2 + k21*y1 + k22*y2;
121  data->x3 = data->x3 + k31*y1 + k32*y2;
122 
123  // Step 7
124  // P = (I-KH)P
125  p11 = data->p11*(1.0f - k11) - data->p21*k12;
126  p12 = data->p12*(1.0f - k11) - data->p22*k12;
127  p13 = data->p13*(1.0f - k11) - data->p23*k12;
128  p21 = data->p21*(1.0f - k22) - data->p11*k21;
129  p22 = data->p22*(1.0f - k22) - data->p12*k21;
130  p23 = data->p23*(1.0f - k22) - data->p13*k21;
131  p31 = data->p31 - data->p21*k32 - data->p11*k31;
132  p32 = data->p32 - data->p22*k32 - data->p12*k31;
133  p33 = data->p33 - data->p22*k32 - data->p13*k31;
134  data->p11 = p11; data->p12 = p12; data->p13 = p13;
135  data->p21 = p21; data->p22 = p22; data->p23 = p23;
136  data->p31 = p31; data->p32 = p32; data->p33 = p33;
137 }