0

I have a dataset where measurements were taken at 10 Hz, and I am trying to use a Kalman filter to add predicted samples in between the measurements, so that my output is at 100 Hz. I have it working ok when the velocity is linear, but when the direction changes, the filter takes a while to catch up. I am new to Kalman models, so am very likely making some mistakes in my settings. See attached image for an example, the red is measured data, with stepping in between measurements. The blue is the Kalman corrected.

std::vector<double> measurements is a dummy data array I am testing with.

The main Kalman code is based on Github: hmartiro/kalman-cppkalman.cpp

The measurement / estimation loop is based on this

Am I correct in feeding the prediction back into the filter for every loop? Or is this line:

yPos << kf.state().transpose(); wrong?

My code is:

int main(int argc, char* argv[]) {

  int n = 3; // Number of states
  int m = 1; // Number of measurements

  double dt = 1.0/10; // Time step

  Eigen::MatrixXd matA(n, n); // System dynamics matrix
  Eigen::MatrixXd matC(m, n); // Output matrix
  Eigen::MatrixXd matQ(n, n); // Process noise covariance
  Eigen::MatrixXd matR(m, m); // Measurement noise covariance
  Eigen::MatrixXd matP(n, n); // Estimate error covariance

  // Discrete motion, measuring position only
  matA << 1, dt, 0, 0, 1, dt, 0, 0, 1;
  matC << 1, 0, 0;

  // Reasonable covariance matrices
  matQ << 0.001, 0.001, .0, 0.001, 0.001, .0, .0, .0, .0;
  matR << 0.03;
  matP << .1, .1, .1, .1, 10000, 10, .1, 10, 100;

  // Construct the filter
  KalmanFilter kf(dt,matA, matC, matQ, matR, matP);

  // List of noisy position measurements (yPos)
  std::vector<double> measurements = {
     10,11,13,13.5,14,15.2,15.6,16,18,22,20,21,19,18,17,16,17.5,19,21,22,23,25,26,25,24,21,20,18,16
  };

  // Best guess of initial states
  Eigen::VectorXd x0(n);
  x0 << measurements[0], 0, 0;
  kf.init(dt,x0);

  // Feed measurements into filter, output estimated states
  double t = 0;
  Eigen::VectorXd y(m);


  for(int i = 0; i < measurements.size(); i++) { //ACTUAL MEASURED SAMPLE

      yPos << measurements[i];

      kf.update(yPos);

      for (int ji = 0; ji < 10; ji++)  // TEN PREDICTED SAMPLES
      {
          t += dt;       

         kf.update(yPos);


          yPos << kf.state().transpose(); //USE PREDICTION AS NEW SAMPLE

      }
  }

  return 0;
}

Thank you.

anti
  • 3,011
  • 7
  • 36
  • 86
  • 1
    This question might find more traction at [CodeReview](https://codereview.stackexchange.com/) – AndyG Jun 08 '17 at 15:33
  • Ah, i will move it there. Thank you! – anti Jun 08 '17 at 15:34
  • @AndyG The question has been [downvoted and closed on Code Review](https://codereview.stackexchange.com/q/165277/9357). – 200_success Jun 08 '17 at 17:39
  • @200_success: Apologies for my naivete. I thought that Code Review would be a good spot following the guidance [here](https://codereview.meta.stackexchange.com/questions/5777/a-guide-to-code-review-for-stack-overflow-users), specifically that "Answers can suggest any improvement". I (incorrectly) assumed that OP thought that their code was working for most cases, but was looking for feedback on perhaps any edge cases where it would fail. – AndyG Jun 08 '17 at 19:50
  • Can't seem to find a home for this. I will get the code working and re-write the question. Should I close this one? or will that effect my 'reputation'? Thanks! – anti Jun 08 '17 at 22:29
  • You might be interested in these answers: https://stackoverflow.com/questions/34290860/tracking-position-and-velocity-using-a-kalman-filter/34324218#34324218 https://stackoverflow.com/questions/25702120/how-to-use-a-kalman-filter-to-predict-gps-positions-in-between-meassurements/26263172#26263172 – Ben Jackson Jun 12 '17 at 17:01

0 Answers0