Skip to content

Commit

Permalink
NAVAND-1257 sticky charging stations for reroute (#7369)
Browse files Browse the repository at this point in the history
  • Loading branch information
VysotskiVadim authored Jul 20, 2023
1 parent f48723a commit 57dc9c5
Show file tree
Hide file tree
Showing 30 changed files with 107,786 additions and 9,582 deletions.
1 change: 1 addition & 0 deletions changelog/unreleased/features/7369.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Nav SDK now preserves charging stations after reroute.
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ class EVRerouteTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java)
private val initialInitialCharge = "18000"
private val initialAuxiliaryConsumption = "300"
private val initialEvPreconditioningTime = "10"
private val expectedStickyChargingStationsFromTheTestRoute = mapOf(
KEY_WAYPOINTS_STATION_ID to ";ocm-176357;",
KEY_WAYPOINTS_CURRENT_TYPE to ";dc;",
KEY_WAYPOINTS_POWER to ";300000;"
)

override fun setupMockLocation(): Location = mockLocationUpdatesRule.generateLocationUpdate {
latitude = twoCoordinates[0].latitude()
Expand Down Expand Up @@ -161,9 +166,8 @@ class EVRerouteTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java)
KEY_EV_INITIAL_CHARGE to initialInitialCharge,
KEY_AUXILIARY_CONSUMPTION to initialAuxiliaryConsumption,
KEY_EV_PRECONDITIONING_TIME to initialEvPreconditioningTime,
)
) + expectedStickyChargingStationsFromTheTestRoute
)
checkDoesNotHaveParameters(url1, userProvidedCpoiKeys)

val newInitialCharge = "17900"
val newRequestedRoutes = requestRoutes(
Expand All @@ -183,9 +187,11 @@ class EVRerouteTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java)
KEY_EV_INITIAL_CHARGE to newInitialCharge,
KEY_AUXILIARY_CONSUMPTION to initialAuxiliaryConsumption,
KEY_EV_PRECONDITIONING_TIME to initialEvPreconditioningTime,
)
KEY_WAYPOINTS_STATION_ID to ";ocm-176357;",
KEY_WAYPOINTS_CURRENT_TYPE to ";dc;",
KEY_WAYPOINTS_POWER to ";300000;"
) + expectedStickyChargingStationsFromTheTestRoute
)
checkDoesNotHaveParameters(url2, userProvidedCpoiKeys)
}

@Test
Expand Down Expand Up @@ -213,9 +219,9 @@ class EVRerouteTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java)
val url = routeHandler.handledRequests.last().requestUrl!!
checkHasParameters(
url,
evData + (KEY_ENGINE to VALUE_ELECTRIC)
evData + (KEY_ENGINE to VALUE_ELECTRIC) +
expectedStickyChargingStationsFromTheTestRoute
)
checkDoesNotHaveParameters(url, userProvidedCpoiKeys)
}

@Test
Expand Down Expand Up @@ -260,7 +266,6 @@ class EVRerouteTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java)
firstUrl,
firstEvData + (KEY_ENGINE to VALUE_ELECTRIC)
)
checkDoesNotHaveParameters(firstUrl, userProvidedCpoiKeys)

val newInitialCharge = "60"
mapboxNavigation.onEVDataUpdated(
Expand All @@ -281,7 +286,6 @@ class EVRerouteTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java)
KEY_EV_PRECONDITIONING_TIME to preconditioningTime,
)
)
checkDoesNotHaveParameters(urlWithTwiceUpdatedData, userProvidedCpoiKeys)

mapboxNavigation.onEVDataUpdated(emptyMap())
oldRequestsCount = routeHandler.handledRequests.size
Expand All @@ -299,14 +303,17 @@ class EVRerouteTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java)
KEY_EV_PRECONDITIONING_TIME to preconditioningTime,
)
)
checkDoesNotHaveParameters(urlAfterEmptyUpdate, userProvidedCpoiKeys)
}

@Test
fun ev_reroute_parameters_with_user_provided_cpoi_data() = sdkTest {
val stationPower = ";3000;6500"
val stationCurrentType = ";dc;dc"
val stationIds = ";ocm-176357;ocm-190632"
val userProvidedChargingStationsPower = ";3000;6500"
val userProvidedChargingStationsCurrentTypes = ";dc;dc"
val userProvidedChargingStationsIds = ";ocm-176357;ocm-190632"
// The SDK transforms server provided charging stations to user provided for stickiness
val expectedStationsPowerAfterReroute = ";3000;300000;6500"
val expectedChargingStationsCurrentTypesAfterReroute = ";dc;dc;dc"
val expectedChargingStationsIdsAfterReroute = ";ocm-176357;ocm-176357;ocm-190632"
val threeCoordinates = listOf(
Point.fromLngLat(11.585226, 48.176099),
Point.fromLngLat(11.063842, 48.39023),
Expand All @@ -325,15 +332,24 @@ class EVRerouteTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java)
val requestedRoutes = requestRoutes(
threeCoordinates,
electric = true,
stationPower = stationPower,
stationCurrentType = stationCurrentType,
stationIds = stationIds,
stationPower = userProvidedChargingStationsPower,
stationCurrentType = userProvidedChargingStationsCurrentTypes,
stationIds = userProvidedChargingStationsIds,
waypointsPerRoute = true,
)

mapboxNavigation.startTripSession()
stayOnPosition(threeCoordinates[0].latitude(), threeCoordinates[0].longitude(), 135f)
mapboxNavigation.setNavigationRoutesAndWaitForUpdate(requestedRoutes)

mockWebServerRule.requestHandlers.remove(routeHandler)
routeHandler = MockDirectionsRequestHandler(
"driving-traffic",
readRawFileText(activity, R.raw.ev_route_response_custom_station_data_reroute),
threeCoordinates,
relaxedExpectedCoordinates = true
)
mockWebServerRule.requestHandlers.add(routeHandler)
stayOnPosition(offRouteLocationUpdate.latitude, offRouteLocationUpdate.longitude)
waitForReroute()

Expand All @@ -342,9 +358,9 @@ class EVRerouteTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java)
url1,
mapOf(
KEY_ENGINE to VALUE_ELECTRIC,
KEY_WAYPOINTS_POWER to stationPower,
KEY_WAYPOINTS_CURRENT_TYPE to stationCurrentType,
KEY_WAYPOINTS_STATION_ID to stationIds,
KEY_WAYPOINTS_POWER to expectedStationsPowerAfterReroute,
KEY_WAYPOINTS_CURRENT_TYPE to expectedChargingStationsCurrentTypesAfterReroute,
KEY_WAYPOINTS_STATION_ID to expectedChargingStationsIdsAfterReroute,
)
)

Expand All @@ -361,9 +377,9 @@ class EVRerouteTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java)
url2,
mapOf(
KEY_ENGINE to VALUE_ELECTRIC,
KEY_WAYPOINTS_POWER to stationPower,
KEY_WAYPOINTS_CURRENT_TYPE to stationCurrentType,
KEY_WAYPOINTS_STATION_ID to stationIds,
KEY_WAYPOINTS_POWER to expectedStationsPowerAfterReroute,
KEY_WAYPOINTS_CURRENT_TYPE to expectedChargingStationsCurrentTypesAfterReroute,
KEY_WAYPOINTS_STATION_ID to expectedChargingStationsIdsAfterReroute,
)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package com.mapbox.navigation.instrumentation_tests.core

import android.location.Location
import com.mapbox.api.directions.v5.models.RouteOptions
import com.mapbox.navigation.base.route.RouterOrigin
import com.mapbox.navigation.base.utils.DecodeUtils.completeGeometryToPoints
import com.mapbox.navigation.core.directions.session.RoutesExtra
import com.mapbox.navigation.instrumentation_tests.utils.history.MapboxHistoryTestRule
import com.mapbox.navigation.instrumentation_tests.utils.location.stayOnPosition
import com.mapbox.navigation.instrumentation_tests.utils.routes.getChargingStationIds
import com.mapbox.navigation.instrumentation_tests.utils.withMapboxNavigation
import com.mapbox.navigation.testing.ui.BaseCoreNoCleanUpTest
import com.mapbox.navigation.testing.ui.utils.coroutines.getSuccessfulResultOrThrowException
import com.mapbox.navigation.testing.ui.utils.coroutines.requestRoutes
import com.mapbox.navigation.testing.ui.utils.coroutines.routeProgressUpdates
import com.mapbox.navigation.testing.ui.utils.coroutines.routesUpdates
import com.mapbox.navigation.testing.ui.utils.coroutines.sdkTest
import com.mapbox.navigation.testing.ui.utils.coroutines.setNavigationRoutesAsync
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import org.junit.Assert.assertEquals
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import java.net.URL

class EvAlternativesTest : BaseCoreNoCleanUpTest() {

@get:Rule
val mapboxHistoryTestRule = MapboxHistoryTestRule()

override fun setupMockLocation(): Location {
return mockLocationUpdatesRule.generateLocationUpdate {
longitude = 13.361378213031003
latitude = 52.49813341962201
}
}

@Test
@Ignore("used for semi manual testing")
fun startNavigationOfflineThenSwitchToOnlineRouteWhenInternetAppears() = sdkTest(
timeout = INCREASED_TIMEOUT_BECAUSE_OF_REAL_ROUTING_TILES_USAGE
) {
val testRouteOptions =
RouteOptions.fromUrl(
URL(
"https://api.mapbox.com/directions/v5/mapbox/" +
"driving-traffic/11.587428364032348,48.20148957377813" +
";11.81872714026062,50.67773738599428" +
";13.378818297105255,52.627628120089355" +
"?access_token=***&geometries=polyline6" +
"&alternatives=true&overview=full" +
"&steps=true&continue_straight=true&annotations=state_of_charge" +
"&roundabout_exits=true&voice_instructions=true" +
"&banner_instructions=true" +
"&enable_refresh=true&waypoints_per_route=true&engine=electric" +
"&ev_initial_charge=30000&ev_max_charge=50000" +
"&ev_connector_types=ccs_combo_type1%2Cccs_combo_type2" +
"&energy_consumption_curve=0%2C300%3B20%2C160%3B80%2C140%3B120%2C180" +
"&ev_charging_curve=" +
"0%2C100000%3B40000%2C70000%3B60000%2C30000%3B80000%2C10000" +
"&ev_min_charge_at_charging_station=7000&bearings=1,45;65,45;" +
"&radiuses=5;50;unlimited&waypoint_names=origin;test;destination" +
"&waypoint_targets=;;13.379077134850064,52.62734923825474" +
"&approaches=;curb;" +
"&layers=0;0;0&snapping_include_static_closures=true;false;true" +
"&snapping_include_closures=true;false;true&waypoints=0;1;2"
)
)
val origin = testRouteOptions.coordinatesList().first()
withMapboxNavigation(
historyRecorderRule = mapboxHistoryTestRule
) { navigation ->
navigation.registerRouteAlternativesObserver(
AdvancedAlternativesObserverFromDocumentation(navigation)
)
val requestResult = navigation.requestRoutes(testRouteOptions)
.getSuccessfulResultOrThrowException()
assertEquals(RouterOrigin.Offboard, requestResult.routerOrigin)

stayOnPosition(
latitude = origin.latitude(),
longitude = testRouteOptions.coordinatesList().first().longitude(),
0.0f,
) {
navigation.startTripSession()
navigation.setNavigationRoutesAsync(requestResult.routes)
}
val forkPoint =
navigation.getAlternativeMetadataFor(requestResult.routes[1])!!
.forkIntersectionOfPrimaryRoute.geometryIndexInRoute
val points = requestResult.routes.first().directionsRoute.completeGeometryToPoints()
val locationAfterAlternativeForkPoint = points[forkPoint + 10]

stayOnPosition(
latitude = locationAfterAlternativeForkPoint.latitude(),
longitude = locationAfterAlternativeForkPoint.longitude(),
bearing = 0f
) {
val onlineRoutes = navigation.routesUpdates().filter {
it.reason == RoutesExtra.ROUTES_UPDATE_REASON_ALTERNATIVE &&
it.navigationRoutes.first().origin ==
RouterOrigin.Offboard && it.navigationRoutes.size > 1
}.drop(1).first()
val routeProgress = navigation.routeProgressUpdates().first()
assertEquals(
onlineRoutes.navigationRoutes[1].getChargingStationIds()
.takeLast(routeProgress.remainingWaypoints),
requestResult.routes.first().getChargingStationIds()
.takeLast(routeProgress.remainingWaypoints)
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import com.mapbox.navigation.instrumentation_tests.utils.http.MockDirectionsRequ
import com.mapbox.navigation.instrumentation_tests.utils.location.stayOnPosition
import com.mapbox.navigation.instrumentation_tests.utils.routes.EvRoutesProvider
import com.mapbox.navigation.instrumentation_tests.utils.routes.MockedEvRoutes
import com.mapbox.navigation.instrumentation_tests.utils.routes.getChargingStationIds
import com.mapbox.navigation.instrumentation_tests.utils.routes.getChargingStationPowerCurrentTypes
import com.mapbox.navigation.instrumentation_tests.utils.routes.getChargingStationPowersKW
import com.mapbox.navigation.instrumentation_tests.utils.routes.getChargingStationTypes
import com.mapbox.navigation.instrumentation_tests.utils.tiles.OfflineRegions
import com.mapbox.navigation.instrumentation_tests.utils.tiles.withMapboxNavigationAndOfflineTilesForRegion
import com.mapbox.navigation.instrumentation_tests.utils.withMapboxNavigation
Expand Down Expand Up @@ -223,7 +227,7 @@ class EvOfflineTest : BaseCoreNoCleanUpTest() {
}

@Test
fun deviateFromOnlinePrimaryRouteWithoutInternet() = sdkTest(
fun deviateFromOnlinePrimaryRouteWithoutInternetAndGetBackOnline() = sdkTest(
timeout = INCREASED_TIMEOUT_BECAUSE_OF_REAL_ROUTING_TILES_USAGE
) {
val originalTestRoute = setupBerlinEvRoute()
Expand All @@ -233,6 +237,9 @@ class EvOfflineTest : BaseCoreNoCleanUpTest() {
OfflineRegions.Berlin,
historyRecorderRule = mapboxHistoryTestRule
) { navigation ->
navigation.registerRouteAlternativesObserver(
AdvancedAlternativesObserverFromDocumentation(navigation)
)
navigation.startTripSession()
val requestResult = navigation.requestRoutes(originalTestRoute.routeOptions)
.getSuccessfulResultOrThrowException()
Expand All @@ -242,7 +249,8 @@ class EvOfflineTest : BaseCoreNoCleanUpTest() {
listOf(3, 3),
requestResult.routes.map { it.waypoints?.size }
)
navigation.setNavigationRoutesAsync(requestResult.routes)
val initialOnlineRoutes = requestResult.routes
navigation.setNavigationRoutesAsync(initialOnlineRoutes)

withoutInternet {
stayOnPosition(
Expand All @@ -255,12 +263,68 @@ class EvOfflineTest : BaseCoreNoCleanUpTest() {
.first { it.reason == RoutesExtra.ROUTES_UPDATE_REASON_REROUTE }
assertEquals(RouterOrigin.Onboard, newRoutes.navigationRoutes.first().origin)
assertEquals(
"onboard router doesn't add waypoints",
newRoutes.navigationRoutes.map { 2 },
newRoutes.navigationRoutes.map { it.waypoints?.size }
"Fallback to offline navigation doesn't change a trip plan",
initialOnlineRoutes.first().waypoints?.map { it.location() }?.drop(1),
newRoutes.navigationRoutes.first().waypoints?.map { it.location() }?.drop(1)
)
assertEquals(
"Fallback to offline navigation doesn't change a trip plan",
initialOnlineRoutes.first().getChargingStationIds(),
newRoutes.navigationRoutes.first().getChargingStationIds()
)
assertEquals(
"Fallback to offline navigation doesn't change charging stations power",
initialOnlineRoutes.first().getChargingStationPowersKW(),
newRoutes.navigationRoutes.first().getChargingStationPowersKW()
)
assertEquals(
"Fallback to offline navigation doesn't " +
"change charging station current type",
initialOnlineRoutes.first().getChargingStationPowerCurrentTypes(),
newRoutes.navigationRoutes.first().getChargingStationPowerCurrentTypes()
)
assertEquals(
"Fallback to offline navigation doesn't change charging station type",
initialOnlineRoutes.first().getChargingStationTypes(),
newRoutes.navigationRoutes.first().getChargingStationTypes()
)
}
}
stayOnPosition(
// off route position
latitude = testRouteAfterReroute.origin.latitude(),
longitude = testRouteAfterReroute.origin.longitude(),
bearing = 280.0f
) {
val onlineRoutesUpdate = navigation.routesUpdates()
.first { it.navigationRoutes.first().origin == RouterOrigin.Offboard }
val onlineRoute = onlineRoutesUpdate.navigationRoutes.first()
assertEquals(
"Switch back to an online route doesn't change a trip plan",
initialOnlineRoutes.first().waypoints?.map { it.location() }?.drop(1),
onlineRoute.waypoints?.map { it.location() }?.drop(1)
)
assertEquals(
"Switch back to an online route doesn't change a trip plan",
initialOnlineRoutes.first().getChargingStationIds(),
onlineRoute.getChargingStationIds()
)
assertEquals(
"Switch back to an online route doesn't change charging stations power",
initialOnlineRoutes.first().getChargingStationPowersKW(),
onlineRoute.getChargingStationPowersKW()
)
assertEquals(
"Switch back to an online route doesn't change charging station current type",
initialOnlineRoutes.first().getChargingStationPowerCurrentTypes(),
onlineRoute.getChargingStationPowerCurrentTypes()
)
assertEquals(
"Switch back to an online route doesn't change charging station type",
initialOnlineRoutes.first().getChargingStationTypes(),
onlineRoute.getChargingStationTypes()
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ class WaypointsTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java)
@Test
fun leg_destination_ev_route() = sdkTest {
val coordinates = listOf(
Point.fromLngLat(48.39023, 11.063842),
Point.fromLngLat(49.164725, 10.340713)
Point.fromLngLat(11.063842, 48.39023),
Point.fromLngLat(10.340713, 49.164725)
)
addResponseHandler(R.raw.ev_route_response_for_refresh_with_2_waypoints, coordinates)
stayOnPosition(coordinates[0])
Expand Down
Loading

0 comments on commit 57dc9c5

Please sign in to comment.