dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lqg.c
Go to the documentation of this file.
1 
15 /*
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful, but
22  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24  * for more details.
25  *
26  * You should have received a copy of the GNU General Public License along
27  * with this program; if not, see <http://www.gnu.org/licenses/>
28  */
29 
30 #include "lqg.h"
31 
32 /*
33  References
34  =====================================================================================================
35 
36  General idea
37 
38  * Linear Gaussian Quadratic Control System (James Cotton (peabody124), Taulabs)
39  http://buildandcrash.blogspot.be/2016/10/linear-gaussian-quadratic-control-system.html
40 
41  Covariance calculation for LQR, instead of DARE
42 
43  * ECE5530: Multivariable Control Systems II (Dr. Gregory L. Plett)
44  http://mocha-java.uccs.edu/ECE5530/ECE5530-CH03.pdf
45  (Page 34)
46 
47 */
48 
49 /* Worst case attempted (Beta 6, Tau 250ms) with default RTKF weights and LQR costs.
50 
51  RTKF: 1.6KHz = 10569 iterations
52  3.2KHz = 18769
53  6.4KHz = 31760
54  8KHz = 37140
55 
56  LQR: 1.6KHz = 3375 iterations
57  3.2KHz = 6269
58  6.4KHz = 11517
59  8Khz = 14039
60 
61  Capped to 11000, reconsider when we eventually bump the stab loop.
62  That said, beta 6 is very rare, and those with faster loop times probably
63  have faster quads, anyway. The higher the beta, the faster things converge. */
64 #define SOLVER_MIN 100
65 #define SOLVER_MAX 11000
66 
67 /*
68  Beta 7.5 and Tau 50ms solves RTKF in 3077 iterations and the LQR is 1267 iterations.
69  Beta 10.5 and Tau 15ms solves RTKF in 298 iterations and the LQR in 156 iterations.
70 */
71 #define SOLVER_KF_TORQUE_EPSILON 0.000000001f
72 #define SOLVER_KF_BIAS_EPSILON 0.000000001f
73 #define SOLVER_LQR_RATE_EPSILON 0.00000001f
74 #define SOLVER_LQR_TORQUE_EPSILON 0.000001f
75 
76 /* Bullshit to quickly make copypasta of MATLAB answers work. */
77 #define P00 P[0][0]
78 #define P10 P[1][0]
79 #define P20 P[2][0]
80 #define P01 P[0][1]
81 #define P11 P[1][1]
82 #define P21 P[2][1]
83 #define P02 P[0][2]
84 #define P12 P[1][2]
85 #define P22 P[2][2]
86 
87 #define A00 A[0][0]
88 #define A10 A[1][0]
89 #define A20 A[2][0]
90 #define A01 A[0][1]
91 #define A11 A[1][1]
92 #define A21 A[2][1]
93 #define A02 A[0][2]
94 #define A12 A[1][2]
95 #define A22 A[2][2]
96 
97 #define Q00 Q[0][0]
98 #define Q10 Q[1][0]
99 #define Q20 Q[2][0]
100 #define Q01 Q[0][1]
101 #define Q11 Q[1][1]
102 #define Q21 Q[2][1]
103 #define Q02 Q[0][2]
104 #define Q12 Q[1][2]
105 #define Q22 Q[2][2]
106 
107 #define B0 B[0]
108 #define B1 B[1]
109 #define B2 B[2]
110 
111 #define X0 X[0]
112 #define X1 X[1]
113 #define X2 X[2]
114 
115 #define K0 K[0]
116 #define K1 K[1]
117 #define K2 K[2]
118 
119 /*
120  Kalman covariance cycle.
121 
122  P = APA' + Q
123  K = PH' (R+HPH')^-1
124  P = (I-KH) P
125 */
126 bool rtkf_calculate_covariance_3x3(float A[3][3], float K[3], float P[3][3], float Q[3][3], float R)
127 {
128  bool solved = false;
129  float nP[3][3];
130 
131  nP[0][0] = Q00 + A00*(A00*P00 + A01*P10 + A02*P20) + A01*(A00*P01 + A01*P11 + A02*P21) + A02*(A00*P02 + A01*P12 + A02*P22);
132  nP[0][1] = A11*(A00*P01 + A01*P11 + A02*P21) + A12*(A00*P02 + A01*P12 + A02*P22);
133  nP[0][2] = A22*(A00*P02 + A01*P12 + A02*P22);
134 
135  nP[1][0] = A00*(A11*P10 + A12*P20) + A01*(A11*P11 + A12*P21) + A02*(A11*P12 + A12*P22);
136  nP[1][1] = Q11 + A11*(A11*P11 + A12*P21) + A12*(A11*P12 + A12*P22);
137  nP[1][2] = A22*(A11*P12 + A12*P22);
138 
139  nP[2][0] = A22*(A00*P20 + A01*P21 + A02*P22);
140  nP[2][1] = A22*(A11*P21 + A12*P22);
141  nP[2][2] = P22*A22*A22 + Q22;
142 
143  memcpy(P, nP, sizeof(float)*9);
144 
145  float S = P00 + R;
146 
147  float nK[2];
148 
149  K0 = P00/S;
150  nK[0] = P10/S;
151  nK[1] = P20/S;
152 
153  if (fabsf(K1 - nK[0]) <= SOLVER_KF_TORQUE_EPSILON && fabsf(K2 - nK[1]) <= SOLVER_KF_BIAS_EPSILON)
154  solved = true;
155 
156  K1 = nK[0];
157  K2 = nK[1];
158 
159  P10 = P10 - K1*P00;
160  P11 = P11 - K1*P01;
161  P12 = P12 - K1*P02;
162 
163  P20 = P20 - K2*P00;
164  P21 = P21 - K2*P01;
165  P22 = P22 - K2*P02;
166 
167  P00 = P00 - K0*P00;
168  P01 = P01 - K0*P01;
169  P02 = P02 - K0*P02;
170 
171  return solved;
172  }
173 
174 struct rtkf_state {
175 
177 
178  float A[3][3];
179  float B[3];
180  float K[3];
181  float P[3][3];
182  float Q[3][3];
183  float R;
184  float X[3];
185 
186  float biaslim;
187 
188 };
189 
190 /*
191  Repeat the Kalman covariance cycle for specified amount of iterations.
192 
193  Tests show that 50 iterations should be plenty to become stable.
194 */
195  void rtkf_stabilize_covariance(rtkf_t rtkf, int iterations)
196  {
197  PIOS_Assert(rtkf);
198 
199  if (rtkf->solver_iterations < 0)
200  return;
201 
202  for (int i = 0; i < iterations; i++) {
203  rtkf->solver_iterations++;
204  if (rtkf->solver_iterations > SOLVER_MAX) {
205  rtkf->solver_iterations = -2;
206  break;
207  } else if (rtkf_calculate_covariance_3x3(rtkf->A, rtkf->K, rtkf->P, rtkf->Q, rtkf->R) && rtkf->solver_iterations > SOLVER_MIN) {
208  rtkf->solver_iterations = -1;
209  break;
210  }
211  }
212  }
213 
214 /*
215  Kalman prediction
216 
217  X_k+1 = AX_k + Bu_k + K(y - HX)
218 */
219 void rtkf_prediction_step(float A[3][3], float B[3], float K[3], float X[3], float signal, float input)
220 {
221  float nX0, nX1, nX2;
222 
223  nX0 = B0*input + A00*X0 + A01*X1 + A02*X2;
224  nX1 = B1*input + A11*X1 + A12*X2;
225  nX2 = B2*input + A22*X2;
226 
227  X0 = nX0 - K0*(nX0 - signal);
228  X1 = nX1 - K1*(nX0 - signal);
229  float in2 = input*input;
230  X2 = (nX2 - K2*(nX0 - signal)) * bound_min_max(1.0f - in2*in2, 0, 1.0f);
231 }
232 
233 void rtkf_predict_axis(rtkf_t rtkf, float signal, float input, float Xout[3])
234 {
235  rtkf_prediction_step(rtkf->A, rtkf->B, rtkf->K, rtkf->X, signal, input);
236 
237  rtkf->X2 = bound_sym(rtkf->X2, rtkf->biaslim);
238 
239  Xout[0] = rtkf->X0;
240  Xout[1] = rtkf->X1;
241  Xout[2] = rtkf->X2;
242 }
243 
244 /*
245  Rate-torque Kalman filter system.
246 
247  A = [ 1 Beta*(tau-tau*e^(-Ts/tau)) -Ts*Beta+Beta*(tau-tau*e^(-Ts/tau)) ]
248  [ 0 e^(-Ts/tau) e^(-Ts/tau)-1 ]
249  [ 0 0 1 ]
250 
251  B = [ Ts*Beta-Beta*(tau-tau*e^(-Ts/tau)) ]
252  [ 1-e^(-Ts/tau) ]
253  [ 0 ]
254 */
255 void rtkf_initialize_matrices_int(float A[3][3], float B[3], float beta, float tau, float Ts)
256 {
257  A00 = 1;
258  A01 = beta*(tau - tau*expf(-Ts/tau));
259  A02 = beta*(tau - tau*expf(-Ts/tau)) - Ts*beta;
260  A11 = expf(-Ts/tau);
261  A12 = expf(-Ts/tau) - 1;
262  A22 = 1;
263 
264  B0 = Ts*beta - beta*(tau - tau*expf(-Ts/tau));
265  B1 = 1 - expf(-Ts/tau);
266  B2 = 0;
267 }
268 
269 /*
270  Q matrix set by experimentation.
271 
272  R = 1000 seems a workable value for raw gyro input.
273 */
274 rtkf_t rtkf_create(float beta, float tau, float Ts, float R, float q1, float q2, float q3, float biaslim)
275 {
276  struct rtkf_state *state = PIOS_malloc_no_dma(sizeof(*state));
277  PIOS_Assert(state);
278  memset(state, 0, sizeof(*state));
279 
280  rtkf_initialize_matrices_int(state->A, state->B, expf(beta), tau, Ts);
281  state->Q00 = q1;
282  state->Q11 = q2;
283  state->Q22 = q3;
284  state->R = R;
285  state->biaslim = biaslim;
286 
287  return state;
288 }
289 
291 {
292  if (rtkf->solver_iterations >= 0)
293  return LQG_SOLVER_RUNNING;
294  else if (rtkf->solver_iterations == -1)
295  return LQG_SOLVER_DONE;
296  return LQG_SOLVER_FAILED;
297 }
298 
299 /*
300  LQR covariance cycle.
301 
302  P = A'PA - A'PB (R+B'PB)^-1 B'PA + Q
303 
304  K = (R + B'PB)^-1 B'PA
305 
306  TODO: Should redo and optimize the math of this, after folding gains calculation into this.
307  Because of obvious substitutions.
308 */
309 bool lqr_calculate_covariance_2x2(float A[2][2], float B[2], float K[2], float P[2][2], float Q[2][2], float R)
310 {
311  float nP[2][2];
312 
313  float B0B0 = B0*B0;
314  float B1B1 = B1*B1;
315  float B0B1 = B0*B1;
316  float A00A00 = A00*A00;
317  float A01A01 = A01*A01;
318  float A11A11 = A11*A11;
319  float P01P10 = P01*P10;
320  float P00P11 = P00*P11;
321 
322  float div = (R + B0B0*P00 + B1B1*P11 + B0B1*(P01 + P10));
323 
324  nP[0][0] = (Q00*R + P00*(A00A00*R + B0B0*Q00) +
325  B1B1*(P11*Q00 + A00A00*(P00P11 - P01P10)) +
326  B0B1*Q00*(P01 + P10))
327  /
328  div;
329 
330  float common = A01*(P00*R + B1B1*(P00P11 - P01P10)) - A11*B0B1*(P00P11 + P01P10);
331 
332  nP[1][0] = (A00*(A11*P10*R + common))
333  /
334  div;
335 
336  nP[0][1] = (A00*(A11*P01*R + common))
337  /
338  div;
339 
340  nP[1][1] = (Q11*R + A01A01*P00*R + B0B0*P00*Q11 +
341  A11A11*(P11*R + B0B0*(P00P11 - P01P10)) +
342  B1B1*(P11*Q11 + A01A01*P00P11 - A01A01*P01P10) +
343  A01*A11*P01*R + A01*A11*P10*R + B0B1*P01*Q11 +
344  B0B1*(P10*Q11 - 2*A01*A11*P00P11 + 2*A01*A11*P01P10))
345  /
346  div;
347 
348  P00 = nP[0][0];
349  P01 = nP[0][1];
350  P10 = nP[1][0];
351  P11 = nP[1][1];
352 
353  bool solved = false;
354 
355  div = (R + B1*B1*P11 + B0*(B0*P00 + B1*(P01 + P10)));
356  float nK[2];
357 
358  nK[0] = (A00*(B0*P00 + B1*P10)) / div;
359  nK[1] = (A01*(B0*P00 + B1*P10) + A11*(B0*P01 + B1*P11)) / div;
360 
361  if (fabsf(K0 - nK[0]) <= SOLVER_LQR_RATE_EPSILON && fabsf(K1 - nK[1]) <= SOLVER_LQR_TORQUE_EPSILON)
362  solved = true;
363 
364  K0 = nK[0];
365  K1 = nK[1];
366 
367  return solved;
368 }
369 
370 struct lqr_state {
371 
373 
374  float A[2][2];
375  float B[2];
376  float K[2];
377  float P[2][2];
378  float R;
379  float Q[2][2];
380  float u;
381 
382  float beta;
383  float tau;
384 
385 };
386 
387 /*
388  Repeat the LQR covariance cycle for as much iterations needed.
389 
390  Discrete algrebraic Riccati "solver" for dumb people.
391 
392  Experimentation shows that it needs at least 700-800 iterations to become stable. Stabilizing
393  two rate-controller LQR systems (say for roll and pitch axis) with 1000 iterations works
394  within a fraction of a second on an STM32F405.
395 
396  The end results pretty much match covariances calculated with dare() in MATLAB. Calculated
397  gains from this also match what dlqr() spits out.
398 
399  Trying peabody124's old branch last year, his proper DARE solver using Eigen took the best of
400  five seconds. It was a tri-state LQR though.
401 
402  Changing the Q state weight matrix in middle operation usually seems to restabilize within
403  a 100 cycles, so TxPID for tuning might qualify.
404 */
405 void lqr_stabilize_covariance(lqr_t lqr, int iterations)
406 {
407  PIOS_Assert(lqr);
408 
409  if (lqr->solver_iterations < 0)
410  return;
411 
412  for (int i = 0; i < iterations; i++) {
413  lqr->solver_iterations++;
414  if (lqr->solver_iterations > SOLVER_MAX) {
415  lqr->solver_iterations = -2;
416  break;
417  } else if (lqr_calculate_covariance_2x2(lqr->A, lqr->B, lqr->K, lqr->P, lqr->Q, lqr->R) && lqr->solver_iterations > SOLVER_MIN) {
418  lqr->solver_iterations = -1;
419  break;
420  }
421  }
422 }
423 
425 {
426  if (lqr->solver_iterations >= 0)
427  return LQG_SOLVER_RUNNING;
428  else if (lqr->solver_iterations == -1)
429  return LQG_SOLVER_DONE;
430  return LQG_SOLVER_FAILED;
431 }
432 
433 /*
434  LQR rate controller.
435 
436  A = [ 1 tau*Beta*(1-e^(-Ts/tau)) ]
437  [ 0 e^(-Ts/tau) ]
438 
439  B = [ Ts*Beta-tau*Beta*(1-e^(-Ts/tau)) ]
440  [ 1-e^(-Ts/tau) ]
441 */
442 void lqr_initialize_matrices_int(float A[2][2], float B[2], float beta, float tau, float Ts)
443 {
444  A00 = 1;
445  A01 = -beta*tau*(expf(-Ts/tau) - 1);
446  A10 = 0;
447  A11 = expf(-Ts/tau);
448 
449  B0 = Ts*beta + beta*tau*(expf(-Ts/tau) - 1);
450  B1 = 1 - expf(-Ts/tau);
451 }
452 
453 /*
454  Q1 and Q2 in the state weighting matrix penalizes rate and torque.
455 
456  Need to talk to peabody124 about the difference in magnitude. Q2 uses frame invariance idea.
457 
458  Current workable values for 5" miniquads seems to be Q1 = 0.00001, Q2 = 0.00013333.
459 */
460 lqr_t lqr_create(float beta, float tau, float Ts, float q1, float q2, float r)
461 {
462  struct lqr_state *state = PIOS_malloc_no_dma(sizeof(*state));
463  PIOS_Assert(state);
464  memset(state, 0, sizeof(*state));
465 
466  lqr_initialize_matrices_int(state->A, state->B, expf(beta), tau, Ts);
467  state->Q00 = q1;
468  state->Q11 = q2*expf(beta);
469  state->R = r;
470 
471  state->beta = beta;
472  state->tau = tau;
473 
474  return state;
475 }
476 
477 void lqr_update(lqr_t lqr, float q1, float q2, float r)
478 {
479  PIOS_Assert(lqr);
480 
481  lqr->Q00 = q1;
482  lqr->Q11 = q2*expf(lqr->beta);
483  lqr->R = r;
484  lqr->solver_iterations = 0;
485 }
486 
487 void lqr_get_gains(lqr_t lqr, float K[2])
488 {
489  PIOS_Assert(lqr);
490  K[0] = lqr->K[0];
491  K[1] = lqr->K[1];
492 }
493 
494 
495 struct lqg_state {
496 
497  int axis;
498 
499  struct lqr_state *lqr;
500  struct rtkf_state *rtkf;
501 
502 };
503 
504 /*
505  Estimate the system state, i.e. presumed true rate and torque, then
506  feed it into the LQR.
507 
508  xr = x - setpoint
509 
510  u = -K*xr + bias
511 
512  u gets clamped to -1..1 because that's the actuator range. Might also prevent the
513  RTKF to go overboard with predicting, when the LQR is trying to demand a lot from the
514  actuators.
515 */
516 float lqg_controller(lqg_t lqg, float signal, float setpoint)
517 {
518  lqr_t lqr = lqg->lqr;
519  rtkf_t rtkf = lqg->rtkf;
520 
521  float x_est[3]; /* Rate, Torque, Bias */
522  rtkf_predict_axis(rtkf, signal, lqr->u, x_est);
523 
524  float xr0 = x_est[0] - setpoint;
525 
526  float u = x_est[2] - lqr->K0 * xr0 - lqr->K1 * x_est[1];
527  if (u < -1) u = -1;
528  else if (u > 1) u = 1;
529 
530  lqr->u = u;
531 
532  return u;
533 }
534 
536 {
537  PIOS_Assert(rtkf);
538  PIOS_Assert(lqr);
539 
540  struct lqg_state *state = PIOS_malloc_no_dma(sizeof(*state));
541  PIOS_Assert(state);
542  memset(state, 0, sizeof(*state));
543 
544  state->rtkf = rtkf;
545  state->lqr = lqr;
546 
547  return state;
548 }
549 
550 void lqg_get_rtkf_state(lqg_t lqg, float *rate, float *torque, float *bias)
551 {
552  *rate = lqg->rtkf->X[0];
553  *torque = lqg->rtkf->X[1];
554  *bias = lqg->rtkf->X[2];
555 }
556 
557 void lqg_set_x0(lqg_t lqg, float x0)
558 {
559  lqg->rtkf->X[0] = x0;
560  lqg->rtkf->X[1] = 0;
561  lqg->rtkf->X[2] = 0;
562 }
563 
565 {
566  if (!lqg)
567  return LQG_SOLVER_FAILED;
568  return MIN(lqr_solver_status(lqg->lqr), rtkf_solver_status(lqg->rtkf));
569 }
570 
572 {
573  return lqg ? lqg->rtkf : NULL;
574 }
575 
577 {
578  return lqg ? lqg->lqr : NULL;
579 }
580 
581 void lqg_run_covariance(lqg_t lqg, int iter)
582 {
583  rtkf_t rtkf = lqg_get_rtkf(lqg);
584  lqr_t lqr = lqg_get_lqr(lqg);
585  PIOS_Assert(rtkf);
586  PIOS_Assert(lqr);
587 
589  rtkf_stabilize_covariance(rtkf, iter);
591  lqr_stabilize_covariance(lqr, iter);
592 }
593 
float A[2][2]
Definition: lqg.c:374
float B[3]
Definition: lqg.c:179
LQG Control algorithm.
#define A00
Definition: lqg.c:87
float Q[NUMW]
Definition: insgps14state.c:67
#define B2
Definition: lqg.c:109
#define Q11
Definition: lqg.c:101
rtkf_t lqg_get_rtkf(lqg_t lqg)
Definition: lqg.c:571
#define K0
Definition: lqg.c:115
#define X1
Definition: lqg.c:112
float beta
Definition: lqg.c:382
int solver_iterations
Definition: lqg.c:176
float P[3][3]
Definition: lqg.c:181
void rtkf_stabilize_covariance(rtkf_t rtkf, int iterations)
Definition: lqg.c:195
#define X2
Definition: lqg.c:113
int solver_iterations
Definition: lqg.c:372
float R[NUMV]
Definition: insgps14state.c:67
#define P01
Definition: lqg.c:80
lqg_t lqg_create(rtkf_t rtkf, lqr_t lqr)
Definition: lqg.c:535
#define LQG_SOLVER_RUNNING
Definition: lqg.h:37
void lqr_get_gains(lqr_t lqr, float K[2])
Definition: lqg.c:487
#define P10
Definition: lqg.c:78
#define X0
Definition: lqg.c:111
#define B0
Definition: lqg.c:107
float P[NUMX][NUMX]
Definition: insgps14state.c:66
lqr_t lqg_get_lqr(lqg_t lqg)
Definition: lqg.c:576
#define K2
Definition: lqg.c:117
#define SOLVER_KF_TORQUE_EPSILON
Definition: lqg.c:71
void rtkf_prediction_step(float A[3][3], float B[3], float K[3], float X[3], float signal, float input)
Definition: lqg.c:219
#define P22
Definition: lqg.c:85
void lqg_set_x0(lqg_t lqg, float x0)
Definition: lqg.c:557
void * PIOS_malloc_no_dma(size_t size)
Definition: pios_heap.c:166
#define SOLVER_MAX
Definition: lqg.c:65
struct rtkf_state * rtkf
Definition: lqg.c:500
#define A10
Definition: lqg.c:88
#define P11
Definition: lqg.c:81
float K[2]
Definition: lqg.c:376
#define Q00
Definition: lqg.c:97
void lqr_update(lqr_t lqr, float q1, float q2, float r)
Definition: lqg.c:477
bool lqr_calculate_covariance_2x2(float A[2][2], float B[2], float K[2], float P[2][2], float Q[2][2], float R)
Definition: lqg.c:309
#define B1
Definition: lqg.c:108
float A[3][3]
Definition: lqg.c:178
#define P02
Definition: lqg.c:83
void lqr_stabilize_covariance(lqr_t lqr, int iterations)
Definition: lqg.c:405
#define SOLVER_MIN
Definition: lqg.c:64
#define SOLVER_KF_BIAS_EPSILON
Definition: lqg.c:72
#define P21
Definition: lqg.c:82
Definition: lqg.c:495
float R
Definition: lqg.c:183
int axis
Definition: lqg.c:497
#define SOLVER_LQR_TORQUE_EPSILON
Definition: lqg.c:74
bool rtkf_calculate_covariance_3x3(float A[3][3], float K[3], float P[3][3], float Q[3][3], float R)
Definition: lqg.c:126
struct lqr_state * lqr
Definition: lqg.c:499
int rtkf_solver_status(rtkf_t rtkf)
Definition: lqg.c:290
float B[2]
Definition: lqg.c:375
#define SOLVER_LQR_RATE_EPSILON
Definition: lqg.c:73
float X[3]
Definition: lqg.c:184
void lqr_initialize_matrices_int(float A[2][2], float B[2], float beta, float tau, float Ts)
Definition: lqg.c:442
uint8_t i
Definition: msp_messages.h:97
float bound_min_max(float val, float min, float max)
Bound input value between min and max.
Definition: misc_math.c:38
float bound_sym(float val, float range)
Bound input value within range (plus or minus)
Definition: misc_math.c:50
#define A02
Definition: lqg.c:93
#define Q22
Definition: lqg.c:105
void lqg_run_covariance(lqg_t lqg, int iter)
Definition: lqg.c:581
void lqg_get_rtkf_state(lqg_t lqg, float *rate, float *torque, float *bias)
Definition: lqg.c:550
#define LQG_SOLVER_FAILED
Definition: lqg.h:36
float P[2][2]
Definition: lqg.c:377
#define A22
Definition: lqg.c:95
#define P12
Definition: lqg.c:84
#define K1
Definition: lqg.c:116
float tau
Definition: lqg.c:383
#define A11
Definition: lqg.c:91
uint8_t rate
Definition: msp_messages.h:99
#define P00
Definition: lqg.c:77
tuple f
Definition: px_mkfw.py:81
#define LQG_SOLVER_DONE
Definition: lqg.h:38
float Q[2][2]
Definition: lqg.c:379
#define A01
Definition: lqg.c:90
lqr_t lqr_create(float beta, float tau, float Ts, float q1, float q2, float r)
Definition: lqg.c:460
#define MIN(a, b)
Definition: misc_math.h:41
rtkf_t rtkf_create(float beta, float tau, float Ts, float R, float q1, float q2, float q3, float biaslim)
Definition: lqg.c:274
void rtkf_initialize_matrices_int(float A[3][3], float B[3], float beta, float tau, float Ts)
Definition: lqg.c:255
float R
Definition: lqg.c:378
float Q[3][3]
Definition: lqg.c:182
float K[3]
Definition: lqg.c:180
float biaslim
Definition: lqg.c:186
void rtkf_predict_axis(rtkf_t rtkf, float signal, float input, float Xout[3])
Definition: lqg.c:233
#define P20
Definition: lqg.c:79
Definition: lqg.c:370
float lqg_controller(lqg_t lqg, float signal, float setpoint)
Definition: lqg.c:516
float X[NUMX]
Definition: insgps14state.c:66
float K[NUMX][NUMV]
Definition: insgps14state.c:68
float u
Definition: lqg.c:380
#define A12
Definition: lqg.c:94
#define PIOS_Assert(test)
Definition: pios_debug.h:52
int lqr_solver_status(lqr_t lqr)
Definition: lqg.c:424
int lqg_solver_status(lqg_t lqg)
Definition: lqg.c:564
enum arena_state state