Planning a long-distance route with an electric vehicle

VERSION 0.45.0
PUBLIC PREVIEW

Electric vehicles (EVs) require special considerations related to energy consumption. We offer the following features:

  • Calculating the reachable offset along the route.
  • Calculating a long-distance EV route (LDEVR) that contains automatically added charging stops as waypoints to ensure that the destination is reachable while also minimizing the overall travel time.

Calculating the reachable offset along the route

Planning an EV route is similar to planning a regular route. To obtain reachability information, you must specify the RoutePlanningOptions. These RoutePlanningOptions must have a Vehicle profile with:

Then the route planner gives you a route where the Summary.reachableOffset field in the summary of the route is set. It estimates how far you can get with the current charge level. That could be the length of the whole route if it’s reachable or less than the length of the entire route if it’s not. The same method can be used with combustion engines, too.

Besides the previously mentioned electric engine parameters, it’s possible to specify the ElectricVehicleEfficiency. This helps the TomTom route planner provide more accurate estimates or arrival charges, though it is not required.

1let consumption: [Measurement<UnitSpeed>: Measurement<TTUnitElectricEfficiency>] = [
2 Measurement.tt.kilometersPerHour(0.0): Measurement.tt.kilowattHoursPer100Kilometers(13.44),
3 Measurement.tt.kilometersPerHour(50.0): Measurement.tt.kilowattHoursPer100Kilometers(16.4),
4 Measurement.tt.kilometersPerHour(80.0): Measurement.tt.kilowattHoursPer100Kilometers(18.8),
5 Measurement.tt.kilometersPerHour(120.0): Measurement.tt.kilowattHoursPer100Kilometers(19.65),
6 Measurement.tt.kilometersPerHour(170.0): Measurement.tt.kilowattHoursPer100Kilometers(21.1),
7]
8
9let electricVehicle: Car
10do {
11 electricVehicle = try Car(electricEngine: ElectricEngine(consumption: ElectricVehicleConsumption(
12 speedConsumption: consumption
13 ), chargeLevel: ChargeLevel(
14 currentCharge: Measurement.tt.kilowattHours(10),
15 maxCharge: Measurement.tt.kilowattHours(60)
16 )))
17} catch {
18 print("Invalid electic vehicle: \(error.localizedDescription)")
19 return
20}
21
22let amsterdam = CLLocationCoordinate2DMake(52.377956, 4.897070)
23let rotterdam = CLLocationCoordinate2DMake(51.926517, 4.462456)
24
25let routePlanningOptions: RoutePlanningOptions
26do {
27 routePlanningOptions = try RoutePlanningOptions(
28 itinerary: Itinerary(
29 origin: ItineraryPoint(coordinate: amsterdam),
30 destination: ItineraryPoint(coordinate: rotterdam)
31 ),
32 vehicle: electricVehicle
33 )
34} catch {
35 print("Invalid planning options: \(error.localizedDescription)")
36 return
37}

Calculating a long distance EV route

To obtain a route with automatically generated waypoints that contain charging information, you must:

Ensure that the battery curve map has no more than twenty (20) entries where all energy values must be greater or equal to zero while the power values must be greater than zero. Additionally, a battery curve without any entries is also considered valid. You should also make sure you are using plug types available in the region where you are trying to plan a route; otherwise, planning will fail.

1let consumption: [Measurement<UnitSpeed>: Measurement<TTUnitElectricEfficiency>] = [
2 Measurement.tt.kilometersPerHour(0.0): Measurement.tt.kilowattHoursPer100Kilometers(13.44),
3 Measurement.tt.kilometersPerHour(50.0): Measurement.tt.kilowattHoursPer100Kilometers(16.4),
4 Measurement.tt.kilometersPerHour(80.0): Measurement.tt.kilowattHoursPer100Kilometers(18.8),
5 Measurement.tt.kilometersPerHour(120.0): Measurement.tt.kilowattHoursPer100Kilometers(19.65),
6 Measurement.tt.kilometersPerHour(170.0): Measurement.tt.kilowattHoursPer100Kilometers(21.1),
7]
8
9let batteryCurve: [Measurement<UnitEnergy>: Measurement<UnitPower>] = [
10 Measurement.tt.kilowattHours(1): Measurement.tt.kilowatts(123),
11 Measurement.tt.kilowattHours(18): Measurement.tt.kilowatts(121),
12 Measurement.tt.kilowattHours(34): Measurement.tt.kilowatts(105),
13 Measurement.tt.kilowattHours(50.8): Measurement.tt.kilowatts(66),
14 Measurement.tt.kilowattHours(62.8): Measurement.tt.kilowatts(55.5),
15]
16
17let chargingConnectors: [ChargingConnector]
18do {
19 chargingConnectors = try [
20 ChargingConnector(currentType: CurrentType.acThreePhase, plugTypes: [.iec62196Type2Outlet]),
21 ChargingConnector(currentType: CurrentType.dc, plugTypes: [.iec62196Type2CCS]),
22 ]
23} catch {
24 print("Invalid charging connector: \(error.localizedDescription)")
25 return
26}
27
28let electricVehicle: Car
29do {
30 electricVehicle = try Car(electricEngine: ElectricEngine(consumption: ElectricVehicleConsumption(
31 speedConsumption: consumption
32 ), chargeLevel: ChargeLevel(
33 currentCharge: Measurement.tt.kilowattHours(10),
34 maxCharge: Measurement.tt.kilowattHours(60)
35 ), chargingParameters: ChargingParameters(
36 batteryCurve: batteryCurve, chargingConnectors: chargingConnectors
37 )))
38} catch {
39 print("Invalid electic vehicle: \(error.localizedDescription)")
40 return
41}

Make sure to use valid charging options:

  1. Minimum charge at a destination must be less than the maximum charge of the vehicle.
  2. Minimum charge at charging stops cannot be greater than half of the maximum charge of the vehicle (note that the first charging stop may have an arrival charge less than this value).
1let chargingOptions = ChargingOptions(
2 minChargeAtDestination: Measurement.tt.kilowattHours(5),
3 minChargeAtChargingStops: Measurement.tt.kilowattHours(10)
4)

Requesting the route

Once the charging options are set, a route can be planned synchronously or asynchronously, as is done with usual route planning requests.

1func planLongDistanceEVRoute(routePlanner: OnlineRoutePlanner, electricCarVehicleProfile: any Vehicle) {
2 let amsterdam = CLLocationCoordinate2DMake(52.377956, 4.897070)
3 let rotterdam = CLLocationCoordinate2DMake(51.926517, 4.462456)
4
5 let routePlanningOptions: RoutePlanningOptions
6 do {
7 routePlanningOptions = try RoutePlanningOptions(
8 itinerary: Itinerary(
9 origin: ItineraryPoint(coordinate: amsterdam),
10 destination: ItineraryPoint(coordinate: rotterdam)
11 ),
12 vehicle: electricCarVehicleProfile,
13 chargingOptions: chargingOptions
14 )
15 } catch {
16 print("Invalid planning options: \(error.localizedDescription)")
17 return
18 }
19
20 routePlanner.planRoute(options: routePlanningOptions, onRouteReady: nil) { result in
21 switch result {
22 case let .success(response):
23 if (response.routes?.first) != nil {
24 // success case
25 }
26 case .failure:
27 // failure case
28 break
29 }
30 }

Unsupported route planning options

The following options are not supported in Long Distance EV Routing:

Charging stops information in successfully computed route

The route contains charging stops as waypoints that have been added automatically based on the vehicle’s consumption and charging model. Charging stops contain additional information:

Next steps

Since you have learned how to plan EV routes, here are recommendations for the next steps: