Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 158 additions & 0 deletions src/main/java/com/kalmanFilters/Tracker1D.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package com.kalmanFilters;


/**
* Kalman filter tracking in one dimension.
*/
class Tracker1D {

// Settings

/**
* Time step
*/
private final double mt, mt2, mt2d2, mt3d2, mt4d4;

/**
* Process noise covariance
*/
private final double mQa, mQb, mQc, mQd;

/**
* Estimated state
*/
private double mXa, mXb;

/**
* Estimated covariance
*/
private double mPa, mPb, mPc, mPd;

/**
* Creates a tracker.
*
* @param timeStep Delta time between predictions. Usefull to calculate speed.
* @param processNoise Standard deviation to calculate noise covariance from.
*/
public Tracker1D(double timeStep, double processNoise) {

// Lookup time step
mt = timeStep;
mt2 = mt * mt;
mt2d2 = mt2 / 2.0;
mt3d2 = mt2 * mt / 2.0;
mt4d4 = mt2 * mt2 / 4.0;

// Process noise covariance
double n2 = processNoise * processNoise;
mQa = n2 * mt4d4;
mQb = n2 * mt3d2;
mQc = mQb;
mQd = n2 * mt2;

// Estimated covariance
mPa = mQa;
mPb = mQb;
mPc = mQc;
mPd = mQd;
}

/**
* Reset the filter to the given state.
* <p>
* Should be called after creation, unless position and velocity are assumed to be both zero.
*
* @param position
* @param velocity
* @param noise
*/
public void setState(double position, double velocity, double noise) {

// State vector
mXa = position;
mXb = velocity;

// Covariance
double n2 = noise * noise;
mPa = n2 * mt4d4;
mPb = n2 * mt3d2;
mPc = mPb;
mPd = n2 * mt2;
}

/**
* Update (correct) with the given measurement.
*
* @param position
* @param noise
*/
public void update(double position, double noise) {

double r = noise * noise;

// y = z - H . x
double y = position - mXa;

// S = H.P.H' + R
double s = mPa + r;
double si = 1.0 / s;

// K = P.H'.S^(-1)
double Ka = mPa * si;
double Kb = mPc * si;

// x = x + K.y
mXa = mXa + Ka * y;
mXb = mXb + Kb * y;

// P = P - K.(H.P)
double Pa = mPa - Ka * mPa;
double Pb = mPb - Ka * mPb;
double Pc = mPc - Kb * mPa;
double Pd = mPd - Kb * mPb;

mPa = Pa;
mPb = Pb;
mPc = Pc;
mPd = Pd;
}

/**
* Predict state.
*
* @param acceleration Should be 0 unless there's some sort of control input (a gas pedal, for instance).
*/
public void predict(double acceleration) {

// x = F.x + G.u
mXa = mXa + mXb * mt + acceleration * mt2d2;
mXb = mXb + acceleration * mt;

// P = F.P.F' + Q
double Pdt = mPd * mt;
double FPFtb = mPb + Pdt;
double FPFta = mPa + mt * (mPc + FPFtb);
double FPFtc = mPc + Pdt;
double FPFtd = mPd;

mPa = FPFta + mQa;
mPb = FPFtb + mQb;
mPc = FPFtc + mQc;
mPd = FPFtd + mQd;
}

/**
* @return Estimated position.
*/
public double getPosition() { return mXa; }

/**
* @return Estimated velocity.
*/
public double getVelocity() { return mXb; }

/**
* @return Accuracy
*/
public double getAccuracy() { return Math.sqrt(mPd / mt2); }
}
18 changes: 18 additions & 0 deletions src/main/java/com/marianhello/bgloc/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public class Config implements Parcelable
private HashMap httpHeaders;
private Integer maxLocations;
private LocationTemplate template;
private Boolean applyKalmanFilter;

public Config () {
}
Expand Down Expand Up @@ -95,6 +96,7 @@ public Config(Config config) {
if (config.template instanceof AbstractLocationTemplate) {
this.template = ((AbstractLocationTemplate)config.template).clone();
}
this.applyKalmanFilter = config.applyKalmanFilter;
}

private Config(Parcel in) {
Expand Down Expand Up @@ -123,6 +125,7 @@ private Config(Parcel in) {
Bundle bundle = in.readBundle();
setHttpHeaders((HashMap<String, String>) bundle.getSerializable("httpHeaders"));
setTemplate((LocationTemplate) bundle.getSerializable(AbstractLocationTemplate.BUNDLE_KEY));
setApplyKalmanFilter((Boolean) in.readValue(null));
}

public static Config getDefault() {
Expand Down Expand Up @@ -151,6 +154,7 @@ public static Config getDefault() {
config.httpHeaders = null;
config.maxLocations = 10000;
config.template = null;
config.applyKalmanFilter = true;

return config;
}
Expand Down Expand Up @@ -183,6 +187,7 @@ public void writeToParcel(Parcel out, int flags) {
out.writeString(getSyncUrl());
out.writeInt(getSyncThreshold());
out.writeInt(getMaxLocations());
out.writeValue(getApplyKalmanFilter());
Bundle bundle = new Bundle();
bundle.putSerializable("httpHeaders", getHttpHeaders());
bundle.putSerializable(AbstractLocationTemplate.BUNDLE_KEY, (AbstractLocationTemplate) getTemplate());
Expand Down Expand Up @@ -520,6 +525,15 @@ public void setTemplate(LocationTemplate template) {
this.template = template;
}

public boolean hasApplyKalmanFilter() {
return applyKalmanFilter != null;
}

public void setApplyKalmanFilter(Boolean applyKalmanFilter) { this.applyKalmanFilter = applyKalmanFilter; }

public Boolean getApplyKalmanFilter() { return applyKalmanFilter; }


@Override
public String toString () {
return new StringBuffer()
Expand Down Expand Up @@ -547,6 +561,7 @@ public String toString () {
.append(" httpHeaders=").append(getHttpHeaders().toString())
.append(" maxLocations=").append(getMaxLocations())
.append(" postTemplate=").append(hasTemplate() ? getTemplate().toString() : null)
.append(" applyKalmanFilter=").append(getApplyKalmanFilter())
.append("]")
.toString();
}
Expand Down Expand Up @@ -639,6 +654,9 @@ public static Config merge(Config config1, Config config2) {
if (config2.hasTemplate()) {
merger.setTemplate(config2.getTemplate());
}
if (config2.hasApplyKalmanFilter()) {
merger.setApplyKalmanFilter(config2.getApplyKalmanFilter());
}

return merger;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public static abstract class ConfigurationEntry implements BaseColumns {
public static final String COLUMN_NAME_HEADERS = "http_headers";
public static final String COLUMN_NAME_MAX_LOCATIONS = "max_locations";
public static final String COLUMN_NAME_TEMPLATE = "template";
public static final String COLUMN_NAME_APPLY_KALMAN_FILTER = "applyKalmanFilter";

public static final String SQL_CREATE_CONFIG_TABLE =
"CREATE TABLE " + ConfigurationEntry.TABLE_NAME + " (" +
Expand Down Expand Up @@ -67,7 +68,8 @@ public static abstract class ConfigurationEntry implements BaseColumns {
ConfigurationEntry.COLUMN_NAME_SYNC_THRESHOLD + INTEGER_TYPE + COMMA_SEP +
ConfigurationEntry.COLUMN_NAME_HEADERS + TEXT_TYPE + COMMA_SEP +
ConfigurationEntry.COLUMN_NAME_MAX_LOCATIONS + INTEGER_TYPE + COMMA_SEP +
ConfigurationEntry.COLUMN_NAME_TEMPLATE + TEXT_TYPE +
ConfigurationEntry.COLUMN_NAME_TEMPLATE + TEXT_TYPE + COMMA_SEP +
ConfigurationEntry.COLUMN_NAME_APPLY_KALMAN_FILTER + INTEGER_TYPE +
" )";

public static final String SQL_DROP_CONFIG_TABLE =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ public Config retrieveConfiguration() throws JSONException {
ConfigurationEntry.COLUMN_NAME_SYNC_THRESHOLD,
ConfigurationEntry.COLUMN_NAME_HEADERS,
ConfigurationEntry.COLUMN_NAME_MAX_LOCATIONS,
ConfigurationEntry.COLUMN_NAME_TEMPLATE
ConfigurationEntry.COLUMN_NAME_TEMPLATE,
ConfigurationEntry.COLUMN_NAME_APPLY_KALMAN_FILTER
};

String whereClause = null;
Expand Down Expand Up @@ -123,7 +124,7 @@ private Config hydrate(Cursor c) throws JSONException {
config.setHttpHeaders(new JSONObject(c.getString(c.getColumnIndex(ConfigurationEntry.COLUMN_NAME_HEADERS))));
config.setMaxLocations(c.getInt(c.getColumnIndex(ConfigurationEntry.COLUMN_NAME_MAX_LOCATIONS)));
config.setTemplate(LocationTemplateFactory.fromJSONString(c.getString(c.getColumnIndex(ConfigurationEntry.COLUMN_NAME_TEMPLATE))));

config.setApplyKalmanFilter( (c.getInt(c.getColumnIndex(ConfigurationEntry.COLUMN_NAME_APPLY_KALMAN_FILTER)) == 1) ? true : false );
return config;
}

Expand Down Expand Up @@ -154,6 +155,7 @@ private ContentValues getContentValues(Config config) throws NullPointerExceptio
values.put(ConfigurationEntry.COLUMN_NAME_HEADERS, new JSONObject(config.getHttpHeaders()).toString());
values.put(ConfigurationEntry.COLUMN_NAME_MAX_LOCATIONS, config.getMaxLocations());
values.put(ConfigurationEntry.COLUMN_NAME_TEMPLATE, config.hasTemplate() ? config.getTemplate().toString() : null);
values.put(ConfigurationEntry.COLUMN_NAME_APPLY_KALMAN_FILTER, (config.getApplyKalmanFilter() == true) ? 1 : 0);

return values;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
alterSql.add(SQL_CREATE_CONFIG_TABLE);
case 11:
alterSql.add("ALTER TABLE " + LocationEntry.TABLE_NAME +
" ADD COLUMN " + LocationEntry.COLUMN_NAME_RADIUS + REAL_TYPE);
" ADD COLUMN " + LocationEntry.COLUMN_NAME_STOP_TERMINATE + REAL_TYPE);
alterSql.add("ALTER TABLE " + LocationEntry.TABLE_NAME +
" ADD COLUMN " + LocationEntry.COLUMN_NAME_HAS_ACCURACY + INTEGER_TYPE);
alterSql.add("ALTER TABLE " + LocationEntry.TABLE_NAME +
Expand Down Expand Up @@ -140,4 +140,4 @@ public void execAndLogSql(SQLiteDatabase db, String sql) {
Log.e(TAG, "Error executing sql: " + e.getMessage());
}
}
}
}
Loading