5
5
6
6
namespace fcarouge ::eigen::sample {
7
7
namespace {
8
+
8
9
// ! @brief ArduPilot Plane Soaring
9
10
// !
10
11
// ! @copyright This example is transcribed from the ArduPilot Soaring Plane
@@ -36,15 +37,15 @@ namespace {
36
37
kalman k;
37
38
38
39
// Initialization
39
- const float trigger_strength{1 / 4.06 };
40
+ const float trigger_strength{0 };
40
41
const float thermal_radius{80 };
41
- const float thermal_position_x{0 };
42
+ const float thermal_position_x{5 };
42
43
const float thermal_position_y{0 };
43
44
k.x (trigger_strength, thermal_radius, thermal_position_x, thermal_position_y);
44
45
45
46
const float strength_covariance{0.0049 };
46
47
const float radius_covariance{400 };
47
- const float position_covariance{400 }; // For both positions x and y.
48
+ const float position_covariance{400 };
48
49
k.p (kalman::estimate_uncertainty{{strength_covariance, 0 , 0 , 0 },
49
50
{0 , radius_covariance, 0 , 0 },
50
51
{0 , 0 , position_covariance, 0 },
@@ -54,7 +55,8 @@ namespace {
54
55
55
56
k.transition ([](const kalman::state &x, const float &drift_x,
56
57
const float &drift_y) -> kalman::state {
57
- const kalman::state drifts{0 , 0 , -drift_x, -drift_y};
58
+ // ! @todo Could make sure that x[1] stays positive, greater than 40.
59
+ const kalman::state drifts{0 , 0 , drift_x, drift_y};
58
60
return x + drifts;
59
61
});
60
62
@@ -72,42 +74,154 @@ namespace {
72
74
// position w.r.t. the thermal center [m.s^-1].
73
75
k.observation ([](const kalman::state &x, const float &position_x,
74
76
const float &position_y) -> kalman::output {
75
- const auto exp {std::exp (
76
- -(std::pow (x (2 ) - position_x, 2 .f ) + std::pow (x (3 ) - position_y, 2 .f )) /
77
- std::pow (x (1 ), 2 .f ))};
78
- return kalman::output{x (0 ) * exp };
77
+ return x (0 ) * std::exp (-(std::pow (x[2 ] - position_x, 2 .f ) +
78
+ std::pow (x[3 ] - position_y, 2 .f )) /
79
+ std::pow (x[1 ], 2 .f ));
79
80
});
80
81
81
82
// See the ArduSoar paper for the equation for H = ∂h/∂X:
82
83
k.h ([](const kalman::state &x, const float &position_x,
83
84
const float &position_y) -> kalman::output_model {
84
- const auto exp {std::exp (
85
- -(std::pow (x (2 ) - position_x, 2 .f ) + std::pow (x (3 ) - position_y, 2 .f )) /
86
- std::pow (x (1 ), 2 .f ))};
85
+ const float expon{std::exp (
86
+ -(std::pow (x[2 ] - position_x, 2 .f ) + std::pow (x[3 ] - position_y, 2 .f )) /
87
+ std::pow (x[1 ], 2 .f ))};
88
+
87
89
const kalman::output_model h{
88
- exp ,
90
+ expon ,
89
91
2 * x (0 ) *
90
92
((std::pow (x (2 ) - position_x, 2 .f ) +
91
93
std::pow (x (3 ) - position_y, 2 .f )) /
92
94
std::pow (x (1 ), 3 .f )) *
93
- exp ,
94
- -2 * (x (0 ) * (x (2 ) - position_x) / std::pow (x (1 ), 2 .f )) * exp ,
95
- -2 * (x (0 ) * (x (3 ) - position_y) / std::pow (x (1 ), 2 .f )) * exp };
95
+ expon,
96
+ -2 * (x (0 ) * (x (2 ) - position_x) / std::pow (x (1 ), 2 .f )) * expon,
97
+ -2 * (x (0 ) * (x (3 ) - position_y) / std::pow (x (1 ), 2 .f )) * expon};
98
+
96
99
return h;
97
100
});
98
101
99
- float variometer{0 };
100
- float position_x{0 };
101
- float position_y{0 };
102
- k.update (variometer, position_x, position_y);
103
-
104
- float drift_x{0 };
105
- float drift_y{0 };
106
- k.predict (drift_x, drift_y);
107
-
108
- // Or so on.
109
- k.template operator ()<float >(position_x, position_y, variometer, drift_x,
110
- drift_y);
102
+ struct data {
103
+ float drift_x;
104
+ float drift_y;
105
+ float position_x;
106
+ float position_y;
107
+ float variometer;
108
+ };
109
+
110
+ // A hundred randomly generated data point.
111
+ constexpr data measured[]{
112
+ {0.0756891 , 0.749786 , 0.878827 , 0.806808 , 0.155487 },
113
+ {0.506366 , 0.261469 , 0.886986 , 0.332883 , 0.434406 },
114
+ {0.249769 , 0.242154 , 0.616454 , 0.672545 , 0.24927 },
115
+ {0.358587 , 0.556206 , 0.909985 , 0.370336 , 0.553264 },
116
+ {0.370579 , 0.368003 , 0.491917 , 0.635429 , 0.73594 },
117
+ {0.82946 , 0.0221123 , 0.461047 , 0.940697 , 0.987409 },
118
+ {0.462132 , 0.708865 , 0.941915 , 0.122432 , 0.911597 },
119
+ {0.888334 , 0.542419 , 0.773781 , 0.116075 , 0.917592 },
120
+ {0.229376 , 0.174244 , 0.972009 , 0.509611 , 0.37637 },
121
+ {0.887738 , 0.707866 , 0.90959 , 0.430274 , 0.242523 },
122
+ {0.40713 , 0.0696747 , 0.456659 , 0.979656 , 0.11167 },
123
+ {0.77115 , 0.183994 , 0.944587 , 0.467626 , 0.0219546 },
124
+ {0.137442 , 0.316077 , 0.660742 , 0.828009 , 0.852228 },
125
+ {0.128113 , 0.0757587 , 0.742959 , 0.360531 , 0.3932 },
126
+ {0.161107 , 0.709262 , 0.690847 , 0.161165 , 0.237205 },
127
+ {0.664184 , 0.658516 , 0.972067 , 0.465567 , 0.807259 },
128
+ {0.669789 , 0.236436 , 0.341701 , 0.430546 , 0.229097 },
129
+ {0.159471 , 0.122824 , 0.975034 , 0.833685 , 0.78011 },
130
+ {0.284848 , 0.917524 , 0.358084 , 0.82927 , 0.0983398 },
131
+ {0.209027 , 0.573124 , 0.428336 , 0.106116 , 0.17974 },
132
+ {0.861987 , 0.110099 , 0.0994602 , 0.208052 , 0.0545667 },
133
+ {0.483002 , 0.707016 , 0.189368 , 0.0626376 , 0.992816 },
134
+ {0.588928 , 0.644143 , 0.763512 , 0.444366 , 0.251652 },
135
+ {0.419946 , 0.338175 , 0.286543 , 0.97232 , 0.908061 },
136
+ {0.0625373 , 0.855109 , 0.763831 , 0.622934 , 0.364608 },
137
+ {0.55833 , 0.505803 , 0.600797 , 0.342724 , 0.735087 },
138
+ {0.664873 , 0.224638 , 0.385409 , 0.892807 , 0.695 },
139
+ {0.255295 , 0.0264766 , 0.229274 , 0.723291 , 0.552242 },
140
+ {0.412129 , 0.856404 , 0.395075 , 0.261842 , 0.947885 },
141
+ {0.468212 , 0.849367 , 0.00615251 , 0.842904 , 0.700869 },
142
+ {0.311582 , 0.293401 , 0.299637 , 0.567025 , 0.659598 },
143
+ {0.695464 , 0.941376 , 0.21219 , 0.27813 , 0.289406 },
144
+ {0.000397467 , 0.301337 , 0.71608 , 0.296278 , 0.718923 },
145
+ {0.36314 , 0.263077 , 0.193163 , 0.295399 , 0.0523569 },
146
+ {0.128381 , 0.572157 , 0.971297 , 0.516492 , 0.921166 },
147
+ {0.596215 , 0.909239 , 0.133898 , 0.506903 , 0.0335569 },
148
+ {0.444556 , 0.997721 , 0.348369 , 0.644847 , 0.80885 },
149
+ {0.891465 , 0.0797467 , 0.85753 , 0.369457 , 0.418543 },
150
+ {0.861948 , 0.520583 , 0.900797 , 0.153884 , 0.080031 },
151
+ {0.169696 , 0.981169 , 0.406729 , 0.292696 , 0.831505 },
152
+ {0.172591 , 0.349291 , 0.782213 , 0.534652 , 0.214628 },
153
+ {0.875081 , 0.746097 , 0.0806311 , 0.15685 , 0.357471 },
154
+ {0.519389 , 0.007303 , 0.18117 , 0.370993 , 0.427305 },
155
+ {0.961372 , 0.218945 , 0.486608 , 0.618755 , 0.168813 },
156
+ {0.537862 , 0.451312 , 0.384422 , 0.540216 , 0.525636 },
157
+ {0.494387 , 0.162124 , 0.0136825 , 0.127037 , 0.803511 },
158
+ {0.409087 , 0.991167 , 0.276877 , 0.188698 , 0.155701 },
159
+ {0.851474 , 0.54778 , 0.133586 , 0.37391 , 0.137362 },
160
+ {0.0148137 , 0.97396 , 0.945259 , 0.297432 , 0.260494 },
161
+ {0.906864 , 0.13484 , 0.214258 , 0.924681 , 0.618572 },
162
+ {0.141742 , 0.563986 , 0.502602 , 0.416297 , 0.97038 },
163
+ {0.698555 , 0.406929 , 0.558199 , 0.875364 , 0.736008 },
164
+ {0.175105 , 0.270328 , 0.332957 , 0.145101 , 0.765857 },
165
+ {0.68083 , 0.125673 , 0.922594 , 0.831683 , 0.457214 },
166
+ {0.520728 , 0.26214 , 0.458674 , 0.306454 , 0.783164 },
167
+ {0.780442 , 0.472245 , 0.125185 , 0.460146 , 0.0847598 },
168
+ {0.360083 , 0.0686402 , 0.328997 , 0.799852 , 0.818809 },
169
+ {0.71546 , 0.717884 , 0.253842 , 0.812915 , 0.0141433 },
170
+ {0.441185 , 0.171204 , 0.0432966 , 0.739241 , 0.448679 },
171
+ {0.399117 , 0.148854 , 0.743042 , 0.0230124 , 0.378786 },
172
+ {0.841239 , 0.292533 , 0.391296 , 0.734326 , 0.0597166 },
173
+ {0.350847 , 0.519149 , 0.808508 , 0.113644 , 0.673261 },
174
+ {0.229909 , 0.814871 , 0.118688 , 0.612729 , 0.354682 },
175
+ {0.734755 , 0.675693 , 0.646155 , 0.0296504 , 0.405621 },
176
+ {0.121731 , 0.231111 , 0.47879 , 0.733299 , 0.270893 },
177
+ {0.732981 , 0.813999 , 0.597652 , 0.455436 , 0.691262 },
178
+ {0.10297 , 0.534613 , 0.553605 , 0.777385 , 0.553588 },
179
+ {0.441429 , 0.974205 , 0.120671 , 0.279931 , 0.624484 },
180
+ {0.531836 , 0.697762 , 0.274009 , 0.827927 , 0.741129 },
181
+ {0.745307 , 0.085542 , 0.473629 , 0.286912 , 0.175756 },
182
+ {0.758466 , 0.268705 , 0.108006 , 0.291002 , 0.559732 },
183
+ {0.632262 , 0.733193 , 0.919653 , 0.165692 , 0.84716 },
184
+ {0.0107621 , 0.694084 , 0.35781 , 0.793076 , 0.0818898 },
185
+ {0.17388 , 0.333606 , 0.867638 , 0.969285 , 0.887633 },
186
+ {0.255376 , 0.180532 , 0.737631 , 0.869954 , 0.875926 },
187
+ {0.525821 , 0.882517 , 0.224126 , 0.906093 , 0.557676 },
188
+ {0.516693 , 0.986614 , 0.644313 , 0.00903489 , 0.207868 },
189
+ {0.00175451 , 0.49772 , 0.436713 , 0.0418148 , 0.63547 },
190
+ {0.559954 , 0.192099 , 0.0787102 , 0.976933 , 0.552542 },
191
+ {0.983202 , 0.165426 , 0.136735 , 0.467933 , 0.626612 },
192
+ {0.520497 , 0.593702 , 0.0155549 , 0.791301 , 0.635127 },
193
+ {0.934924 , 0.0663795 , 0.513404 , 0.791586 , 0.68594 },
194
+ {0.977299 , 0.682359 , 0.0689664 , 0.769369 , 0.169862 },
195
+ {0.681586 , 0.900795 , 0.312534 , 0.854568 , 0.113097 },
196
+ {0.0783791 , 0.340692 , 0.23686 , 0.5932 , 0.38193 },
197
+ {0.430041 , 0.401364 , 0.88266 , 0.226286 , 0.514185 },
198
+ {0.422123 , 0.713778 , 0.813105 , 0.960577 , 0.794308 },
199
+ {0.0531423 , 0.930818 , 0.913336 , 0.382305 , 0.372521 },
200
+ {0.91698 , 0.128078 , 0.901849 , 0.0860355 , 0.432365 },
201
+ {0.749259 , 0.198112 , 0.538301 , 0.739992 , 0.909026 },
202
+ {0.903781 , 0.206122 , 0.743227 , 0.700662 , 0.784729 },
203
+ {0.914658 , 0.625943 , 0.697374 , 0.333459 , 0.213769 },
204
+ {0.313091 , 0.0485961 , 0.625018 , 0.916347 , 0.363119 },
205
+ {0.455916 , 0.982769 , 0.245987 , 0.555492 , 0.938798 },
206
+ {0.0737146 , 0.324519 , 0.325405 , 0.677491 , 0.148078 },
207
+ {0.918677 , 0.537612 , 0.917458 , 0.611973 , 0.965844 },
208
+ {0.832977 , 0.466222 , 0.528761 , 0.348765 , 0.472975 },
209
+ {0.784042 , 0.866144 , 0.00524178 , 0.217837 , 0.145246 },
210
+ {0.308576 , 0.993283 , 0.0244056 , 0.543786 , 0.575841 },
211
+ {0.285113 , 0.12198 , 0.74075 , 0.834888 , 0.561457 },
212
+ {0.635992 , 0.590228 , 0.629378 , 0.112457 , 0.78253 }};
213
+
214
+ for (const auto &output : measured) {
215
+ k.predict (output.drift_x , output.drift_y );
216
+ k.update (output.position_x , output.position_y , output.variometer );
217
+ }
218
+
219
+ assert (std::abs (1 - k.x ()[0 ] / 0 .347191f ) < 0 .0001f &&
220
+ std::abs (1 - k.x ()[1 ] / 91 .8926f ) < 0 .0001f &&
221
+ std::abs (1 - k.x ()[2 ] / 22 .9656f ) < 0 .0001f &&
222
+ std::abs (1 - k.x ()[3 ] / 20 .6146f ) < 0 .0001f &&
223
+ " The estimated states expected to meet ArduPilot soaring plane "
224
+ " implementation at 0.01% accuracy." );
111
225
112
226
return 0 ;
113
227
}()};
0 commit comments