tomlankhorst/control
ghk.h
1 
5 #pragma once
6 
7 #include <cmath>
8 
9 namespace control::ghk {
10 
11 // g h k = alpha beta gamma/2
12 template<typename ValueType>
13 struct coeff {
14  ValueType g, h, k;
15 };
16 
17 // x dx ddx
18 template<typename ValueType>
19 struct state {
20  ValueType x, dx, ddx;
21 };
22 
23 namespace parameterize {
24 
25 // Get g h k parameters from alpha beta gamma
26 template<typename ValueType>
27 constexpr coeff<ValueType> abc(ValueType a, ValueType b, ValueType c) {
28  return { a, b, c/2 };
29 }
30 
31 // Get g h k parameters from critical dampened theta
32 // Eli Brookner DSc, Tracking and Kalman Filtering Made Easy - g–h and g–h–k Filters
33 template<typename ValueType>
34 constexpr coeff<ValueType> critical_dampened(ValueType th) {
35  return {
36  1-std::pow(th,3),
37  3*(1-th*th)*(1-th)/2,
38  pow(1-th,3)/2,
39  };
40 }
41 
42 // Get g h k parameters from optimal guassian (Kalman) lambda
43 // J. E. Gray and W. Murray, "A derivation of an analytic expression for the tracking index for the alpha-beta-gamma filter," in IEEE Transactions on Aerospace and Electronic Systems, vol. 29, no. 3, pp. 1064-1065, July 1993, doi: 10.1109/7.220956.
44 template<typename ValueType>
45 constexpr coeff<ValueType> optimal_gaussian(ValueType l) {
46  auto b = l/2-3;
47  auto c = l/2+3;
48  auto d = -1;
49  auto p = c-b*b/3;
50  auto q = 2*b*b*b/27-b*c/3+d;
51  auto v = sqrt(q*q+4*p*p*p/27);
52  auto z = -std::pow(q+v/2,1./3);
53  auto s = z-p/(3*z)-b/3;
54  auto g = 1-s*s;
55  auto h = 2*s*s-4*s+2;
56  auto k = h*h/(2*g)/2;
57  return { g, h, k };
58 }
59 
66 template<typename ValueType>
67 constexpr coeff<ValueType> optimal_gaussian(ValueType s_w, ValueType s_v, ValueType T) {
68  auto l = s_w*T*T/s_v;
69  return optimal_gaussian<ValueType>(l);
70 }
71 
72 }
73 
74 template<typename ValueType>
75 struct result {
76  state<ValueType> correction, prediction;
77 };
78 
79 template<typename ValueType>
80 result<ValueType> correct_predict(const coeff<ValueType>& coeff, state<ValueType> current, ValueType z, ValueType T) {
81  auto& [g,h,k] = coeff;
82 
83  // update with residual
84  auto r = z - current.x;
85 
86  current.x += g*r;
87  current.dx += h/T*r;
88  current.ddx += 2*k/(T*T)*r;
89 
90  auto correct = current;
91 
92  // predict with current value
93  current.x += current.dx*T+current.ddx*T*T/2;
94  current.dx += current.ddx*T;
95 
96  return {correct, current };
97 }
98 
99 }
Definition: ghk.h:75
Definition: ghk.h:9
Definition: ghk.h:19
Definition: ghk.h:13