diff --git a/evrouting/charge/routing.py b/evrouting/charge/routing.py index d1a57f0c57a9888ab7cb80f4a836391fc5fe6f2a..ce7bddc9d62dde0cfb2ee1e9d4f3d10d935be3e7 100644 --- a/evrouting/charge/routing.py +++ b/evrouting/charge/routing.py @@ -13,7 +13,7 @@ from math import inf import networkx as nx from evrouting.T import Node, SoC, Time, Result, EmptyResult, ConsumptionFunction from evrouting.utils import PriorityQueue -from evrouting.graph_tools import distance, consumption +from evrouting.graph_tools import distance, consumption, DISTANCE_KEY, CONSUMPTION_KEY from evrouting.charge.T import SoCFunction, Label from evrouting.charge.utils import LabelPriorityQueue from evrouting.charge.factories import ( @@ -161,7 +161,10 @@ def _setup(G: nx.Graph, charging_stations: Set[Node], capacity: SoC, # left at t (final_soc). The node becomes the new final node. dummy_final_node: Node = len(G) G.add_node(dummy_final_node) - G.add_edge(t, dummy_final_node, weight=0, c=final_soc) + G.add_edge(t, dummy_final_node, **{ + DISTANCE_KEY: 0, + CONSUMPTION_KEY: final_soc + }) t = dummy_final_node # Init factories diff --git a/evrouting/osm/imports.py b/evrouting/osm/imports.py index 9fdea4e7eeb92a360b031b4b9c0039d26b1b2c67..84b7e29ca21af32ff940fd12b3020fc8cc8efc7d 100644 --- a/evrouting/osm/imports.py +++ b/evrouting/osm/imports.py @@ -72,7 +72,7 @@ class OSMGraph(nx.DiGraph): lat = s['lat'] n = self.find_nearest((lat, lon), distance_limit=500) if n is not None: - self.nodes[n][CHARGING_COEFFICIENT_KEY] = s['power'] + self.nodes[n][CHARGING_COEFFICIENT_KEY] = s['power'] / 3.6 # in Wh/s S.add(n) self.charging_stations = S diff --git a/tests/osm/test_osm_charge.py b/tests/osm/test_osm_charge.py index dd598179d16e310ab86ce33f8a9758e8c70b69f9..f5b06efcc4bda4e2a1c14407032b42cc14f552ea 100644 --- a/tests/osm/test_osm_charge.py +++ b/tests/osm/test_osm_charge.py @@ -8,7 +8,7 @@ from evrouting.T import Result from evrouting.osm.imports import read_osm, OSMGraph, HAVERSINE_KEY from evrouting.osm.profiles import car from evrouting.osm.routing import shortest_path -from evrouting.graph_tools import CHARGING_COEFFICIENT_KEY, DISTANCE_KEY +from evrouting.graph_tools import CHARGING_COEFFICIENT_KEY, DISTANCE_KEY, CONSUMPTION_KEY @pytest.fixture @@ -99,6 +99,7 @@ def test_shortest_route_dimensions(map_graph): def test_charge_shortest_route_dimensions(map_graph): + """Full tank is enough to get there. Must be equal to shortest path.""" s = (51.75041438844966, 6.9332313537597665) t = (51.75657783347559, 7.000350952148438) _s = map_graph.find_nearest(s) @@ -109,7 +110,10 @@ def test_charge_shortest_route_dimensions(map_graph): def c(G, u, v): """Returns consumption in Wh from u to v.""" - return G[u][v][HAVERSINE_KEY] * consumption * 1000 + try: + return G[u][v][HAVERSINE_KEY] * consumption + except KeyError: + return G[u][v][CONSUMPTION_KEY] result = charge.routing.shortest_path( G=map_graph, @@ -122,4 +126,46 @@ def test_charge_shortest_route_dimensions(map_graph): c=c ) + path = shortest_path(map_graph, _s, _t, car) + + assert type(result) is Result + assert [n for n, t in result.charge_path] == path + + +def test_charge_shortest_route_stop(map_graph): + """Full tank is enough to get there. Must be equal to shortest path.""" + s = (51.75041438844966, 6.9332313537597665) + t = (51.75657783347559, 7.000350952148438) + _s = map_graph.find_nearest(s) + _t = map_graph.find_nearest(t) + + consumption = 1 # kWh/km + cost_path = 6 * consumption * 1000 # distance * consumption in Wh + + def c(G, u, v): + """Returns consumption in Wh from u to v.""" + try: + return G[u][v][HAVERSINE_KEY] * consumption + except KeyError: + return G[u][v][CONSUMPTION_KEY] + + result = charge.routing.shortest_path( + G=map_graph, + charging_stations=map_graph.charging_stations, + s=_s, + t=_t, + initial_soc=2000, # > cost_path + final_soc=0, + capacity=10000, + c=c + ) + assert type(result) is Result + charge_at = [t for n, t in result.charge_path if t > 0] + # charge once + assert len(charge_at) == 1 + + # Charge about 10 min + assert charge_at[0] < 600 + assert charge_at[0] > 500 +