0

I'm building a tracking app and I found out that I should filter out GPS raw data, so I'm using a Kalman filter, and it really smooths out the resulting tracking. So I'm fine tuning two parameters, and in order to be able to change those parameters on the go from the iPhone I added two textfields @IBOutlet weak var filterValueTextField: UITextField! and @IBOutlet weak var horizontalAccuracyTextField: UITextField! and I want to connected those to the parameters hcKalmanFilter?.rValue = 40.0 and guard mostRecentLocation.horizontalAccuracy < 60 else { return }. I did try various ways but I get an error:

Cannot invoke initializer for type 'Double' with an argument list of type '(String?)' on this try: guard mostRecentLocation.horizontalAccuracy < Double(horizontalAccuracyTextField.text) else { return }

This is the function:

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {


        hcKalmanFilter?.rValue = 40.0

        guard let mostRecentLocation = locations.last else { return }
        guard mostRecentLocation.horizontalAccuracy > 0 else { return }
        guard mostRecentLocation.horizontalAccuracy < 60 else { return }

        guard mostRecentLocation.horizontalAccuracy < horizontalAccuracy else { return }



        var myLocation: CLLocation = mostRecentLocation

        if hcKalmanFilter == nil {
            self.hcKalmanFilter = HCKalmanAlgorithm(initialLocation: myLocation)
        }
        else {
            if let hcKalmanFilter = self.hcKalmanFilter {
                if resetKalmanFilter == true {
                    hcKalmanFilter.resetKalman(newStartLocation: myLocation)
                    resetKalmanFilter = false
                }
                else {
                    let kalmanLocation = hcKalmanFilter.processState(currentLocation: myLocation)
                    self.actualRouteInUseCoordinatesArray.append(kalmanLocation.coordinate)
                }
            }
        }
    }

I tried to handle it like this after @maddy advises :

var filterValue:Double = 40.0
        guard let filterAmount:String? = filterValueTextField.text! else  {return}
        filterValue = Double(filterAmount)!
        hcKalmanFilter?.rValue = filterValue

but I still get error : Cannot invoke initializer for type 'Double' with an argument list of type '(String?)'

Vincenzo
  • 5,304
  • 5
  • 38
  • 96
  • Do not use `!`. Safely unwrap. And never use `String(describing:)` for anything except printing something for debugging. – rmaddy Aug 26 '18 at 15:10
  • @maddy. can you explain me why String(describing:) should not be used? I'm still learning so that would be very helpful as I us it in different portions of my app. – Vincenzo Aug 26 '18 at 16:44
  • @maddy. I edited the question. It should now make sense. – Vincenzo Aug 26 '18 at 17:22
  • @ Maddy. I did edit the question, and found the solution. Can you please delete the duplicate marking so I can answer the question?This is how I have set things up and works perfectly. ` let filterValue = Double(filterValueTextField.text!)! hcKalmanFilter?.rValue = filterValue let accuracy = Double(horizontalAccuracyTextField.text!)! guard let mostRecentLocation = locations.last else { return } guard mostRecentLocation.horizontalAccuracy > 0 else { return } guard mostRecentLocation.horizontalAccuracy < accuracy else { return }` – Vincenzo Aug 26 '18 at 21:53
  • I think the problem was that I was trying to do the value conversion from String coming from text label to Double right when I needed to use the Double value. but assigning the converted value to a new variable and use that as value for parameters fixed it. Could that be the cause of `Cannot invoke initializer for type 'Double' with an argument list of type '(String?)` error? – Vincenzo Aug 26 '18 at 21:57
  • Note that `guard let filterAmont:String?` is relatively meaningless, particularly in combination with `.text!`. Try deleting the `var filterValue` line and replace the whole guard line with `guard let filterAmount = filterValueTextField, let filterValue = Double(filterAmount) ?? 40.0 else { return }` – David Berry Aug 27 '18 at 21:33
  • @ David Berry. Hi and thank for answering, I thin I kind misled you with that 40 value. it's not needed anymore. Check my answer and see if you find any strange thing, I think I found the solution dough the resoults are not perfect yet. – Vincenzo Aug 29 '18 at 04:09

1 Answers1

0

So after all best practice advises and corrections the function is:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    let filterValue = Double(filterValueTextField.text!)!
    hcKalmanFilter?.rValue = filterValue

    let horizontalAccuracy = Double(horizontalAccuracyTextField.text!)!
    let verticalAccuracy = Double( verticalAccuracyTextField.text!)!

     // make sure to get last location
    guard let mostRecentLocation = locations.last else { return }
    //make sure that it's a valid gps signal ( vertical -1 = no gps triangulation )
    guard mostRecentLocation.horizontalAccuracy > 0 else { return }
    guard mostRecentLocation.verticalAccuracy > 0 else { return }

    // check angainst fine tuning parameters, filtering out locations with errors greater than values
    guard mostRecentLocation.horizontalAccuracy < horizontalAccuracy else { return }
    guard mostRecentLocation.verticalAccuracy < verticalAccuracy else { return }

    // passing the surviving locations to kalman filter for further filtering aiming for precision
    var myLocation: CLLocation = mostRecentLocation

    if hcKalmanFilter == nil {
        self.hcKalmanFilter = HCKalmanAlgorithm(initialLocation: myLocation)
    }
    else {
        if let hcKalmanFilter = self.hcKalmanFilter {
            if resetKalmanFilter == true {
                hcKalmanFilter.resetKalman(newStartLocation: myLocation)
                resetKalmanFilter = false
            }
            else {
                let kalmanLocation = hcKalmanFilter.processState(currentLocation: myLocation)
                self.actualRouteInUseCoordinatesArray.append(kalmanLocation.coordinate)
            }
        }
    }
}
Vincenzo
  • 5,304
  • 5
  • 38
  • 96