Skip to content

Instantly share code, notes, and snippets.

@AakashKumarNain
Last active April 27, 2017 19:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AakashKumarNain/0594602cc70de0df5248d40ed2517fe3 to your computer and use it in GitHub Desktop.
Save AakashKumarNain/0594602cc70de0df5248d40ed2517fe3 to your computer and use it in GitHub Desktop.
Unscented Kalman Filter
#ifndef GROUND_TRUTH_PACKAGE_H_
#define GROUND_TRUTH_PACKAGE_H_
#include "Eigen/Dense"
class GroundTruthPackage {
public:
long long timestamp_;
enum SensorType{
LASER,
RADAR
} sensor_type_;
Eigen::VectorXd gt_values_;
};
#endif /* GROUND_TRUTH_PACKAGE_H_ */
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include "Eigen/Dense"
#include "ukf.h"
#include "ground_truth_package.h"
#include "measurement_package.h"
using namespace std;
using Eigen::MatrixXd;
using Eigen::VectorXd;
using std::vector;
void check_arguments(int argc, char* argv[]) {
string usage_instructions = "Usage instructions: ";
usage_instructions += argv[0];
usage_instructions += " path/to/input.txt output.txt";
bool has_valid_args = false;
// make sure the user has provided input and output files
if (argc == 1) {
cerr << usage_instructions << endl;
} else if (argc == 2) {
cerr << "Please include an output file.\n" << usage_instructions << endl;
} else if (argc == 3) {
has_valid_args = true;
} else if (argc > 3) {
cerr << "Too many arguments.\n" << usage_instructions << endl;
}
if (!has_valid_args) {
exit(EXIT_FAILURE);
}
}
void check_files(ifstream& in_file, string& in_name,
ofstream& out_file, string& out_name) {
if (!in_file.is_open()) {
cerr << "Cannot open input file: " << in_name << endl;
exit(EXIT_FAILURE);
}
if (!out_file.is_open()) {
cerr << "Cannot open output file: " << out_name << endl;
exit(EXIT_FAILURE);
}
}
int main(int argc, char* argv[]) {
check_arguments(argc, argv);
string in_file_name_ = argv[1];
ifstream in_file_(in_file_name_.c_str(), ifstream::in);
string out_file_name_ = argv[2];
ofstream out_file_(out_file_name_.c_str(), ofstream::out);
check_files(in_file_, in_file_name_, out_file_, out_file_name_);
/**********************************************
* Set Measurements *
**********************************************/
vector<MeasurementPackage> measurement_pack_list;
vector<GroundTruthPackage> gt_pack_list;
string line;
// prep the measurement packages (each line represents a measurement at a
// timestamp)
while (getline(in_file_, line)) {
string sensor_type;
MeasurementPackage meas_package;
GroundTruthPackage gt_package;
istringstream iss(line);
long long timestamp;
// reads first element from the current line
iss >> sensor_type;
if (sensor_type.compare("L") == 0) {
// laser measurement
// read measurements at this timestamp
meas_package.sensor_type_ = MeasurementPackage::LASER;
meas_package.raw_measurements_ = VectorXd(2);
float px;
float py;
iss >> px;
iss >> py;
meas_package.raw_measurements_ << px, py;
iss >> timestamp;
meas_package.timestamp_ = timestamp;
measurement_pack_list.push_back(meas_package);
} else if (sensor_type.compare("R") == 0) {
// radar measurement
// read measurements at this timestamp
meas_package.sensor_type_ = MeasurementPackage::RADAR;
meas_package.raw_measurements_ = VectorXd(3);
float ro;
float phi;
float ro_dot;
iss >> ro;
iss >> phi;
iss >> ro_dot;
meas_package.raw_measurements_ << ro, phi, ro_dot;
iss >> timestamp;
meas_package.timestamp_ = timestamp;
measurement_pack_list.push_back(meas_package);
}
// read ground truth data to compare later
float x_gt;
float y_gt;
float vx_gt;
float vy_gt;
iss >> x_gt;
iss >> y_gt;
iss >> vx_gt;
iss >> vy_gt;
gt_package.gt_values_ = VectorXd(4);
gt_package.gt_values_ << x_gt, y_gt, vx_gt, vy_gt;
gt_pack_list.push_back(gt_package);
}
// Create a UKF instance
UKF ukf;
// used to compute the RMSE later
vector<VectorXd> estimations;
vector<VectorXd> ground_truth;
// start filtering from the second frame (the speed is unknown in the first
// frame)
size_t number_of_measurements = measurement_pack_list.size();
// column names for output file
out_file_ << "time_stamp" << "\t";
out_file_ << "px_state" << "\t";
out_file_ << "py_state" << "\t";
out_file_ << "v_state" << "\t";
out_file_ << "yaw_angle_state" << "\t";
out_file_ << "yaw_rate_state" << "\t";
out_file_ << "sensor_type" << "\t";
out_file_ << "NIS" << "\t";
out_file_ << "px_measured" << "\t";
out_file_ << "py_measured" << "\t";
out_file_ << "px_ground_truth" << "\t";
out_file_ << "py_ground_truth" << "\t";
out_file_ << "vx_ground_truth" << "\t";
out_file_ << "vy_ground_truth" << "\n";
for (size_t k = 0; k < number_of_measurements; ++k) {
// Call the UKF-based fusion
ukf.ProcessMeasurement(measurement_pack_list[k]);
// timestamp
out_file_ << measurement_pack_list[k].timestamp_ << "\t"; // pos1 - est
// output the state vector
out_file_ << ukf.x_(0) << "\t"; // pos1 - est
out_file_ << ukf.x_(1) << "\t"; // pos2 - est
out_file_ << ukf.x_(2) << "\t"; // vel_abs -est
out_file_ << ukf.x_(3) << "\t"; // yaw_angle -est
out_file_ << ukf.x_(4) << "\t"; // yaw_rate -est
// output lidar and radar specific data
if (measurement_pack_list[k].sensor_type_ == MeasurementPackage::LASER) {
// sensor type
out_file_ << "lidar" << "\t";
// NIS value
out_file_ << ukf.NIS_laser_ << "\t";
// output the lidar sensor measurement px and py
out_file_ << measurement_pack_list[k].raw_measurements_(0) << "\t";
out_file_ << measurement_pack_list[k].raw_measurements_(1) << "\t";
} else if (measurement_pack_list[k].sensor_type_ == MeasurementPackage::RADAR) {
// sensor type
out_file_ << "radar" << "\t";
// NIS value
out_file_ << ukf.NIS_radar_ << "\t";
// output radar measurement in cartesian coordinates
float ro = measurement_pack_list[k].raw_measurements_(0);
float phi = measurement_pack_list[k].raw_measurements_(1);
out_file_ << ro * cos(phi) << "\t"; // px measurement
out_file_ << ro * sin(phi) << "\t"; // py measurement
}
// output the ground truth
out_file_ << gt_pack_list[k].gt_values_(0) << "\t";
out_file_ << gt_pack_list[k].gt_values_(1) << "\t";
out_file_ << gt_pack_list[k].gt_values_(2) << "\t";
out_file_ << gt_pack_list[k].gt_values_(3) << "\n";
// convert ukf x vector to cartesian to compare to ground truth
VectorXd ukf_x_cartesian_ = VectorXd(4);
float x_estimate_ = ukf.x_(0);
float y_estimate_ = ukf.x_(1);
float vx_estimate_ = ukf.x_(2) * cos(ukf.x_(3));
float vy_estimate_ = ukf.x_(2) * sin(ukf.x_(3));
ukf_x_cartesian_ << x_estimate_, y_estimate_, vx_estimate_, vy_estimate_;
estimations.push_back(ukf_x_cartesian_);
ground_truth.push_back(gt_pack_list[k].gt_values_);
}
// compute the accuracy (RMSE)
Tools tools;
cout << "RMSE" << endl << tools.CalculateRMSE(estimations, ground_truth) << endl;
// close files
if (out_file_.is_open()) {
out_file_.close();
}
if (in_file_.is_open()) {
in_file_.close();
}
cout << "Done!" << endl;
return 0;
}
#ifndef MEASUREMENT_PACKAGE_H_
#define MEASUREMENT_PACKAGE_H_
#include "Eigen/Dense"
class MeasurementPackage {
public:
long long timestamp_;
enum SensorType{
LASER,
RADAR
} sensor_type_;
Eigen::VectorXd raw_measurements_;
};
#endif /* MEASUREMENT_PACKAGE_H_ */
#include <iostream>
#include "tools.h"
using Eigen::VectorXd;
using Eigen::MatrixXd;
using std::vector;
Tools::Tools() {}
Tools::~Tools() {}
VectorXd Tools::CalculateRMSE(const vector<VectorXd> &estimations,
const vector<VectorXd> &ground_truth) {
/**
TODO:
* Calculate the RMSE here.
*/
VectorXd rmse(4);
rmse << 0,0,0,0;
//Check the validity
//Estimation size must be greater than zero and equal to the ground_truth vector size
if(estimations.size() != ground_truth.size() || estimations.size()==0)
{
std::cout<<"Invalid estimation or ground truth data " << std::endl;
return rmse;
}
for(unsigned int i=0; i< estimations.size(); i++)
{
VectorXd residual = estimations[i] - ground_truth[i];
residual = residual.array() * residual.array();
rmse += residual;
}
//Calculate the mean
rmse = rmse/estimations.size();
//Take the square root
rmse = rmse.array().sqrt();
//Return the rmse
return rmse;
}
#include "ukf.h"
#include "tools.h"
#include "Eigen/Dense"
#include <iostream>
using namespace std;
using Eigen::MatrixXd;
using Eigen::VectorXd;
using std::vector;
/**
* Initializes Unscented Kalman filter
*/
UKF::UKF() {
// if this is false, laser measurements will be ignored (except during init)
use_laser_ = true;
// if this is false, radar measurements will be ignored (except during init)
use_radar_ = true;
// Define number of dimesnions
n_x_ = 5;
// Define the number of augmented states
n_aug_ = n_x_ + 2;
// Define design parameter -lambda
lambda_ = 3 - n_x_;
// initial state vector
x_ = VectorXd(5);
// initial covariance matrix
P_ = MatrixXd(5, 5);
P_ << 1,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0,
0,0,0,0,1;
// Process noise standard deviation longitudinal acceleration in m/s^2
std_a_ = 10;
// Process noise standard deviation yaw acceleration in rad/s^2
std_yawdd_ = 1;
// Laser measurement noise standard deviation position1 in m
std_laspx_ = 0.15;
// Laser measurement noise standard deviation position2 in m
std_laspy_ = 0.15;
// Radar measurement noise standard deviation radius in m
std_radr_ = 0.3;
// Radar measurement noise standard deviation angle in rad
std_radphi_ = 0.03;
// Radar measurement noise standard deviation radius change in m/s
std_radrd_ = 0.3;
Xsig_pred_ = MatrixXd(n_x_, 2*n_aug_+1);
/**
TODO:
Complete the initialization. See ukf.h for other member properties.
Hint: one or more values initialized above might be wildly off...
*/
}
UKF::~UKF() {}
/**
* @param {MeasurementPackage} meas_package The latest measurement data of
* either radar or laser.
*/
void UKF::ProcessMeasurement(MeasurementPackage meas_package) {
/**
TODO:
Complete this function! Make sure you switch between lidar and radar
measurements.
*/
if(!is_initialized_)
{
// Initialize the state with the first measurement depending upon the measurement sensor type
if(meas_package.sensor_type_ == MeasurementPackage::RADAR)
{
float rho = meas_package.raw_measurements_(0);
float psi = meas_package.raw_measurements_(1);
float rhodot = meas_package.raw_measurements_(2);
x_(0) = rho*cos(psi);
x_(1) = rho*sin(psi);
x_(2) = rhodot;
x_(3) = psi;
x_(4) = 0;
if(fabs(rho)>0.0001)
{
is_initialized_ = true;
}
}
else if(meas_package.sensor_type_ == MeasurementPackage::LASER)
{
x_(0) = meas_package.raw_measurements_(0);
x_(1) = meas_package.raw_measurements_(1);
x_(2) = 0;
x_(3) = 0;
x_(4) = 0;
if(sqrt(pow(x_(0),2) + pow(x_(1),2)) > 0.0001)
{
is_initialized_ = true;
}
}
time_us_ = meas_package.timestamp_;
return;
}
// Compute the time elapsed in seconds
double dt = (meas_package.timestamp_ - time_us_) / 1000000.0;
time_us_ = meas_package.timestamp_;
Prediction(dt);
if(meas_package.sensor_type_ == MeasurementPackage::RADAR)
{
if(fabs(meas_package.raw_measurements_(0)) > 0.001)
{
UpdateRadar(meas_package);
}
}
else if(meas_package.sensor_type_ == MeasurementPackage::LASER)
{
double lpx = meas_package.raw_measurements_(0);
double lpy = meas_package.raw_measurements_(1);
if(sqrt(pow(lpx,2)+ pow(lpy,2)) > 0.001)
{
UpdateLidar(meas_package);
}
}
}
/**
* Predicts sigma points, the state, and the state covariance matrix.
* @param {double} delta_t the change in time (in seconds) between the last
* measurement and this one.
*/
void UKF::Prediction(double delta_t) {
/**
TODO:
Complete this function! Estimate the object's location. Modify the state
vector, x_. Predict sigma points, the state, and the state covariance matrix.
*/
//Created augmented mean vector
VectorXd x_aug = VectorXd(n_aug_);
// Create augmented state covariance
MatrixXd P_aug = MatrixXd(n_aug_, n_aug_);
//create sigma point matrix
MatrixXd Xsig_aug = MatrixXd(n_aug_, 2 * n_aug_ + 1);
x_aug.head(n_x_) = x_;
x_aug(5) = 0;
x_aug(6) = 0;
P_aug.fill(0.0);
P_aug.topLeftCorner(5,5) = P_;
P_aug(5,5) = std_a_*std_a_;
P_aug(6,6) = std_yawdd_*std_yawdd_;
// Create square root matrix
MatrixXd L = P_aug.llt().matrixL();
// Create augmented sigma points
Xsig_aug.col(0) = x_aug;
for(int i=0; i< n_aug_; i++)
{
Xsig_aug.col(i) = x_aug + sqrt(lambda_ +n_aug_) * L.col(i);
Xsig_aug.col(i+1+n_aug_) = x_aug - sqrt(lambda_ + n_aug_) * L.col(i);
}
// Create matrix with predicted siigma points as columns
MatrixXd Xsig_pred = MatrixXd(n_x_, 2*n_aug_+1);
// Predict sigma points
for(int i=0; i< 2*n_aug_+1; i++)
{
double p_x = Xsig_aug(0,i);
double p_y = Xsig_aug(1,i);
double v = Xsig_aug(2,i);
double yaw = Xsig_aug(3,i);
double yawd = Xsig_aug(4,i);
double nu_a = Xsig_aug(5,i);
double nu_yawdd = Xsig_aug(6,i);
// Predicted stated values
double px_p, py_p;
if(fabs(yawd) > 0.001)
{
px_p = p_x + v/yawd * (sin(yaw + yaw*delta_t)-sin(yaw));
py_p = p_y + v/yawd * ( cos(yaw) - cos(yaw+yawd*delta_t));
}
else
{
px_p = p_x + v*delta_t*cos(yaw);
py_p = p_y + v*delta_t*sin(yaw);
}
double v_p = v;
double yaw_p = yaw + yaw*delta_t;
double yawd_p = yawd;
//add noise
px_p = px_p + 0.5 * nu_a*delta_t*delta_t*cos(yaw);
py_p = py_p + 0.5*nu_a*delta_t*delta_t*sin(yaw);
v_p = v_p + nu_a*delta_t;
yaw_p = yaw_p + 0.5*nu_yawdd*delta_t*delta_t;
yawd_p = yawd_p + nu_yawdd*delta_t;
//write predicted sigma point into right column
Xsig_pred(0,i) = px_p;
Xsig_pred(1,i) = py_p;
Xsig_pred(2,i) = v_p;
Xsig_pred(3,i) = yaw_p;
Xsig_pred(4,i) = yawd_p;
}
// Create a vector for weights
VectorXd weights = VectorXd(2*n_aug_+1);
double weights_0 = lambda_ / (lambda_ + n_aug_);
weights(0) = weights_0;
for(int i=0; i<2*n_aug_+1; i++)
{
weights(i) = 0.5/(lambda_ + n_aug_);
}
// predicted state mean
x_ = Xsig_pred * weights;
// predicted covariance matrix
for (int i = 0; i < 2 * n_aug_ + 1; i++)
{
// state difference
VectorXd x_diff = Xsig_pred.col(i) - x_;
//angle normalization
while (x_diff(3)> M_PI) x_diff(3)-=2.*M_PI;
while (x_diff(3)<-M_PI) x_diff(3)+=2.*M_PI;
P_ = weights(i) * x_diff * x_diff.transpose() ;
Xsig_pred_ = Xsig_pred;
}
}
/**
* Updates the state and the state covariance matrix using a laser measurement.
* @param {MeasurementPackage} meas_package
*/
void UKF::UpdateLidar(MeasurementPackage meas_package) {
/**
TODO:
Complete this function! Use lidar data to update the belief about the object's
position. Modify the state vector, x_, and covariance, P_.
You'll also need to calculate the lidar NIS.
*/
int n_z = 2;
//set vector for weights
VectorXd weights = VectorXd(2*n_aug_+1);
double weight_0 = lambda_/(lambda_+n_aug_);
weights(0) = weight_0;
for (int i=1; i<2*n_aug_+1; i++)
{
double weight = 0.5/(n_aug_+lambda_);
weights(i) = weight;
}
//create matrix for sigma points in measurement space
MatrixXd Zsig = MatrixXd(n_z, 2 * n_aug_ + 1);
for (int i = 0; i < 2 * n_aug_ + 1; i++)
{
// extract values for better readibility
double p_x = Xsig_pred_(0, i);
double p_y = Xsig_pred_(1, i);
Zsig(0,i) = p_x;
Zsig(1,i) = p_y;
}
VectorXd z_true = VectorXd(n_z);
z_true = meas_package.raw_measurements_;
//mean predicted measurement
VectorXd z_pred = VectorXd(n_z);
//create matrix for cross correlation Tc
MatrixXd Tc = MatrixXd(n_x_, n_z);
//measurement covariance matrix S
MatrixXd S = MatrixXd(n_z,n_z);
z_pred.fill(0.0);
for (int i=0; i < 2*n_aug_+1; i++)
{
z_pred = z_pred + weights(i) * Zsig.col(i);
}
S.fill(0.0);
Tc.fill(0.0);
for (int i = 0; i < 2 * n_aug_ + 1; i++)
{
//residual
VectorXd z_diff = Zsig.col(i) - z_pred;
// state difference
VectorXd x_diff = Xsig_pred_.col(i) - x_;
S = S + weights(i) * z_diff * z_diff.transpose();
Tc = Tc + weights(i) * x_diff * z_diff.transpose();
}
//add measurement noise covariance matrix
MatrixXd R = MatrixXd(n_z,n_z);
R << std_laspx_ * std_laspx_, 0,
0, std_laspy_ * std_laspy_;
S = S + R;
//Kalman gain K;
MatrixXd K = Tc * S.inverse();
//residual
VectorXd z_diff = z_true - z_pred;
//update state mean and covariance matrix
x_ = x_ + K * z_diff;
P_ = P_ - K*S*K.transpose();
//Calculate NIS
NIS_laser_ = (z_true - z_pred).transpose()* S * (z_true - z_pred);
}
/**
* Updates the state and the state covariance matrix using a radar measurement.
* @param {MeasurementPackage} meas_package
*/
void UKF::UpdateRadar(MeasurementPackage meas_package) {
/**
TODO:
Complete this function! Use radar data to update the belief about the object's
position. Modify the state vector, x_, and covariance, P_.
You'll also need to calculate the radar NIS.
*/
int n_z =3;
//set vector for weights
VectorXd weights = VectorXd(2*n_aug_+1);
double weight_0 = lambda_/(lambda_+n_aug_);
weights(0) = weight_0;
for (int i=1; i<2*n_aug_+1; i++)
{
double weight = 0.5/(n_aug_+lambda_);
weights(i) = weight;
}
//create matrix for sigma points in measurement space
MatrixXd Zsig = MatrixXd(n_z, 2 * n_aug_ + 1);
for (int i = 0; i < 2 * n_aug_ + 1; i++)
{
// extract values for better readibility
double p_x = Xsig_pred_(0,i);
double p_y = Xsig_pred_(1,i);
double v = Xsig_pred_(2,i);
double yaw = Xsig_pred_(3,i);
double v1 = cos(yaw)*v;
double v2 = sin(yaw)*v;
// measurement model
if((p_x*p_x + p_y*p_y) > 0.001)
{
Zsig(0,i) = sqrt(p_x*p_x + p_y*p_y); //r
Zsig(1,i) = atan2(p_y,p_x); //phi
}
else
{
Zsig(0,i) = sqrt(0.001); //r
Zsig(1,i) = atan2(0.001, 0.001); //phi
}
Zsig(2,i) = (p_x*v1 + p_y*v2 ) / sqrt(p_x*p_x + p_y*p_y); //r_dot
}
VectorXd z_true = VectorXd(n_z);
z_true = meas_package.raw_measurements_;
//mean predicted measurement
VectorXd z_pred = VectorXd(n_z);
//create matrix for cross correlation Tc
MatrixXd Tc = MatrixXd(n_x_, n_z);
//measurement covariance matrix S
MatrixXd S = MatrixXd(n_z,n_z);
z_pred.fill(0.0);
for (int i=0; i < 2*n_aug_+1; i++)
{
z_pred = z_pred + weights(i) * Zsig.col(i);
}
S.fill(0.0);
Tc.fill(0.0);
for (int i = 0; i < 2 * n_aug_ + 1; i++)
{
//residual
VectorXd z_diff = Zsig.col(i) - z_pred;
//angle normalization
while (z_diff(1)> M_PI) z_diff(1)-=2.*M_PI;
while (z_diff(1)<-M_PI) z_diff(1)+=2.*M_PI;
// state difference
VectorXd x_diff = Xsig_pred_.col(i) - x_;
//angle normalization
while (x_diff(3)> M_PI) x_diff(3)-=2.*M_PI;
while (x_diff(3)<-M_PI) x_diff(3)+=2.*M_PI;
S = S + weights(i) * z_diff * z_diff.transpose();
Tc = Tc + weights(i) * x_diff * z_diff.transpose();
}
//add measurement noise covariance matrix
MatrixXd R = MatrixXd(n_z,n_z);
R << std_radr_*std_radr_, 0, 0,
0, std_radphi_*std_radphi_, 0,
0, 0,std_radrd_*std_radrd_;
S = S + R;
//Kalman gain K;
MatrixXd K = Tc * S.inverse();
//residual
VectorXd z_diff = z_true - z_pred;
//angle normalization
while (z_diff(1)> M_PI) z_diff(1)-=2.*M_PI;
while (z_diff(1)<-M_PI) z_diff(1)+=2.*M_PI;
//update state mean and covariance matrix
x_ = x_ + K * z_diff;
P_ = P_ - K*S*K.transpose();
//Calculate NIS
NIS_radar_ = (z_true - z_pred).transpose()* S * (z_true - z_pred);
}
#ifndef UKF_H
#define UKF_H
#include "measurement_package.h"
#include "Eigen/Dense"
#include <vector>
#include <string>
#include <fstream>
#include "tools.h"
using Eigen::MatrixXd;
using Eigen::VectorXd;
class UKF {
public:
///* initially set to false, set to true in first call of ProcessMeasurement
bool is_initialized_;
///* if this is false, laser measurements will be ignored (except for init)
bool use_laser_;
///* if this is false, radar measurements will be ignored (except for init)
bool use_radar_;
///* state vector: [pos1 pos2 vel_abs yaw_angle yaw_rate] in SI units and rad
VectorXd x_;
///* state covariance matrix
MatrixXd P_;
///* predicted sigma points matrix
MatrixXd Xsig_pred_;
///* time when the state is true, in us
long long time_us_;
///* Process noise standard deviation longitudinal acceleration in m/s^2
double std_a_;
///* Process noise standard deviation yaw acceleration in rad/s^2
double std_yawdd_;
///* Laser measurement noise standard deviation position1 in m
double std_laspx_;
///* Laser measurement noise standard deviation position2 in m
double std_laspy_;
///* Radar measurement noise standard deviation radius in m
double std_radr_;
///* Radar measurement noise standard deviation angle in rad
double std_radphi_;
///* Radar measurement noise standard deviation radius change in m/s
double std_radrd_ ;
///* Weights of sigma points
VectorXd weights_;
///* State dimension
int n_x_;
///* Augmented state dimension
int n_aug_;
///* Sigma point spreading parameter
double lambda_;
///* the current NIS for radar
double NIS_radar_;
///* the current NIS for laser
double NIS_laser_;
/**
* Constructor
*/
UKF();
/**
* Destructor
*/
virtual ~UKF();
/**
* ProcessMeasurement
* @param meas_package The latest measurement data of either radar or laser
*/
void ProcessMeasurement(MeasurementPackage meas_package);
/**
* Prediction Predicts sigma points, the state, and the state covariance
* matrix
* @param delta_t Time between k and k+1 in s
*/
void Prediction(double delta_t);
/**
* Updates the state and the state covariance matrix using a laser measurement
* @param meas_package The measurement at k+1
*/
void UpdateLidar(MeasurementPackage meas_package);
/**
* Updates the state and the state covariance matrix using a radar measurement
* @param meas_package The measurement at k+1
*/
void UpdateRadar(MeasurementPackage meas_package);
};
#endif /* UKF_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment