Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Location returned by kalman filter is very noisy #82

Open
arpansengupta-appsbee opened this issue Jul 20, 2020 · 1 comment
Open

Location returned by kalman filter is very noisy #82

arpansengupta-appsbee opened this issue Jul 20, 2020 · 1 comment

Comments

@arpansengupta-appsbee
Copy link

Hello,
I have implemented your library in a foreground service. I am using only the Kalman filter to get user's position every 10m. While setting Utils.GPS_MIN_DISTANCE to 0 the deviations in the points returned is acceptable but setting it to 10m it becomes very noisy.

Below is my locationService. I have used default values in KalmanLocationService.Settings except Utils.GPS_MIN_DISTANCE

`
public class LocationMonitoringService extends Service implements LocationServiceInterface, ILogger {

private static final String TAG = LocationMonitoringService.class.getSimpleName();
private SensorCalibrator m_sensorCalibrator = null;
ApiGPSStream mApiGPSStream = new ApiGPSStream();
String NOTIFICATION_CHANNEL_ID = "FleetWorker";

class RefreshTask extends AsyncTask {
    boolean needTerminate = false;
    long deltaT;
    Context owner;
    RefreshTask(long deltaTMs, Context owner) {
        this.owner = owner;
        this.deltaT = deltaTMs;
    }

    @Override
    protected Object doInBackground(Object[] objects) {
        while (!needTerminate) {
            try {
                Thread.sleep(deltaT);
                publishProgress();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Object... values) {
        if (!m_sensorCalibrator.isInProgress())
            return;

        if (m_sensorCalibrator.getDcAbsLinearAcceleration().isCalculated() &&
                m_sensorCalibrator.getDcLinearAcceleration().isCalculated()) {
            set_isCalibrating(false);
        }

    }
}

private RefreshTask m_refreshTask = new RefreshTask(1000l, this);

@Override
public void onCreate() {
    startService();
    XLog.init();
    super.onCreate();
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    System.out.println("bind");
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    ServicesHelper.addLocationServiceInterface(this);
    initActivity();
    m_refreshTask = new RefreshTask(1000, this);
    m_refreshTask.needTerminate = false;
    m_refreshTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    return START_STICKY;
}


@Override
public void onDestroy() {
    m_refreshTask.needTerminate = true;
    m_refreshTask.cancel(true);
    if (m_sensorCalibrator != null) {
        m_sensorCalibrator.stop();
    }
    stopSelf();
    super.onDestroy();
}


private void initActivity() {
    SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    if (sensorManager == null || locationManager == null) {
        System.exit(1);
    }

    m_sensorCalibrator = new SensorCalibrator(sensorManager);
    ServicesHelper.getLocationService(this, value -> {
        set_isLogging(value.IsRunning());
    });
    set_isCalibrating(true);
}

private void set_isLogging(boolean isLogging) {
    Log.e("isLogging",""+isLogging);
    if (isLogging) {
        ServicesHelper.getLocationService(this, value -> {
            if (value.IsRunning()) {
                return;
            }
            value.stop();
            KalmanLocationService.Settings settings =
                    new KalmanLocationService.Settings(
                            Utils.ACCELEROMETER_DEFAULT_DEVIATION,
                            10,
                            2000,
                            6,
                            2,
                            10,
                            this,
                            false,
                            Utils.DEFAULT_VEL_FACTOR,
                            Utils.DEFAULT_POS_FACTOR
                    );
            value.reset(settings); //warning!! here you can adjust your filter behavior
            value.start();
        });

    } else {
        ServicesHelper.getLocationService(this, value -> {
            value.stop();
        });
    }
}

private void set_isCalibrating(boolean isCalibrating) {
    if (isCalibrating) {
        m_sensorCalibrator.reset();
        m_sensorCalibrator.start();
        set_isLogging(false);
    } else {
        m_sensorCalibrator.stop();
        set_isLogging(true);
    }
}

@Override
public void log2file(String s, Object... objects) {
    XLog.i(s, objects);
}

@Override
public void locationChanged(Location location) {
    Log.e("KALMAN",
            "LAT: "+location.getLatitude()
                    +" LONG: "+location.getLongitude()
                    +" Accuracy: "+ location.getAccuracy()
                    +" getTime: "+ location.getTime()
                    +" getElapsedRealtimeNanos: "+ location.getElapsedRealtimeNanos()
                    +" getAltitude: "+ location.getAltitude()
                    +" getSpeed: "+ location.getSpeed()
                    +" getBearing: "+ location.getBearing()
    );
  
}

public void startService(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel serviceChannel = new NotificationChannel(
                NOTIFICATION_CHANNEL_ID,
                "Location service Channel",
                NotificationManager.IMPORTANCE_HIGH
        );
        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(serviceChannel);
    }

    Intent resultIntent = new Intent(this, SplashActivity.class);
    resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    stackBuilder.addNextIntentWithParentStack(resultIntent);
    PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, 0);

    Notification notification = new NotificationCompat.Builder(this,NOTIFICATION_CHANNEL_ID)
            .setContentTitle("Location service")
                .setContentText("Location streaming in progress")
            .setSmallIcon(R.mipmap.notification_icon)
            .setDefaults(Notification.DEFAULT_ALL)
            .setContentIntent(resultPendingIntent).build();

    startForeground(1,notification);
}

}
`
Below are the poly lines drawn using these position. The actual polylines should be along the road.
map1
map2

@Lezh1k
Copy link
Collaborator

Lezh1k commented Jul 23, 2020

I guess this is related to this GPS_MIN_DISTANCE. I mean gps receiver provides coordinates not frequently and sum of noise from accelerometer becomes bigger (we accumulate this error during predict step).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants