Skip to content

Comments

Reroute when the user is moving away from maneuver#646

Merged
bsudekum merged 4 commits intomasterfrom
reroute-when-moving-away
Sep 22, 2017
Merged

Reroute when the user is moving away from maneuver#646
bsudekum merged 4 commits intomasterfrom
reroute-when-moving-away

Conversation

@bsudekum
Copy link
Contributor

If the user is moving away from the maneuver (whips a uturn on a country road half way down a step), we should reroute them once we know they are really moving away.

The gist:

  • Calculate distance to maneuver
  • add to an array
  • check the last distance in the array. If it's greater than the previous distance, add it
  • if this array grows to be greater than 3 distances, reroute.

/cc @1ec5 @frederoni @ericrwolfe


var hasFoundOneQualifiedLocation = false

var previousDistancesFromManeuver: [CLLocationDistance] = []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

recentDistancesFromManeuver makes it more clear that this isn’t a full history of distances.

}

func resetPreviousDistanceArray() {
previousDistancesFromManeuver.removeAll()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a separate method really needed for this statement? It looks like we’re calling it every time we touch routeProgress.currentLegProgress.stepIndex – maybe what this class needs is a property that mirrors routeProgress.currentLegProgress.stepIndex:

var currentStepIndex: Int {
    get {
        return routeProgress.currentLegProgress.stepIndex
    }
    set {
        routeProgress.currentLegProgress.stepIndex = newValue
        recentDistancesFromManeuver.removeAll()
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As much as I like this style, I don't like hiding routeProgress.currentLegProgress.stepIndex behind another var. I like explicitly changing values on routeProgress.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two alternatives:

  • Use KVO to observe for changes to the key path routeProgress.currentLegProgress and reset the array.
  • Listen for alert level change notifications and reset the array.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let userDistanceToManeuver = distance(along: coordinates, from: location.coordinate)

guard previousDistancesFromManeuver.count <= 3 else {
resetPreviousDistanceArray()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make it so that rerouting automatically calls this method, making this line redundant.


if previousDistancesFromManeuver.isEmpty {
previousDistancesFromManeuver.append(userDistanceToManeuver)
} else if let lastSpeed = previousDistancesFromManeuver.last, userDistanceToManeuver > lastSpeed {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we comparing distances or speeds?

if previousDistancesFromManeuver.isEmpty {
previousDistancesFromManeuver.append(userDistanceToManeuver)
} else if let lastSpeed = previousDistancesFromManeuver.last, userDistanceToManeuver > lastSpeed {
previousDistancesFromManeuver.append(userDistanceToManeuver)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RouteStepProgress.userDistanceToManeuverLocation already tracks the most recent distance, so all this class needs is to keep a counter of increasing distances: countOfRecentBackwardsUpdates or something along those lines.

Bobby Sudekum added 2 commits September 22, 2017 13:24
@bsudekum
Copy link
Contributor Author

@1ec5 updated.

@bsudekum
Copy link
Contributor Author

Note, this does not solve the case when the user is at the beginning of the route and moving away since distance along has a max value (length of the step). However, if the user is moving away from the departure maneuver, they should be rerouted quickly.


guard recentDistancesFromManeuver.count <= 3 else {
resetPreviousDistanceArray()
return false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


if recentDistancesFromManeuver.isEmpty {
recentDistancesFromManeuver.append(userDistanceToManeuver)
} else if let lastSpeed = recentDistancesFromManeuver.last, userDistanceToManeuver > lastSpeed {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

func resetPreviousDistanceArray() {
recentDistancesFromManeuver.removeAll()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bsudekum
Copy link
Contributor Author

@1ec5 👍 fixed

if let lastReroute = outstandingFeedbackEvents.map({$0 as? RerouteEvent }).last {
lastReroute?.update(newRoute: routeProgress.route)
}
recentDistancesFromManeuver.removeAll()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make a difference if this is in willReroute(notification:) or didReroute(notification:)? Wondering if there’s a possibility of a race condition if a location even more distant from the maneuver comes in while waiting for a response from the API.

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

Successfully merging this pull request may close these issues.

2 participants