Skip to content

Commit 6042120

Browse files
[sample] add a data set and verification for the plane soaring example
1 parent fb656d7 commit 6042120

File tree

2 files changed

+150
-28
lines changed

2 files changed

+150
-28
lines changed

.github/workflows/cppcheck.yml

+9-1
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,12 @@ jobs:
3838
cmake --build . ;
3939
sudo make install ; ) ) )
4040
- name: Verify
41-
run: cppcheck --verbose --error-exitcode=1 --enable=all -I include .
41+
# unusedStructMember https://trac.cppcheck.net/ticket/10699
42+
run: |
43+
cppcheck \
44+
--enable=all \
45+
--error-exitcode=1 \
46+
--suppress=unusedStructMember:sample/ekf_4x1x0_ardupilot_soaring.cpp
47+
--verbose \
48+
-I include \
49+
.

sample/ekf_4x1x0_ardupilot_soaring.cpp

+141-27
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
namespace fcarouge::eigen::sample {
77
namespace {
8+
89
//! @brief ArduPilot Plane Soaring
910
//!
1011
//! @copyright This example is transcribed from the ArduPilot Soaring Plane
@@ -36,15 +37,15 @@ namespace {
3637
kalman k;
3738

3839
// Initialization
39-
const float trigger_strength{1 / 4.06};
40+
const float trigger_strength{0};
4041
const float thermal_radius{80};
41-
const float thermal_position_x{0};
42+
const float thermal_position_x{5};
4243
const float thermal_position_y{0};
4344
k.x(trigger_strength, thermal_radius, thermal_position_x, thermal_position_y);
4445

4546
const float strength_covariance{0.0049};
4647
const float radius_covariance{400};
47-
const float position_covariance{400}; // For both positions x and y.
48+
const float position_covariance{400};
4849
k.p(kalman::estimate_uncertainty{{strength_covariance, 0, 0, 0},
4950
{0, radius_covariance, 0, 0},
5051
{0, 0, position_covariance, 0},
@@ -54,7 +55,8 @@ namespace {
5455

5556
k.transition([](const kalman::state &x, const float &drift_x,
5657
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};
5860
return x + drifts;
5961
});
6062

@@ -72,42 +74,154 @@ namespace {
7274
// position w.r.t. the thermal center [m.s^-1].
7375
k.observation([](const kalman::state &x, const float &position_x,
7476
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));
7980
});
8081

8182
// See the ArduSoar paper for the equation for H = ∂h/∂X:
8283
k.h([](const kalman::state &x, const float &position_x,
8384
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+
8789
const kalman::output_model h{
88-
exp,
90+
expon,
8991
2 * x(0) *
9092
((std::pow(x(2) - position_x, 2.f) +
9193
std::pow(x(3) - position_y, 2.f)) /
9294
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+
9699
return h;
97100
});
98101

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.");
111225

112226
return 0;
113227
}()};

0 commit comments

Comments
 (0)