This example demonstrates how to set up an Extended Kalman Filter. We simulate a system, add noise to the observations and then compute state estimates using the EKF class.
int main(
int argc,
char** argv)
{
std::string settingsFile = ct::optcon::exampleDir + "/kalmanFilterWeights.info";
const size_t output_dim = 2;
x(0) = 1.0;
x(1) = 0.0;
double w_n = 50;
double kp = 10;
double kd = 1;
uff << 2.0;
std::shared_ptr<CustomController> controller(
new CustomController(uff, kp, kd));
oscillator->setController(controller);
double dt = 0.001;
size_t nSteps = 100;
states.push_back(x);
for (size_t i = 0; i < nSteps; i++)
{
controller->computeControl(x, i * dt, u_temp);
controls.push_back(u_temp);
integrator.integrate_n_steps(x, i * dt, 1, dt);
position_process_noise.noisify(x(0));
velocity_process_noise.noisify(x(1));
states.push_back(x);
times.push_back(i * dt);
}
C.setIdentity();
dFdv.setIdentity();
std::cout << "Loaded Kalman R as " << std::endl << R << std::endl;
std::cout << "Loaded Kalman Q as " << std::endl << Q << std::endl;
std::shared_ptr<ct::core::SystemLinearizer<state_dim, control_dim>>
linearizer(
std::shared_ptr<ct::core::SensitivityApproximation<state_dim, control_dim>> sensApprox(
std::shared_ptr<ct::optcon::CTSystemModel<state_dim, control_dim>> sysModel(
dHdw.setIdentity();
std::shared_ptr<ct::optcon::LinearMeasurementModel<output_dim, state_dim>> measModel(
sysModel, measModel, Q, R, states[0], Q);
states_est[0] = states[0];
states_meas[0] = states[0];
for (size_t i = 1; i < states.size(); ++i)
{
states_meas[i] = states[i];
position_measurement_noise.noisify(states_meas[i](0));
velocity_measurement_noise.noisify(states_meas[i](1));
filter.predict(controls[i], dt, dt * i);
states_est[i] = x_est;
}
#ifdef PLOTTING_ENABLED
std::vector<double> time_plot, pos_est_plot, vel_est_plot, pos_plot, vel_plot, pos_meas_plot, vel_meas_plot;
for (size_t i = 0; i < times.size(); i++)
{
time_plot.push_back(times[i]);
pos_est_plot.push_back(states_est[i](0));
vel_est_plot.push_back(states_est[i](1));
pos_plot.push_back(states[i](0));
vel_plot.push_back(states[i](1));
pos_meas_plot.push_back(states_meas[i](0));
vel_meas_plot.push_back(states_meas[i](1));
}
#else // print results to command line
for (size_t i = 0; i < states_est.size(); ++i)
std::cout << "State\t\tState_est\n"
<< std::fixed << std::setprecision(6) << states[i][0] << "\t" << states_est[i][0] << std::endl
<< states[i][1] << "\t" << states_est[i][1] << std::endl
<< std::endl;
#endif
return 0;
}