maddevsio / mad-location-manager

Mad Location Manager is a library for GPS and Accelerometer data "fusion" with Kalman filter
MIT License
538 stars 155 forks source link

URGENT HELP #113

Open kritikas726 opened 2 years ago

kritikas726 commented 2 years ago

Hi my name is Kritika Sharma and I have to make a project. The idea is to name an android application which take GPS values from android phones and calculate speed through either calculating distance between two GPS coordinates or somehow through accelerometer(still don't know how to). Pass the values through Kalman Filter(not perfectly clear how it works) and get a corrected speed. The user which enter a max speed, if the calculated speed is higher than the user's max speed, it will generate a audio alert. I have tried so many resources to understand Kalman Filter but I am unable to, always getting confused with values of matrices. Can you please please please help me with this? My email id is kritikas726@gmail.com

Lezh1k commented 2 years ago

@kritikas726 Hello there. Could you provide more details about your issue with Kalman filter?

I found this article very useful: http://campar.in.tum.de/Chair/KalmanFilter. Also there is a link to our blog with all explanations.

kritikas726 commented 2 years ago

Hi, actually I want to make an android application where the application takes GPS coordinates(lat,long) of the phone in a car, and passes it through a kalman filter and predicts the velocity. This velocity will be shown to the user. User will be asked to input a max speed. Now, if the speed at any given time in the moving car goes above that max speed limit(for example 60km/hr) there will be an audio alert to lower down the speed. I read about kalman filter a lot but I am not able to implement it on a dataset. I am not able to understand what values will be the input, what will be the output, how will it work and what should be the values in the matrix for this application. I have tried to red about kalman filter a lot but somehow I am not able to understand it. If you could help me in this then it will be great.

Lezh1k commented 2 years ago

@kritikas726

I don't see the necessity in Kalman filter in your task. You can get the speed from GPS and this value is going to be very accurate.

But anyway if you are sure that you need Kalman, then :

  1. X[k] - it's your system state. In my case it is vector and looks like this : x - x coord y - y coord x' - x velocity y' - y velocity

  2. F - it's your transition state matrix. It can be used as "movement law". In my case it looks like this: `F.set({

      1.0, 0.0, dt_ms, 0.0,
    
      0.0, 1.0, 0.0, dt_ms,
    
      0.0, 0.0, 1.0, 0.0,
    
      0.0, 0.0, 0.0, 1.0});`

dt_ms - delta time in milliseconds.

  1. B - it's control matrix

double dt_2 = 0.5 dt_ms dt_ms; B.set({

      dt_2, 0.0,

      0.0, dt_2,

      dt_ms, 0.0,

      0.0, dt_ms

    });


4. U - control vector. In my case it contains accelerations for x and y axis.

SO!!! 
Try to apply to these 4 matrices this formula : 
X[k+1] = F * X[k] + B * U 

It will looks like this for your system:
x[k+1] = x[k] + x'[k]*dt + (x'' * dt ^ 2) / 2
y[k+1] = y[k] + y'[k]*dt + (y'' * dt ^ 2) / 2
x'[k+1] = x[k] + x'' * dt
y'[k+1] = y[k] + y'' * dt. 

It is uniformly accelerated motion law :)  

Other matrices are magic except Q and R. Those 2 are most difficult part. But simplified: 

    Q, the process noise covariance, contributes to the overall uncertainty. When Q is large, the Kalman Filter tracks large changes in the data more closely than for smaller Q.

    R, the measurement noise covariance, determines how much information from the measurement is used. If R is high, the Kalman Filter considers the measurements as not very accurate. For smaller R it will follow the measurements more closely.

In your case you will use GPS as speed data source. GPS provides very precise speed so you will have small values in R matrix and large values in Q (because accelerometers are noisy).  
kritikas726 commented 2 years ago

Can we have a zoom(or any type of meeting,Google Meet, Microsoft Teams) call if you are free sometime today? Are you Indian or is there time difference between us? And in x - x coord y - y coord x' - x velocity y' - y velocity In my case x and y coordinates will be the latitude and longitude coordiantes, so can I enter them directly or do I have to change them in some other form? and x' velocity and y' velocity will be 0.0 in my case right? You said in my case GPS will provide me speed, but I guess it wont provide me speed in x and y direction separately. And for accelerometer values the accelerometer in android phones provide me with acceleration values in x,y and z. So should I discard z value? But what if the phone orientation changes?Can we have a zoom(or any type of meeting,Google Meet, Microsoft Teams) call if you are free sometime today?

Lezh1k commented 2 years ago

Sure, we can have a meeting. My time zone is GMT+6.

  1. Yes, in your case x and y coordinates are longitude and latitude respectively. But you can not use them directly because they are in different coordinate system. So you need to convert them into meters.

So your x will be the distance between the point (longitude: 0, latitude: your_latitude) and "zero" point (longitude: 0, latitude: 0) And your y will be the distance between the point (longitude: your_longitude, latitude: 0) and "zero" point.

You can find all those calculations here..

  1. x' and y' velocity won't be 0.0 in your case. GPS receivers provide speed as 2 values: speed + bearing. Android system provides everything in their Location class. But if you use some bare metal system then you need to parse nmea messages directly. In this case you are interested in 3 parts of nmea message: ground speed, course and hdop. Some receivers don't provide hdop, in this case you need to read their manuals and find alternative.

So! With speed and bearing your x' = speed cos(course) and y' = speed sin(course) . If you are on android : course = location.GetBearing() . Actually it has to be checked twice. You need to be sure that course is a clockwise angle between direction and true north.

  1. Accelerometer values should be converted too (because they are not connected to any coordinate system). SO! Firstly you have to receive the position of your phone in space. This position can be represented as rotation matrix or as quaternion (I recommend use quaternion form). This quaternion can be received from android's ROTATION_VECTOR. Or, alternatively, you can implement the Madgwick's filter. I tried both of them and recommend use ROTATION_VECTOR on android and Madgwick on bare metal.

Once you received quaternion you can "connect" your accelerometer values to our coordinate system. You just need to take values from LINEAR_ACCELERATION sensor and multiply it on that quaternion.

Sample code is available here and here

Or you can convert quaternion from ROTATION_VECTOR sensor into matrix and multiply LINEAR_ACCELERATION vector on it. Both methods work fine :)

I hope this can help too.