DPRG
DPRG List  



[DPRG] Simple UKF example in 2D

Subject: [DPRG] Simple UKF example in 2D
From: Chris Jang christopher.jang at yahoo.com
Date: Wed Dec 5 01:38:39 CST 2007

I wanted to try the same problem as in:

http://list.dprg.org/archive/2007-November/031051.html

with an unscented Kalman filter. The only difference
is that noise is characterized by 5 sigma points
through the non-linear odometry update:

x(k+1) = x(k) + distance * cos(theta)
y(k+1) = y(k) + distance * sin(theta)

Variance in distance and theta become covariance in x
and y after the update. The UKF more accurately
characterizes the uncertainty by sampling. In the EKF
example, we just chose sufficiently large variance
values in x and y and ignored the polar coordinate
system. This is the main difference between the two
examples.




double x, y;    // current best estimate of position
double x_, y_;  // prediction using odometry process

double dt;      // odometry distance traveled
double th;      // odometry bearing

double zx, zy;  // GPS position measurement

double pxx, pyy, pxy;  // covariance in position
estimate
double wdt, wth;       // variance in odometry process
double vx, vy;         // variance in GPS measurement

double alpha;   // sigma-point tuning factor

// sigma point weights
double a[5];
a[0] = (alpha * alpha - 1) / alpha * alpha;
a[1] = a[2] = a[3] = a[4] = 1 / (4 * alpha * alpha);

// sigma points are around the mean
double _dt[5], _th[5];
_dt[0] = _th[0] = 0
_dt[1] = alpha * sqrt(2) * sqrt(wdt);
_dt[2] =  _dt[1];
_dt[3] = -_dt[1];
_dt[4] = -_dt[1];
_th[1] = alpha * sqrt(2) * sqrt(wth);
_th[2] = -_th[1];
_th[3] =  _th[1];
_th[4] = -_th[1];

while (1)
{
    zx = gpsX();
    zy = gpsY();
    dt = odoDistance();
    th = odoTheta();

    // prior estimate, uses odometry process model
    x_ = x + dt * cos(th);
    y_ = y + dt * sin(th);

    // sigma point mean and covariance of: dt *
cos(th)
    double avg_x = 0, avg_y = 0;
    double cov_xx = 0, cov_yy = 0, cov_xy = 0;
    for (int i = 0; i < 5; i++)
    {
        double xtmp = a[i] * (dt + _dt[i]) * cos(th +
_th[i]);
        double ytmp = a[i] * (dt + _dt[i]) * sin(th +
_th[i]);
        avg_x += xtmp;
        avg_y += ytmp;
        cov_xx += xtmp * xtmp;
        cov_yy += ytmp * ytmp;
        cov_xy += xtmp * ytmp;
    }
    avg_x  = avg_x / 5;
    avg_y  = avg_y / 5;
    cov_xx = (cov_xx / 5) - avg_x * avg_x;
    cov_yy = (cov_yy / 5) - avg_y * avg_y;
    cov_xy = (cov_xy / 5) - avg_x * avg_y;

    // covariance in prediction (prior estimate)
    double pxx_ = pxx + cov_xx;
    double pyy_ = pyy + cov_yy;
    double pxy_ = pxy + cov_xy;

    // Kalman gain matrix
    double tmp = pxx_ * pyy_ - pxy_ * pxy_;
    double K11 = 1 + (pxx_ * vy) / tmp;
    double K22 = 1 + (pyy_ * vx) / tmp;
    double K21 = (pxy_ * vy) / tmp;
    double K12 = (pxy_ * vx) / tmp;

    // posterior estimate, Kalman gain and measurement
correction
    x = x_ + K11 * (zx - x_) + K12 * (zy - y_);
    y = y_ + K21 * (zx - x_) + K22 * (zy - y_);

    // update covariance in posterior estimate
    pxx = (1 - K11) * pxx_ - K12 * pxy_;
    pyy = (1 - K22) * pyy_ - K21 * pxy_;
    pxy = (1 - K22) * pxy_ - K21 * pxx_;
}



      ____________________________________________________________________________________
Be a better friend, newshound, and 
know-it-all with Yahoo! Mobile.  Try it now.  http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 


More information about the DPRG mailing list

Copyright © 1984 - 2006 Dallas Personal Robotics Group. All rights reserved.
Website Design by NCC

For the latest robot news visit robots.net