Skip to content

Navigation For Electric Vehicles

This tutorial shows how to make great navigation experience for electric vehicles with navigation session.

Get started

The navigation session leverages the powerful cloud service of Trip Planner for electric vehicles to monitor the remaining battery during navigation. It provides notifications on insufficient battery and a new trip plan if possible.

Get a navigable EV trip plan

Use direction service to build an EV trip planning request and use it in navigation service to make a hybrid EV trip plan calculation.

1
2
3
// EV trip planning request is built with direction service
// use default hybrid EV trip planning configuration to create a task
const auto planningTask = navigationService->createNavigableEvTripPlanTask(planningRequest);

Hybrid EV trip planning configuration can be adjusted for each request.

// adjust hybrid EV trip planning configuration
tn::drive::api::HybridEvTripPlanningConfig planningConfig;
planningConfig.timeout_for_short_route = 2500;
planningConfig.timeout_for_medium_short_route = 3500;
planningConfig.timeout_for_medium_route = 5000;
planningConfig.timeout_for_medium_long_route = 8000;
planningConfig.timeout_for_long_route = 15000;
planningConfig.timeout_for_old_data_version = 15000;

// use customized hybrid EV trip planning configuration to create a task
const auto planningTask = navigationService->createNavigableEvTripPlanTask(planningRequest, planningConfig);

Check the estimated reachable distance from route to see if it's an EV trip planned offboard or an ordinary route calculated onboard.

// run hybrid routing task and handle the result
planningTask->runAsync([](
    tn::foundation::ErrorCode errorCode, tn::shared_ptr<tn::drive::api::NavigableEvTripPlanResponse> response)
{
    if (errorCode == tn::foundation::SDKError::OK && response)
    {
        const auto& routes = response->routes();

        for (const auto& route : routes)
        {
            if (route)
            {
                const auto estimatedReachableLength = route->estimatedReachableLength();
                if (estimatedReachableLength.has_value())
                {
                    // offboard EV trip planned route
                }
                else
                {
                    // onboard ordinary route
                }
            }
        }
    }
});

Use the route calculated above to start a navigation session from navigation service.

In-navigation range monitoring

The navigation session makes a periodic assessment of the remaining battery to make sure that the current charging plan is still valid. The periodic assessment is made every time X% of the available battery at the start of each leg is consumed (X is a configurable value, defaulting to 5, ranging from 2 to 30).

For example:
(with X = 5) 5% battery consumed compared to originally available battery level on each leg - If the available battery on leg departure is 80 KWh, navigation session will make assessments every 4 KWh consumed - If the available battery on leg departure is 30 Kwh, navigation session will make assessments every 1.5 KWh consumed

// adjust percentage of battery consumption to trigger assessment
auto settings = tn::foundation::Settings::Builder()
    .setString(tn::drive::api::SettingConstants::SETTING_NAVIGATION_BATTERY_CONSUMED_CHECK_PERCENT, "10")
    .build();

// create a navigation service options with navigation enabled
tn::drive::api::NavigationServiceOptions options;
options.enable_navigation = true;

// customized percentage will take effect in all navigation sessions created from this navigation service
const auto navigationService = tn::drive::api::NavigationServiceFactory::createNavigationService(
    options, system, settings, mapContent, directionService);

If the assessment result is that the remaining battery power is insufficient for the vehicle to reach the next planned charging station (if there's any) or destination (if there's no charging station along the route), a charging station unreachable event will be emitted in the navigation status update.

void NavigationObserver::onNavigationStatusUpdated(const tn::drive::models::v1::NavStatus& navStatus)
{
    const auto& unreachableSignal = navStatus.charging_station_unreachable_signal;
    if (unreachableSignal)
    {
        const auto& batteryLevelInfo = unreachableSignal->battery_level_info;

        // distance from current vehicle location (at the time point when checking) to the predicted location in meters
        // predicted location is upcoming charging station or destination (if there's no upcoming charging station)
        // it's the distance along the route
        const auto distanceToPredictedLocation = batteryLevelInfo.distance_to_predicted_location;

        // estimated travel distance in meters with remaining battery
        const auto estimatedTravelDistance = batteryLevelInfo.estimated_travel_distance;

        assert((distanceToPredictedLocation - estimatedTravelDistance) > std::numeric_limits<float>::epsilon());

        // show warning message about insufficient battery
    }
}

Trip plan for insufficient battery

With the insufficient battery detected, the navigation session will try to make a new trip plan.

void NavigationObserver::onNavigationRouteUpdating(
    const tn::drive::models::v1::BetterRouteUpdateProgress& progress)
{
    // omit other cases...
    else if (reason == tn::drive::models::v1::BetterRouteUpdateProgress::RouteUpdateReason::InsufficientBatteryLevel)
    {
        if (status == tn::drive::models::v1::BetterRouteUpdateProgress::RouteUpdateStatus::Succeeded)
        {
            updateRoute(progress);
        }
        else if (status == tn::drive::models::v1::BetterRouteUpdateProgress::RouteUpdateStatus::Failed)
        {
            // cannot get a new trip plan with the remaining battery
            // get estimated travel distance with remaining battery
            const auto& context = progress.route_update_context;
            const auto& batteryLevelInfo = context.battery_insufficient_info;
            const auto estimatedTravelDistance = batteryLevelInfo.estimated_travel_distance;

            // show warning message for trip plan failure
        }
    }
}

Charing station availability check

Besides the assessment of the remaining battery to reach the next planned charging station, the navigation session will periodically check the availability of the next planned charging station as well. In case it's not available before the vehicle arrives, e.g., all charging facilities are occupied, the navigation session will try to make a new trip plan and propose it to the user.

void NavigationObserver::onBetterRouteDetected(const tn::drive::models::v1::BetterRouteProposal& proposal)
{
    // omit other cases...
    else if (reason == tn::drive::models::v1::BetterRouteProposal::BetterRouteReason::ChargingStationUnavailable)
    {
        const auto& stationInfo = proposal.station_info;

        // entity id of the unavailable charging station
        const auto& stationId = stationInfo.station_id;

        // estimated travel time to the unavailable charging station
        const auto estimatedTravelTime = stationInfo.estimated_travel_time;

        // connector information of the unavailable charging station
        const auto& connectorsInfo = stationInfo.connector_info;

        // show messages about the unavailable charging station
        // and accepts the proposal if user takes it
        navigationSession->acceptRouteProposal(proposal);
    }
}

The availability check of an upcoming planned charging station is triggered if the estimated travel time to it is less than a configurable value. The default time is ten minutes.

// adjust remaining travel time to trigger charging station availability check
auto settings = tn::foundation::Settings::Builder()
    .setString(tn::drive::api::SettingConstants::SETTING_NAVIGATION_CHARGING_STATION_STATUS_CHECK_REMAINING_TIME, "900")
    .build();

// create a navigation service options with navigation enabled
tn::drive::api::NavigationServiceOptions options;
options.enable_navigation = true;

// customized remaining time will take effect in all navigation sessions created from this navigation service
const auto navigationService = tn::drive::api::NavigationServiceFactory::createNavigationService(
    options, system, settings, mapContent, directionService);

Update arrival battery

During driving, the estimated arrival battery may be out of data. The navigation will periodically(same time as range monitor assessment) check the arrival battery of the next charging station or destination.For the upcoming chargeable travel point, its charging duration is updated too.

void NavigationObserver::onNavigationStatusUpdated(const tn::drive::models::v1::NavStatus& navStatus)
{
    for (const auto& estimation : navStatus.travel_estimations)
    {
        if (estimation.arrival_battery.has_value())
        {
            showArrivalBatteryInfo(estimation.arrival_battery.value());
        }
    }
}

Resume EV trip plan

The client may get an onboard route when calculating EV route if no network connection or network error. The navigation component tries to switch to EV route when the network is good enough.

void NavigationObserver::onNavigationRouteUpdating(
    const tn::drive::models::v1::BetterRouteUpdateProgress& progress)
{
    // omit other cases...
    else if (reason == tn::drive::models::v1::BetterRouteUpdateProgress::RouteUpdateReason::ResumeEvTripPlan)
    {
        if (status == tn::drive::models::v1::BetterRouteUpdateProgress::RouteUpdateStatus::Succeeded)
        {
            updateRoute(progress);
        }
    }
}

Update EV route while the excessive battery is high enough

The vehicle may be charged to a higher level than planned in a planned station or even in a not planned station. In this case the navigation component will attempt to update the EV trip plan when the estimated arrival battery for the upcoming auto-planned station is higher than the original planned level.

void NavigationObserver::onNavigationRouteUpdating(
    const tn::drive::models::v1::BetterRouteUpdateProgress& progress)
{
    // omit other cases...
    else if (reason == tn::drive::models::v1::BetterRouteUpdateProgress::RouteUpdateReason::UpdateEvTripPlan)
    {
        if (status == tn::drive::models::v1::BetterRouteUpdateProgress::RouteUpdateStatus::Succeeded)
        {
            updateRoute(progress);
        }
    }
}

Arrival battery level for destination check

The navigation session will periodically check the arrival battery level for the remaining waypoints. When the destination is the checkpoint and its arrival battery level has dropped to a certain low level, the navigation session will try to make a new trip plan and propose it to the user.

1
2
3
4
5
6
7
8
9
void NavigationObserver::onBetterRouteDetected(const tn::drive::models::v1::BetterRouteProposal& proposal)
{
    // omit other cases...
    else if (reason == tn::drive::models::v1::BetterRouteProposal::BetterRouteReason::LowArrivalBatteryLevel)
    {
        // accepts the proposal if user takes it
        navigationSession->acceptRouteProposal(proposal);
    }
}