ESP-IDF Firmware
Firmware architecture and call graph
Loading...
Searching...
No Matches
ekf_imu13states.cpp
Go to the documentation of this file.
1// Copyright 2020-2021 Espressif Systems (Shanghai) PTE LTD
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "ekf_imu13states.h"
16#include <cmath>
17
19 mag0(3, 1),
20 accel0(3, 1)
21{
22 this->NUMU = 3;
23}
24
28
30{
31 mag0.data[0] = 1;
32 mag0.data[1] = 0;
33 mag0.data[2] = 0;
34
35 mag0 /= mag0.norm();
36
37 accel0.data[0] = 0;
38 accel0.data[1] = 0;
39 accel0.data[2] = 1;
40
41 accel0 /= accel0.norm();
42
43 this->Q.Copy(0.1 * dspm::Mat::eye(3), 0, 0);
44 this->Q.Copy(0.0001 * dspm::Mat::eye(3), 3, 3);
45 this->Q.Copy(0.0001 * dspm::Mat::eye(3), 6, 6);
46 this->Q.Copy(0.0001 * dspm::Mat::eye(3), 9, 9);
47 this->Q.Copy(0.00001 * dspm::Mat::eye(3), 12, 12);
48 this->Q.Copy(0.00001 * dspm::Mat::eye(3), 15, 15);
49
50 this->X.data[0] = 1; // Init quaternion
51 this->X.data[7] = 1; // Initial magnetometer vector
52}
53
55{
56 float wx = u[0] - x(4, 0); // subtract the biases on gyros
57 float wy = u[1] - x(5, 0);
58 float wz = u[2] - x(6, 0);
59
60 float w[] = {wx, wy, wz};
61 dspm::Mat q = dspm::Mat(x.data, 4, 1);
62
63 // qdot = Q * w
64 dspm::Mat Omega = 0.5 * SkewSym4x4(w);
65 dspm::Mat qdot = Omega * q;
66 dspm::Mat Xdot(this->NUMX, 1);
67 Xdot *= 0;
68 Xdot.Copy(qdot, 0, 0);
69 // dwbias = 0
70 // dMang_Ampl = 0
71 // dMang_offset = 0
72 return Xdot;
73}
74
76{
77 float w[3] = {(u[0] - x(4, 0)), (u[1] - x(5, 0)), (u[2] - x(6, 0))}; // subtract the biases on gyros
78 // float w[3] = {u[0], u[1], u[2]}; // subtract the biases on gyros
79
80 this->F *= 0; // Initialize F and G matrixes.
81 this->G *= 0;
82
83 // dqdot / dq - skey matrix
84 F.Copy(0.5 * ekf::SkewSym4x4(w), 0, 0);
85
86 // dqdot/dvector
87 dspm::Mat dq = -0.5 * qProduct(x.data);
88 dspm::Mat dq_q = dq.Get(0, 4, 1, 3);
89
90 // dqdot / dnw
91 G.Copy(dq_q, 0, 0);
92 // dqdot / dwbias
93 F.Copy(dq_q, 0, 4);
94
95 dspm::Mat rotm = -1 * this->quat2rotm(x.data); // Convert quat to rotation matrix
96
97 G.Copy(rotm, 7, 6);
98 G.Copy(dspm::Mat::eye(3), 4, 3); // random noise wbias
99 G.Copy(dspm::Mat::eye(3), 7, 12); // random noise magnetometer amplitude
100 G.Copy(dspm::Mat::eye(3), 10, 9); // magnetometer offset constant
101 G.Copy(dspm::Mat::eye(3), 10, 15); // random noise offset constant
102}
103
105{
106 dspm::Mat test_x(7, 1);
107 for (size_t i = 0; i < 7; i++) {
108 test_x(i, 0) = i;
109 }
110 printf("Allocate data = %i\n", this->NUMU);
111 float *test_u = new float[this->NUMU];
112 for (size_t i = 0; i < this->NUMU; i++) {
113 test_u[i] = i;
114 }
115 dspm::Mat result_StateXdot = StateXdot(test_x, test_u);
116 delete[] test_u;
117}
118
119void ekf_imu13states::TestFull(bool enable_att)
120{
121 int total_N = 2048;
122 float pi = std::atan(1) * 4;
123 float gyro_err_data[] = {0.1, 0.2, 0.3}; // static constatnt error
124 dspm::Mat gyro_err(gyro_err_data, 3, 1);
125 float R[10];
126 for (size_t i = 0; i < 10; i++) {
127 R[i] = 0.01;
128 }
129
130 float accel0_data[] = {0, 0, 1};
131 float magn0_data[] = {1, 0, 0};
132
133 dspm::Mat accel0(accel0_data, 3, 1);
134 dspm::Mat magn0(magn0_data, 3, 1);
135
136 float dt = 0.01;
137
138 dspm::Mat gyro_data(3, 1);
139 int count = 0;
140
141 // Initial rotation matrix
144
145 gyro_err *= 1;
146
147 std::cout << "Gyro error: " << gyro_err.t() << std::endl;
148 for (size_t n = 1; n < total_N * 3; n++) {
149 if ((n % 1000) == 0) {
150 std::cout << "Loop " << n << " from " << total_N * 16;
151 std::cout << ", State data : " << this->X.t();
152 }
153 gyro_data *= 0; // reset gyro value
154 if ((n >= (total_N / 2)) && (n < total_N * 12)) {
155 gyro_data(0, 0) = 1 / pi * std::cos(-pi / 2 + pi / 2 * count * 2 / (total_N / 10));
156 gyro_data(1, 0) = 2 / pi * std::cos(-pi / 2 + pi / 2 * count * 2 / (total_N / 10));
157 gyro_data(2, 0) = 3 / pi * std::cos(-pi / 2 + pi / 2 * count * 2 / (total_N / 10));
158 count++;
159 }
160 dspm::Mat gyro_sample = gyro_data + gyro_err;
161
162 gyro_data *= dt;
163 Re = this->eul2rotm(gyro_data.data); // Calculate rotation to gyro angel
164 Rm = Rm * Re; // Rotate original matrix
165 dspm::Mat attitude = ekf::rotm2quat(Rm);
166 // We have to rotate accel and magn to the opposite direction
167 dspm::Mat accel_data = Rm.t() * accel0;
168 dspm::Mat magn_data = Rm.t() * magn0;
169
170 dspm::Mat accel_norm = accel_data / accel_data.norm();
171 dspm::Mat magn_norm = magn_data / magn_data.norm();
172
173 float input_u[] = {gyro_sample(0, 0), gyro_sample(1, 0), gyro_sample(2, 0)};
174 // Process input values to new state
175 this->Process(input_u, dt);
176 dspm::Mat q_norm(this->X.data, 4, 1);
177 q_norm /= q_norm.norm();
178
179 if (true == enable_att) {
180 this->UpdateRefMeasurement(accel_norm.data, magn_norm.data, attitude.data, R);
181 } else {
182 this->UpdateRefMeasurement(accel_norm.data, magn_norm.data, R);
183 }
184 }
185 std::cout << "Final State data : " << this->X.t() << std::endl;
186}
187
188void ekf_imu13states::UpdateRefMeasurement(float *accel_data, float *magn_data, float R[6])
189{
190 dspm::Mat quat(this->X.data, 4, 1);
191 dspm::Mat H = 0 * dspm::Mat(6, this->NUMX);
192 dspm::Mat Re = this->quat2rotm(quat.data).t();
193
194 // dAccel/dq
195 dspm::Mat dAccel_dq = ekf::dFdq_inv(this->accel0, quat);
196 H.Copy(dAccel_dq, 3, 0);
197
198 // dMagn/dq
199 dspm::Mat magn(&this->X.data[7], 3, 1);
200 dspm::Mat magn_offset(&this->X.data[10], 3, 1);
201 dspm::Mat dMagn_dq = ekf::dFdq_inv(magn, quat);
202 H.Copy(dMagn_dq, 0, 0);
203
204 dspm::Mat expected_magn = Re * magn + magn_offset;
205 dspm::Mat expected_accel = Re * this->accel0;
206
207 float measured_data[6];
208 float expected_data[6];
209 for (size_t i = 0; i < 3; i++) {
210 measured_data[i] = magn_data[i];
211 expected_data[i] = expected_magn.data[i];
212 measured_data[i + 3] = accel_data[i];
213 expected_data[i + 3] = expected_accel.data[i];
214 }
215
216 this->Update(H, measured_data, expected_data, R);
217 quat /= quat.norm();
218}
219
220void ekf_imu13states::UpdateRefMeasurementMagn(float *accel_data, float *magn_data, float R[6])
221{
222 dspm::Mat quat(this->X.data, 4, 1);
223 dspm::Mat H = 0 * dspm::Mat(6, this->NUMX);
224 dspm::Mat Re = this->quat2rotm(quat.data).t();
225
226 // We include these two line to update magnetometer initial state
227 H.Copy(Re, 0, 7);
228 H.Copy(dspm::Mat::eye(3), 0, 10);
229
230 // dAccel/dq
231 dspm::Mat dAccel_dq = ekf::dFdq_inv(this->accel0, quat);
232 H.Copy(dAccel_dq, 3, 0);
233
234 // dMagn/dq
235 dspm::Mat magn(&this->X.data[7], 3, 1);
236 dspm::Mat magn_offset(&this->X.data[10], 3, 1);
237 dspm::Mat dMagn_dq = ekf::dFdq_inv(magn, quat);
238 H.Copy(dMagn_dq, 0, 0);
239
240 dspm::Mat expected_magn = Re * magn + magn_offset;
241 dspm::Mat expected_accel = Re * this->accel0;
242
243 float measured_data[6];
244 float expected_data[6];
245 for (size_t i = 0; i < 3; i++) {
246 measured_data[i] = magn_data[i];
247 expected_data[i] = expected_magn.data[i];
248 measured_data[i + 3] = accel_data[i];
249 expected_data[i + 3] = expected_accel.data[i];
250 }
251
252 this->Update(H, measured_data, expected_data, R);
253 quat /= quat.norm();
254}
255
256void ekf_imu13states::UpdateRefMeasurement(float *accel_data, float *magn_data, float *attitude, float R[10])
257{
258 dspm::Mat quat(this->X.data, 4, 1);
259 dspm::Mat H = 0 * dspm::Mat(10, this->NUMX);
260 dspm::Mat Re = this->quat2rotm(quat.data).t();
261
262 H.Copy(Re, 0, 7);
263 H.Copy(dspm::Mat::eye(3), 0, 10);
264 // dAccel/dq
265 dspm::Mat dAccel_dq = ekf::dFdq_inv(this->accel0, quat);
266 H.Copy(dAccel_dq, 3, 0);
267 // dMagn/dq
268 dspm::Mat magn(&this->X.data[7], 3, 1);
269 dspm::Mat magn_offset(&this->X.data[10], 3, 1);
270 dspm::Mat dMagn_dq = ekf::dFdq_inv(magn, quat);
271 H.Copy(dMagn_dq, 0, 0);
272
273 // dq/dq
274 H.Copy(dspm::Mat::eye(4), 6, 1);
275
276 dspm::Mat expected_magn = Re * magn + magn_offset;
277 dspm::Mat expected_accel = Re * this->accel0;
278
279 float measured_data[10];
280 float expected_data[10];
281 for (size_t i = 0; i < 3; i++) {
282 measured_data[i] = magn_data[i];
283 expected_data[i] = expected_magn.data[i];
284 measured_data[i + 3] = accel_data[i];
285 expected_data[i + 3] = expected_accel.data[i];
286 }
287 for (size_t i = 0; i < 4; i++) {
288 measured_data[i + 6] = attitude[i];
289 expected_data[i + 6] = this->X.data[i];
290 }
291
292 this->Update(H, measured_data, expected_data, R);
293 quat /= quat.norm();
294}
Matrix.
Definition mat.h:30
Mat Get(int row_start, int row_size, int col_start, int col_size)
Definition mat.cpp:209
float * data
Definition mat.h:37
float norm(void)
Definition mat.cpp:456
static Mat eye(int size)
Definition mat.cpp:394
void Copy(const Mat &src, int row_pos, int col_pos)
Definition mat.cpp:168
Mat t()
Definition mat.cpp:383
void TestFull(bool enable_att)
virtual ~ekf_imu13states()
void UpdateRefMeasurement(float *accel_data, float *magn_data, float R[6])
virtual void LinearizeFG(dspm::Mat &x, float *u)
void UpdateRefMeasurementMagn(float *accel_data, float *magn_data, float R[6])
virtual dspm::Mat StateXdot(dspm::Mat &x, float *u)
virtual void Init()
static dspm::Mat rotm2quat(dspm::Mat &R)
Definition ekf.cpp:305
dspm::Mat & F
Definition ekf.h:78
static dspm::Mat dFdq_inv(dspm::Mat &vector, dspm::Mat &quat)
Definition ekf.cpp:389
virtual void Process(float *u, float dt)
Definition ekf.cpp:53
ekf(int x, int w)
Definition ekf.cpp:19
static dspm::Mat quat2rotm(float q[4])
Definition ekf.cpp:209
int NUMX
Definition ekf.h:63
static dspm::Mat eul2rotm(float xyz[3])
Definition ekf.cpp:251
dspm::Mat & G
Definition ekf.h:82
virtual void Update(dspm::Mat &H, float *measured, float *expected, float *R)
Definition ekf.cpp:149
dspm::Mat & X
Definition ekf.h:73
dspm::Mat & Q
Definition ekf.h:92
static dspm::Mat qProduct(float *q)
Definition ekf.cpp:112
static dspm::Mat SkewSym4x4(float *w)
Definition ekf.cpp:81
float x[1024]
Definition test_fir.c:10
const int n
Definition test_mmult.c:17