Skip to content

Commit

Permalink
Added code for Kalman Filter (Lidar and Radar) and RMSE (error).
Browse files Browse the repository at this point in the history
  • Loading branch information
MyCodeBits committed Jul 22, 2017
1 parent 59ecd58 commit 8bfd1c5
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 129 deletions.
Binary file added output_images/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added output_images/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added output_images/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added output_images/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
97 changes: 80 additions & 17 deletions src/FusionEKF.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -31,13 +31,38 @@ FusionEKF::FusionEKF() {
0, 0.0009, 0, 0, 0.0009, 0,
0, 0, 0.09; 0, 0, 0.09;


/** /*
TODO: * Initialize the FusionEKF.
* Finish initializing the FusionEKF. * Set the process and measurement noises
* Set the process and measurement noises */
*/ // measurement function matrix - laser

H_laser_ << 1, 0, 0, 0,

0, 1, 0, 0;

//state covariance matrix: low values for high certainity
MatrixXd P_ = MatrixXd(4, 4);
P_ << 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1000, 0,
0, 0, 0, 1000;

// state transition matrix
MatrixXd F_ = MatrixXd(4, 4);
F_ << 1, 0, 1, 0,
0, 1, 0, 1,
0, 0, 1, 0,
0, 0, 0, 1;

// new covariance matrix based on noise vector
MatrixXd Q_ = MatrixXd(4, 4);
Q_ << 1, 0, 1, 0,
0, 1, 0, 1,
1, 0, 1, 0,
0, 1, 0, 1;

VectorXd x_ = VectorXd(4);
x_ << 1, 1, 1, 1;
ekf_.Init(x_, P_, F_, H_laser_, R_laser_, Q_);
} }


/** /**
Expand All @@ -53,7 +78,6 @@ void FusionEKF::ProcessMeasurement(const MeasurementPackage &measurement_pack) {
****************************************************************************/ ****************************************************************************/
if (!is_initialized_) { if (!is_initialized_) {
/** /**
TODO:
* Initialize the state ekf_.x_ with the first measurement. * Initialize the state ekf_.x_ with the first measurement.
* Create the covariance matrix. * Create the covariance matrix.
* Remember: you'll need to convert radar from polar to cartesian coordinates. * Remember: you'll need to convert radar from polar to cartesian coordinates.
Expand All @@ -63,16 +87,28 @@ void FusionEKF::ProcessMeasurement(const MeasurementPackage &measurement_pack) {
ekf_.x_ = VectorXd(4); ekf_.x_ = VectorXd(4);
ekf_.x_ << 1, 1, 1, 1; ekf_.x_ << 1, 1, 1, 1;


// initialize position and velocity
float px = 0.0;
float py = 0.0;
float vx = 0.0;
float vy = 0.0;

if (measurement_pack.sensor_type_ == MeasurementPackage::RADAR) { if (measurement_pack.sensor_type_ == MeasurementPackage::RADAR) {
/** // Convert radar from polar to cartesian coordinates and initialize state.
Convert radar from polar to cartesian coordinates and initialize state. float rho = measurement_pack.raw_measurements_[0];
*/ float phi = measurement_pack.raw_measurements_[1];
float rho_dot = measurement_pack.raw_measurements_[2];

px = rho * cos(phi);
py = rho * sin(phi);
} else if (measurement_pack.sensor_type_ == MeasurementPackage::LASER) { } else if (measurement_pack.sensor_type_ == MeasurementPackage::LASER) {
/** px = measurement_pack.raw_measurements_[0];
Initialize state. py = measurement_pack.raw_measurements_[1];
*/
} }


ekf_.x_ << px, py, vx, vy;
previous_timestamp_ = measurement_pack.timestamp_;

// done initializing, no need to predict or update // done initializing, no need to predict or update
is_initialized_ = true; is_initialized_ = true;
return; return;
Expand All @@ -83,32 +119,59 @@ void FusionEKF::ProcessMeasurement(const MeasurementPackage &measurement_pack) {
****************************************************************************/ ****************************************************************************/


/** /**
TODO:
* Update the state transition matrix F according to the new elapsed time. * Update the state transition matrix F according to the new elapsed time.
- Time is measured in seconds. - Time is measured in seconds.
* Update the process noise covariance matrix. * Update the process noise covariance matrix.
* Use noise_ax = 9 and noise_ay = 9 for your Q matrix. * Use noise_ax = 9 and noise_ay = 9 for your Q matrix.
*/ */


// calculating time elapsed
float dt = (measurement_pack.timestamp_ - previous_timestamp_) / 1000000.0;
previous_timestamp_ = measurement_pack.timestamp_;

// Update the state transition matrix F according to the new elapsed time
ekf_.F_(0, 2) = dt;
ekf_.F_(1, 3) = dt;

float dt_2 = dt * dt;
float dt_3 = dt_2 * dt / 2.0;
float dt_4 = dt_3 * dt / 2.0;

//set the process covariance matrix Q
ekf_.Q_ = MatrixXd(4, 4);
ekf_.Q_ << dt_4 * noise_ax, 0, dt_3 * noise_ax, 0,
0, dt_4 * noise_ay, 0, dt_3 * noise_ay,
dt_3 * noise_ax, 0, dt_2 * noise_ax, 0,
0, dt_3 * noise_ay, 0, dt_2 * noise_ay;

ekf_.Predict(); ekf_.Predict();


/***************************************************************************** /*****************************************************************************
* Update * Update
****************************************************************************/ ****************************************************************************/


/** /**
TODO:
* Use the sensor type to perform the update step. * Use the sensor type to perform the update step.
* Update the state and covariance matrices. * Update the state and covariance matrices.
*/ */


if (measurement_pack.sensor_type_ == MeasurementPackage::RADAR) { if (measurement_pack.sensor_type_ == MeasurementPackage::RADAR) {
// Radar updates // Radar updates
try {
ekf_.R_ = R_radar_;
ekf_.H_ = tools.CalculateJacobian(ekf_.x_);
ekf_.UpdateEKF(measurement_pack.raw_measurements_);
} catch (...) {
return;
}
} else { } else {
// Laser updates // Laser updates
ekf_.R_ = R_laser_;
ekf_.H_ = H_laser_;
ekf_.Update(measurement_pack.raw_measurements_);
} }


// print the output // print the output
cout << "x_ = " << ekf_.x_ << endl; cout << "x_ = " << ekf_.x_ << endl;
cout << "P_ = " << ekf_.P_ << endl; cout << "P_ = " << ekf_.P_ << endl;
} }
6 changes: 5 additions & 1 deletion src/FusionEKF.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ class FusionEKF {
Eigen::MatrixXd R_radar_; Eigen::MatrixXd R_radar_;
Eigen::MatrixXd H_laser_; Eigen::MatrixXd H_laser_;
Eigen::MatrixXd Hj_; Eigen::MatrixXd Hj_;

// Noise parameters as suggested.
float noise_ax = 9.0;
float noise_ay = 9.0;
}; };


#endif /* FusionEKF_H_ */ #endif /* FusionEKF_H_ */
65 changes: 52 additions & 13 deletions src/kalman_filter.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -18,22 +18,61 @@ void KalmanFilter::Init(VectorXd &x_in, MatrixXd &P_in, MatrixXd &F_in,
} }


void KalmanFilter::Predict() { void KalmanFilter::Predict() {
/** // predict the state
TODO: x_ = F_ * x_;
* predict the state P_ = F_ * P_ * F_.transpose() + Q_;
*/
} }


void KalmanFilter::Update(const VectorXd &z) { void KalmanFilter::Update(const VectorXd &z) {
/** // update the state by using Kalman Filter equations
TODO:
* update the state by using Kalman Filter equations // measurement update
*/ VectorXd z_pred = H_ * x_;
VectorXd y = z - z_pred;
MatrixXd PHt = P_ * H_.transpose();
MatrixXd S = H_ * PHt + R_;
MatrixXd K = PHt * S.inverse();

//new state
x_ = x_ + (K * y);
int x_size = x_.size();
MatrixXd I = MatrixXd::Identity(x_size, x_size);
P_ = (I - K * H_) * P_;
} }


void KalmanFilter::UpdateEKF(const VectorXd &z) { void KalmanFilter::UpdateEKF(const VectorXd &z) {
/** // update the state by using Extended Kalman Filter equations
TODO:
* update the state by using Extended Kalman Filter equations // get components of predicted state
*/ float px = x_(0);
} float py = x_(1);
float vx = x_(2);
float vy = x_(3);

// get components of radar measurement space
float rho = sqrt(px * px + py * py);
float phi = atan2(py, px);
float rho_dot = (rho != 0 ? (px * vx + py * vy) / rho : 0);

// define predicted position and speed
VectorXd z_pred(3);
z_pred << rho, phi, rho_dot;

// measurement update
VectorXd y = z - z_pred;

// normalize angle
double width = 2 * M_PI; //
double offsetValue = y(1) + M_PI; // value relative to 0
y(1) = (offsetValue - (floor(offsetValue / width) * width)) - M_PI;

MatrixXd PHt = P_ * H_.transpose();
MatrixXd S = H_ * PHt + R_;
MatrixXd K = PHt * S.inverse();

// new state
x_ = x_ + (K * y);
int x_size = x_.size();
MatrixXd I = MatrixXd::Identity(x_size, x_size);
P_ = (I - K * H_) * P_;
}
2 changes: 1 addition & 1 deletion src/kalman_filter.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class KalmanFilter {
// state covariance matrix // state covariance matrix
Eigen::MatrixXd P_; Eigen::MatrixXd P_;


// state transition matrix // state transistion matrix
Eigen::MatrixXd F_; Eigen::MatrixXd F_;


// process covariance matrix // process covariance matrix
Expand Down
89 changes: 1 addition & 88 deletions src/main.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -175,91 +175,4 @@ int main() {
return -1; return -1;
} }
h.run(); h.run();
} }























































































Loading

0 comments on commit 8bfd1c5

Please sign in to comment.