Continuous replanning

VERSION 0.40.0
PUBLIC PREVIEW

The Navigation SDK for iOS is only available upon request. Contact us to get started.

Route update mode

This RouteReplanningEngineOptions.routeUpdateMode specifies whether the system should try to periodically update the active route and look for better route proposals.

There are two possible values:

By default, RouteReplanningEngineOptions.routeUpdateMode is set to RouteUpdateMode.enabled. It is configured in the following way:

1let routeReplanningEngineOptions = RouteReplanningEngineOptions(routeUpdateMode: .enabled)
2let routeReplanningEngine = TomTomRouteReplanningEngine(options: routeReplanningEngineOptions)
3
4let navigationConfiguration = OnlineTomTomNavigationFactory.Configuration(
5 locationProvider: locationEngine,
6 routeReplanner: routeReplanner,
7 apiKey: Keys.navigation,
8 routeReplanningEngine: routeReplanningEngine
9)
10
11let navigation = try OnlineTomTomNavigationFactory.create(configuration: navigationConfiguration)

Route refresh

When navigating a route, the road situation is constantly changing. As a result, the route data may become outdated during a trip. Route refresh provides users the most up-to-date route information such as:

  • Travel time and ETA (Estimated Time of Arrival)
  • Traffic information (delay and amount of traffic)
  • Updated legs and sections

Route refresh works only if RouteUpdateMode is set to RouteUpdateMode.enabled.

Route refresh might fail if the initial route planning was done with densely placed supporting points in comparison to route geometry. The replanning is made based on the geometry of the current route, where the density of coordinates may be lower.

Replanning response

The updated route is always automatically applied and the reason is set to RouteUpdatedReason.refresh.

Continuous replanning - finding better alternatives

To receive alternative route proposals, RouteUpdateMode must be set to RouteUpdateMode.enabled.

The search frequency for better route proposals is defined by the replanRouteInterval. Based on this interval, the Navigation module periodically attempts to find a better alternative to the current route. This is known as continuous replanning.

BetterProposalAcceptanceMode defines how a better route proposal is handled.

The TomTomRouteReplanningEngine provides a default RouteProposalSelector implementation for selecting the best route. This can be configured by setting the following fields in RouteReplanningEngineOptions:

By default, RouteReplanningEngineOptions.minTrafficDelay is set to ten (10) minutes and RouteReplanningEngineOptions.minTimeDifference to five (5) minutes.

1let routeReplanningEngineOptions = RouteReplanningEngineOptions(
2 routeUpdateMode: RouteReplanningEngineOptions.Defaults.routeUpdateMode,
3 minTrafficDelay: RouteReplanningEngineOptions.Defaults.minTrafficDelay,
4 minTimeDifference: RouteReplanningEngineOptions.Defaults.minTimeDifference
5)
6let routeReplanningEngine = TomTomRouteReplanningEngine(options: routeReplanningEngineOptions)
7
8let navigationConfiguration = OnlineTomTomNavigationFactory.Configuration(
9 locationProvider: locationEngine,
10 routeReplanner: routeReplanner,
11 apiKey: Keys.navigation,
12 routeReplanningEngine: routeReplanningEngine
13)
14
15let navigation = try OnlineTomTomNavigationFactory.create(configuration: navigationConfiguration)

Providing a custom RouteProposalSelector

If the default implementation of the RouteProposalSelector does not perform as you desire, you can provide your own object when creating the TomTomRouteReplanningEngine.

Note that it’s up to the provider of the custom route proposal selector to make sure that a reachable proposal is chosen whenever the current route has a blockage.

1let routeProposalSelector = CustomRouteProposalSelector()
2
3let routeReplanningEngine = TomTomRouteReplanningEngine(
4 options: routeReplanningEngineOptions,
5 routeProposalSelector: routeProposalSelector
6)
7
8let navigationConfiguration = OnlineTomTomNavigationFactory.Configuration(
9 locationProvider: locationEngine,
10 routeReplanner: routeReplanner,
11 apiKey: Keys.navigation,
12 routeReplanningEngine: routeReplanningEngine
13)
14
15let navigation = try OnlineTomTomNavigationFactory.create(configuration: navigationConfiguration)

Replanning response

A better route proposal can be selected both manually and automatically. A better route proposal is added to the navigation session with one of the following settings for `RouteReplanningReason':

Better proposal acceptance mode

There are three ways to handle a better route proposal:

Automatic mode is the default and can be changed by passing BetterProposalAcceptanceMode to the navigation configuration e.g., OnlineTomTomNavigationFactory.Configuration for online mode, during TomTomNavigation initialization.

1let navigationConfiguration = OnlineTomTomNavigationFactory.Configuration(
2 locationProvider: locationEngine,
3 routeReplanner: routeReplanner,
4 apiKey: Keys.navigation,
5 betterProposalAcceptanceMode: .automatic
6)
7
8let navigation = try OnlineTomTomNavigationFactory.create(configuration: navigationConfiguration)

Automatic handling

Replan proposals are applied automatically. The user is notified by the NavigationRouteAddObserver event NavigationRouteAddObserver.didAddRoute(route:options:reason:), which provides a Route, RoutePlanningOptions and a RouteAddedReason containing the reason the new route was added. The new route then becomes the active route and the NavigationActiveRouteChangeObserver notifies the user about the active route change.

1 let navigationConfiguration = OnlineTomTomNavigationFactory.Configuration(
2 locationProvider: locationEngine,
3 routeReplanner: routeReplanner,
4 apiKey: Keys.navigation,
5 betterProposalAcceptanceMode: .automatic
6 )
7
8 let navigation = try OnlineTomTomNavigationFactory.create(configuration: navigationConfiguration)
9
10func didAddRoute(route: Route, options: RoutePlanningOptions, reason: RouteAddedReason) {
11 /* YOUR CODE GOES HERE */
12}
13
14func didChangeActiveRoute(route: TomTomSDKRoute.Route) {
15 /* YOUR CODE GOES HERE */
16}

Unreachable only handling

Replan proposals are applied automatically only if there is a blockage on the current route or if the current route is not reachable due to insufficient battery charge (electric vehicles only). The user is notified by the NavigationRouteAddObserver event NavigationRouteAddObserver.didAddRoute(route:options:reason:). The proposed route then becomes the active route and the NavigationActiveRouteChangeObserver notifies the user about the active route change.

Manual handling

The user is notified of a better route proposal by the NavigationRouteAddObserver with the RouteAddedReason set to RouteAddedReason.betterRouteProposed. The better route proposal can be accepted using TomTomNavigation.selectActiveRoute(routeId:) method, after which, it becomes the active route. The NavigationActiveRouteChangeObserver notifies the user about the active route change.

1let routeReplanningEngineOptions = RouteReplanningEngineOptions(
2 routeReplanInterval: RouteReplanningEngineOptions.Defaults.replanInterval
3)
4let routeReplanningEngine = TomTomRouteReplanningEngine(options: routeReplanningEngineOptions)
5let navigationConfiguration = OnlineTomTomNavigationFactory.Configuration(
6 locationProvider: locationEngine,
7 routeReplanner: routeReplanner,
8 apiKey: Keys.navigation,
9 routeReplanningEngine: routeReplanningEngine,
10 betterProposalAcceptanceMode: .manual
11)
12
13let navigation = try OnlineTomTomNavigationFactory
14 .create(configuration: navigationConfiguration)
15
16navigation.addRouteAddObserver(self)
17navigation.addRouteRemoveObserver(self)
18navigation.addRouteUpdateObserver(self)
19navigation.addActiveRouteChangeObserver(self)

The Navigation supports decide-by-steering, which means that the driver can also select a better route proposal by steering into it. The system will detect the driver’s location on the proposed route and set it as active.

Specifying replanning intervals

By default, the intervals between route updates are set to five (5) minutes.

This can be set in RouteReplanningEngineOptions.

1let routeReplanningEngineOptions = RouteReplanningEngineOptions(
2 routeReplanInterval: Measurement.tt.minutes(5)
3)
4let routeReplanningEngine = TomTomRouteReplanningEngine(options: routeReplanningEngineOptions)
5
6let navigationConfiguration = OnlineTomTomNavigationFactory.Configuration(
7 locationProvider: locationEngine,
8 routeReplanner: routeReplanner,
9 apiKey: Keys.navigation,
10 routeReplanningEngine: routeReplanningEngine
11)
12
13let navigation = try OnlineTomTomNavigationFactory.create(configuration: navigationConfiguration)

Replanning on deviation

If a user has deviated from the current route, they will be informed by navigation. The navigation module may do one of the following things:

  • Automatically plan a new route.
  • Wait for the user to manually provide a new route.

Automatic handling

The default is to plan and apply a new route automatically. The user does not need to take any action.

To turn off automatic route planning, specify TomTomNavigation.deviationReplanningMode as DeviationReplanningMode.none using the OnlineTomTomNavigationFactory.Configuration.

1let navigationConfigurationNone = OnlineTomTomNavigationFactory.Configuration(
2 locationProvider: locationEngine,
3 routeReplanner: routeReplanner,
4 apiKey: Keys.navigation,
5 deviationReplanningMode: .none
6)

The NavigationRouteAddObserver notifies the user when the new route is added to the navigation session with RouteAddedReason.deviated as the reason for adding the new route. The NavigationActiveRouteChangeObserver then notifies the user about the active route change. When the new route becomes active the old route is removed from the navigation session. NavigationRouteRemoveObserver notifies the user about the removed route.

Route tracking engine

Deviation is not tracking a route.

To configure the route tracking engine, create a custom engine that implements the RouteTrackingEngine protocol and set this engine using the navigation OnlineTomTomNavigationFactory.Configuration.

1let navigationConfigurationNone = OnlineTomTomNavigationFactory.Configuration(
2 locationProvider: locationEngine,
3 routeReplanner: routeReplanner,
4 apiKey: Keys.navigation,
5 routeTrackingEngine: customEngine
6)

Replan retry policy

If the replanning is successful, the navigation module uses the returned route to replace the current one. Otherwise, the navigation module tries to replan the route again. The delay between retries are defined by the ReplanningRetryPolicy protocol.

Policy configuration

The default implementation of ReplanningRetryPolicy (to set up use ReplanningRetryPolicyFactory.create(maxRetryDelay:) with default values) periodically retries the operation with increasing delays between calls. The default maximum delay time is ten (10) seconds.

The default parameters can also be overridden as follows:

let customRetryPolicy = ReplanningRetryPolicyFactory.create(maxRetryDelay: maxDelay)

Once the policy is configured, it must be provided during initialization of the navigation module:

1let navigationConfigurationNone = OnlineTomTomNavigationFactory.Configuration(
2 locationProvider: locationEngine,
3 routeReplanner: routeReplanner,
4 apiKey: Keys.navigation,
5 routeDeviationReplanningRetryPolicy: customRetryPolicy
6)

Providing a custom replan retry policy

You can also provide your own implementation instead of using the default policy.

To do this, implement the ReplanningRetryPolicy protocol and pass it during the navigation module initialization.

Incremental guidance computation

If the Route.guidanceProgressOffset of the route is less than the Summary.length in the Route.summary, the route must be updated.

Instead of calling the [RoutePlanner.planRoute(options:onRouteReady:completion:) method, the replanning engine can call the RouteReplanner.advanceGuidanceProgress(_:) method.

This adds more instructions and corresponding lane guidance to the route and increases the Route.guidanceProgressOffset of the route.

Next steps

Since you have learned about route replanning, here are recommendations for the next steps: