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

NaN latitude and longitude #19

Open
tdimeco opened this issue Oct 1, 2018 · 6 comments
Open

NaN latitude and longitude #19

tdimeco opened this issue Oct 1, 2018 · 6 comments

Comments

@tdimeco
Copy link

tdimeco commented Oct 1, 2018

Hello,

I have an issue with the filter. Sometimes, the algorithm returns a location with both latitude and longitude NaN:

(lldb) po location
<nan,nan> +/- 65.00m (speed -1.00 mps / course -1.00) @ 01/10/2018 18:07:54 UTC+02:00

Usually, everything works fine and locations are smoothed correctly, but in certain circumstances the output location is NaN.

In case this can help you: the issue occurs indoor, the GPS signal is low, the phone is not moving on a table and the app fetches location in background every second. The problem starts sometimes after 3 minutes, sometimes after 1+ hour. Feel free to ask me if you need further information.

Thank you!

Thomas

@yashbedi
Copy link

yashbedi commented Feb 6, 2019

Hey Thomas thanks for bringing up this issue,
Can you suggest any best way to overcome this issue,? I mean instead using bunch of if let's or guard statements.

@tdimeco
Copy link
Author

tdimeco commented Feb 6, 2019

Hey Yash,

I am not using the library anymore, but in the past, I temporary "solved" the issue by resetting the Kalman filter when it was dirty. Here is some parts of the code:

class LocationDataProvider: CLLocationManagerDelegate {
    
    // ...
    
    private var locationManager: CLLocationManager?
    private var kalmanAlgorithm: HCKalmanAlgorithm?
    
    // ...
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        
        let location = locations.last!
        var correctedLocation: CLLocation!
        
        // Use the kalman algorithm to smooth location data
        if self.kalmanAlgorithm == nil {
            self.kalmanAlgorithm = HCKalmanAlgorithm(initialLocation: location)
            correctedLocation = location
        } else {
            correctedLocation = self.kalmanAlgorithm!.processState(currentLocation: location)
        }
        
        correctedLocation = self.tempFixForNaNLocations(location: location, correctedLocation: correctedLocation)
        
        // ... <Use correctedLocation>
    }
    
    // FIX: Temporary fix to avoid NaN locations: https://github.com/Hypercubesoft/HCKalmanFilter/issues/19
    private func tempFixForNaNLocations(location: CLLocation, correctedLocation: CLLocation) -> CLLocation {
        if correctedLocation.coordinate.latitude.isNaN || correctedLocation.coordinate.longitude.isNaN || correctedLocation.altitude.isNaN {
            self.kalmanAlgorithm = HCKalmanAlgorithm(initialLocation: location)
            return location
        } else {
            return correctedLocation
        }
    }
}

Hope this can help you.
Cheers.

@yashbedi
Copy link

Hey, Thomas

Yeah, I too figured out a way something like that.
Though Really appreciate you taking out time to write the snippet. Thank you.

@Gerharbo
Copy link

Gerharbo commented Apr 9, 2019

We've had the same problem. It seems that the problem is the value of timeInterval. It's 0 when calculating velocityXComponent, velocityYComponent and velocityZComponent.

See lines 197, 198 and 199:
https://github.com/Hypercubesoft/HCKalmanFilter/blob/master/HCKalmanFilter/HCKalmanAlgorithm.swift#L197

After calculating the velocity, the outcome is:

velocityXComponent = (Double) -Inf
velocityYComponent = (Double) NaN
velocityZComponent = (Double) NaN

What's the best approach? Should we skip the location? Or should the KalmanFilter be altered to devide by 1 instead of zero?

@Mike1707
Copy link

Mike1707 commented May 20, 2019

Hey guys, I found this library right now and didn't test it yet but looked into this issue.

For me it sounds as if you are using cached locations which you receive in your didUpdateLocations method because the timestamp of the new and previous location must be the same if these three values are 0.

In my own app, I skip cached locations in my didUpdateLocations method when they are older than 10 seconds (however, you should test how many seconds fit to your case). I also skip locations which are invalid (horizontalAccuracy < 0) and those with an horizontalAccuracy over 30 meters.

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    
        guard let mostRecentLocation = locations.last else {
            return
        }
        
        let age = -mostRecentLocation.timestamp.timeIntervalSinceNow
        
        // Filter cached locations, invalid ones and ones with accuracy over 30 meters
        if age > 10 || mostRecentLocation.horizontalAccuracy < 0 || mostRecentLocation.horizontalAccuracy > 30 {
            return
        }

        // ... Use your location 
}

This will not fix the library code which doesn't test for division by zero, but maybe this will help anyway.

@PguOrange
Copy link

Hello,

Just if some one else got this error.
I have done some investigation and i find that i have a NaN error when my location (previous and current one) have the same timestamp.

If they have the same timestamps some we do a division by 0 and we got a NaN.
To prevent it you can just check your locations timestamps before use Kalman or update KalmanAlgo to set value to 0 if the interval between locations is 0

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

5 participants