Estimating the vehicle location.
Estimating the vehicle location.
In this example, we would like to estimate the location of the vehicle in the XY plane. The vehicle has an onboard location sensor that reports X and Y coordinates of the system. We assume constant acceleration dynamics. In this example we don't have a control variable u since we don't have control input. Let us assume a vehicle moving in a straight line in the X direction with a constant velocity. After traveling 400 meters the vehicle turns right, with a turning radius of 300 meters. During the turning maneuver, the vehicle experiences acceleration due to the circular motion (an angular acceleration). The measurements period: Δt = 1s (constant).
#include "fcarouge/linalg.hpp"
#include <cassert>
#include <cmath>
namespace {
using state = fcarouge::state<vector<6>>;
[[maybe_unused]] auto sample{[] {
state{0., 0., 0., 0., 0., 0.},
output<vector<2>>,
estimate_uncertainty{{500., 0., 0., 0., 0., 0.},
{0., 500., 0., 0., 0., 0.},
{0., 0., 500., 0., 0., 0.},
{0., 0., 0., 500., 0., 0.},
{0., 0., 0., 0., 500., 0.},
{0., 0., 0., 0., 0., 500.}},
process_uncertainty{0.2 * 0.2 *
{0.5, 1., 1., 0., 0., 0.},
{0.5, 1., 1., 0., 0., 0.},
{0., 0., 0., 0.25, 0.5, 0.5},
{0., 0., 0., 0.5, 1., 1.},
{0., 0., 0., 0.5, 1., 1.}}},
output_uncertainty{{9., 0.}, {0., 9.}},
output_model{{1., 0., 0., 0., 0., 0.}, {0., 0., 0., 1., 0., 0.}},
state_transition{{1., 1., 0.5, 0., 0., 0.},
{0., 1., 1., 0., 0., 0.},
{0., 0., 1., 0., 0., 0.},
{0., 0., 0., 1., 1., 0.5},
{0., 0., 0., 0., 1., 1.},
{0., 0., 0., 0., 0., 1.}}};
filter.predict();
filter.update(-393.66, 300.4);
filter.predict();
const auto step{[&filter](double position_x, double position_y) {
filter.update(position_x, position_y);
filter.predict();
}};
step(-375.93, 301.78);
assert(std::abs(1 - filter.x()[0] / -277.8) < 0.001 &&
std::abs(1 - filter.x()[1] / 148.3) < 0.001 &&
std::abs(1 - filter.x()[2] / 94.5) < 0.001 &&
std::abs(1 - filter.x()[3] / 249.8) < 0.001 &&
std::abs(1 - filter.x()[4] / -85.9) < 0.001 &&
std::abs(1 - filter.x()[5] / -63.6) < 0.001 &&
"The state estimates expected at 0.1% accuracy.");
step(-351.04, 295.1);
step(-328.96, 305.19);
step(-299.35, 301.06);
step(-273.36, 302.05);
step(-245.89, 300);
step(-222.58, 303.57);
step(-198.03, 296.33);
step(-174.17, 297.65);
step(-146.32, 297.41);
step(-123.72, 299.61);
step(-103.47, 299.6);
step(-78.23, 302.39);
step(-52.63, 295.04);
step(-23.34, 300.09);
step(25.96, 294.72);
step(49.72, 298.61);
step(76.94, 294.64);
step(95.38, 284.88);
step(119.83, 272.82);
step(144.01, 264.93);
step(161.84, 251.46);
step(180.56, 241.27);
step(201.42, 222.98);
step(222.62, 203.73);
step(239.4, 184.1);
step(252.51, 166.12);
step(266.26, 138.71);
step(271.75, 119.71);
step(277.4, 100.41);
step(294.12, 79.76);
step(301.23, 50.62);
step(291.8, 32.99);
step(299.89, 2.14);
assert(std::abs(1 - filter.x()[0] / 298.5) < 0.006 &&
std::abs(1 - filter.x()[1] / -1.65) < 0.006 &&
std::abs(1 - filter.x()[2] / -1.9) < 0.006 &&
std::abs(1 - filter.x()[3] / -22.5) < 0.006 &&
std::abs(1 - filter.x()[4] / -26.1) < 0.006 &&
std::abs(1 - filter.x()[5] / -0.64) < 0.006 &&
"The state estimates expected at 0.6% accuracy.");
assert(std::abs(1 - filter.p()(0, 0) / 11.25) < 0.001 &&
std::abs(1 - filter.p()(0, 1) / 4.5) < 0.001 &&
std::abs(1 - filter.p()(0, 2) / 0.9) < 0.001 &&
std::abs(1 - filter.p()(1, 1) / 2.4) < 0.001 &&
std::abs(1 - filter.p()(2, 2) / 0.2) < 0.001 &&
std::abs(1 - filter.p()(3, 3) / 11.25) < 0.001 &&
"The estimate uncertainty expected at 0.1% accuracy."
"At this point, the position uncertainty px = py = 5, which means "
"that the standard deviation of the prediction is square root of 5m.");
return 0;
}()};
}
}
The Kalman filter class and library top-level header.
Eigen::Matrix< Type, Row, Column > matrix
Compile-time sized Eigen3 matrix.
Eigen::Vector< Type, Row > column_vector
Compile-time sized Eigen3 column vector.
Examples, tutorials, demonstrators of the library.
indexed::column_vector< column_vector< Representation, sizeof...(References)>, quantity< Representation, References >... > vector
Quantity column vector with mp-units and Eigen implementations.
kalman(Arguments... arguments) -> kalman< internal::deduce_filter< Arguments... > >
Deduces the filter type from its declared configuration.