#include <mrs_lib/lkf.h>
#include <random>
#include <ros/ros.h>
{
const int n_states = 4;
const int n_inputs = 2;
const int n_measurements = 2;
using lkf_t = LKF<n_states, n_inputs, n_measurements>;
}
enum x_pos
{
x_x = 0,
x_y = 1,
x_dx = 2,
x_dy = 3,
};
enum u_pos
{
u_dx = 0,
u_dy = 0,
};
enum z_pos
{
z_x = 0,
z_y = 1,
};
A_t A;
B_t B;
H_t H;
const double speed = 0.3;
x_t tra_model_f(const x_t& x, const u_t& u, [[maybe_unused]] const double dt)
{
return A*x + B*u;
}
z_t obs_model_f(const x_t& x)
{
return H*x;
}
template <int rows>
Eigen::Matrix<double, rows, 1> normal_randmat(const Eigen::Matrix<double, rows, rows>& cov)
{
static std::random_device rd{};
static std::mt19937 gen{rd()};
static std::normal_distribution<> d{0,1};
Eigen::Matrix<double, rows, 1> ret;
for (int row = 0; row < rows; row++)
ret(row, 0) = d(gen);
return cov*ret;
}
int main()
{
const double dt = 1.0;
A <<
1, 0, dt, 0,
0, 1, 0, dt,
0, 0, 1, 0,
0, 0, 0, 1;
B <<
0, 0,
0, 0,
1, 0,
0, 1;
H <<
1, 0, 0, 0,
0, 1, 0, 0;
Q_t Q; Q <<
1e-3, 0, 0, 0,
0, 1e-3, 0, 0,
0, 0, 1e-2, 0,
0, 0, 0, 1e-2;
R_t R; R <<
1e-2, 0,
0, 1e-2;
const x_t x0 = 100.0*x_t::Random();
P_t P_tmp = P_t::Random();
const P_t P0 = 10.0*P_tmp*P_tmp.transpose();
const statecov_t sc0({x0, P0});
const int n_its = 1e4;
x_t x_gt = sc0.x;
statecov_t sc_est = sc0;
for (int it = 0; it < n_its; it++)
{
std::cout << "step: " << it << std::endl;
const u_t u = u_t::Random();
x_gt = tra_model_f(x_gt, u, dt) + normal_randmat(Q);
const z_t z = obs_model_f(x_gt) + normal_randmat(R);
try
{
sc_est = lkf.predict(sc_est, u, Q, dt);
sc_est = lkf.correct(sc_est, z, R);
}
catch (const std::exception& e)
{
ROS_ERROR("LKF failed: %s", e.what());
}
const auto error = (x_gt-sc_est.x).norm();
std::cout << "Current LKF estimation error is: " << error << std::endl;
std::cout << "Current ground-truth state is: " << x_gt.transpose() << std::endl;
std::cout << "Current LKF estimated state is: " << sc_est.x.transpose() << std::endl;
std::cout << "Current LKF state covariance is:" << std::endl << sc_est.P << std::endl;
}
return 0;
}