Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: various changes required for ride-hailing #370

Merged
merged 8 commits into from
Jan 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -336,11 +336,13 @@ private void process(final VehicleTypesInitialization vehicleTypesInitialization
}

private void process(final VehicleRoutesInitialization vehicleRoutesInitialization) {
SimulationKernel.SimulationKernel.getRoutes().putAll(vehicleRoutesInitialization.getRoutes());
for (var routeEntry : vehicleRoutesInitialization.getRoutes().entrySet()) {
SimulationKernel.SimulationKernel.registerRoute(routeEntry.getKey(), routeEntry.getValue());
}
}

private void process(final VehicleRouteRegistration vehicleRouteRegistration) {
SimulationKernel.SimulationKernel.getRoutes().put(vehicleRouteRegistration.getRoute().getId(), vehicleRouteRegistration.getRoute());
SimulationKernel.SimulationKernel.registerRoute(vehicleRouteRegistration.getRoute().getId(), vehicleRouteRegistration.getRoute());
}

private void process(final RsuRegistration rsuRegistration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.FileAppender;
import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import org.apache.commons.lang3.Validate;
import org.slf4j.LoggerFactory;

import java.io.File;
Expand Down Expand Up @@ -270,17 +271,17 @@ public CentralPerceptionComponent getCentralPerceptionComponent() {
*/
@Nonnull
public Map<String, VehicleRoute> getRoutes() {
return routes;
return Collections.unmodifiableMap(routes);
}

/**
* Returns a view for the {@link #routes}.
* Registers a new route to the simulation kernel.
*
* @return a view for the {@link #routes}.
* @param id the id of the route
* @param route the {@link VehicleRoute} to register
*/
@Nonnull
public Map<String, VehicleRoute> getRoutesView() {
return routesView;
public void registerRoute(String id, VehicleRoute route) {
routes.put(id, Validate.notNull(route, "The given route must not be null."));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
Expand Down Expand Up @@ -85,11 +84,6 @@ public class CentralNavigationComponent {
*/
private Routing routing;

/**
* Map storing all known route IDs with the belonging route.
*/
private Map<String, VehicleRoute> routeMap = new HashMap<>();

/**
* The configuration for routingAPI.
*/
Expand Down Expand Up @@ -134,7 +128,10 @@ public void initialize(RtiAmbassador rtiAmbassador) throws InternalFederateExcep
this.log.info("CNC - Navigation-System initialized");

try {
routeMap = routing.getRoutesFromDatabaseForMessage();
final Map<String, VehicleRoute> routeMap = routing.getRoutesFromDatabaseForMessage();
for (var routeEntry: routeMap.entrySet()) {
SimulationKernel.SimulationKernel.registerRoute(routeEntry.getKey(), routeEntry.getValue());
}

// generate VehicleRoutesInitialization to inform other simulators
VehicleRoutesInitialization interaction = new VehicleRoutesInitialization(0, routeMap);
Expand All @@ -151,6 +148,10 @@ public void initialize(RtiAmbassador rtiAmbassador) throws InternalFederateExcep
}
}

private Map<String, VehicleRoute> getAllRoutes() {
return SimulationKernel.SimulationKernel.getRoutes();
}

Routing createFromType(String type) throws InternalFederateException {
if (type == null || "database".equalsIgnoreCase(type) || "graphhopper".equalsIgnoreCase(type)) {
return new DatabaseRouting();
Expand Down Expand Up @@ -202,8 +203,8 @@ public VehicleRoute switchRoute(VehicleData vehicleData, CandidateRoute rawRoute
// — first check if already a route exists
// — generate a complete route with an ID and propagate it
VehicleRoute knownRoute = null;
for (VehicleRoute route : routeMap.values()) {
newRouteOnOriginalRoute = isNewRouteOnOriginalRoute(rawRoute.getConnectionIds(), routeMap.get(route.getId()).getConnectionIds());
for (VehicleRoute route : getAllRoutes().values()) {
newRouteOnOriginalRoute = isNewRouteOnOriginalRoute(rawRoute.getConnectionIds(), getAllRoutes().get(route.getId()).getConnectionIds());
if (newRouteOnOriginalRoute) {
knownRoute = route;
break;
Expand Down Expand Up @@ -261,9 +262,9 @@ private VehicleRoute requestStaticRouteChange(VehicleData vehicleData, VehicleRo
* @return {@link GeoPoint}-target of the given route, {@code null} if route doesn't exist.
*/
GeoPoint getTargetPositionOfRoute(String routeId) {
if (routeMap.containsKey(routeId)) {
String lastNodeId = Iterables.getLast(routeMap.get(routeId).getNodeIds(), null);
return getPositionOfNode(lastNodeId);
if (getAllRoutes().containsKey(routeId)) {
String lastConnectionId = Iterables.getLast(getAllRoutes().get(routeId).getConnectionIds(), null);
return routing.getConnection(lastConnectionId).getEndNode().getPosition();
schwepmo marked this conversation as resolved.
Show resolved Hide resolved
} else {
return null;
}
Expand All @@ -276,9 +277,9 @@ GeoPoint getTargetPositionOfRoute(String routeId) {
* @return {@link GeoPoint}-target of the given route, {@code null} if route doesn't exist.
*/
public GeoPoint getSourcePositionOfRoute(String routeId) {
if (routeMap.containsKey(routeId)) {
String firstNodeId = Iterables.getFirst(routeMap.get(routeId).getNodeIds(), null);
return getPositionOfNode(firstNodeId);
if (getAllRoutes().containsKey(routeId)) {
String firstConnectionId = Iterables.getFirst(getAllRoutes().get(routeId).getConnectionIds(), null);
return routing.getConnection(firstConnectionId).getStartNode().getPosition();
} else {
return null;
}
Expand Down Expand Up @@ -321,7 +322,7 @@ private GeoPoint getPositionOfNode(String nodeId) {
* @throws InternalFederateException If the {@link Interaction} could not be send.
*/
private void propagateRoute(VehicleRoute newRoute, long time) throws InternalFederateException {
if (routeMap.containsKey(newRoute.getId())) {
if (getAllRoutes().containsKey(newRoute.getId())) {
throw new InternalFederateException(
String.format("Route %s is already known but is tried to be propagated, which is not allowed.", newRoute.getId())
);
Expand All @@ -331,7 +332,7 @@ private void propagateRoute(VehicleRoute newRoute, long time) throws InternalFed
try {
this.rtiAmbassador.triggerInteraction(interaction);
// store route in local map
routeMap.put(newRoute.getId(), newRoute);
SimulationKernel.SimulationKernel.registerRoute(newRoute.getId(), newRoute);
} catch (IllegalValueException e) {
throw new InternalFederateException(e);
}
Expand Down Expand Up @@ -385,7 +386,7 @@ public VehicleDeparture createRouteForOdInfo(long time, OriginDestinationPair od
// check if best route, matches one of the existing routes and if so choose that existing route
if (response.getBestRoute() != null) {
VehicleRoute route = null;
for (VehicleRoute existingRoute : routeMap.values()) {
for (VehicleRoute existingRoute : getAllRoutes().values()) {
if (isNewRouteOnOriginalRoute(response.getBestRoute().getConnectionIds(), existingRoute.getConnectionIds())) {
route = existingRoute;
break;
Expand Down Expand Up @@ -456,7 +457,7 @@ public IRoadPosition refineRoadPosition(IRoadPosition roadPosition) {
if (finalNode == null) {
throw new IllegalArgumentException("finalNode is null.");
}
List<String> currentRouteNodes = routeMap.get(routeId).getNodeIds();
List<String> currentRouteNodes = getAllRoutes().get(routeId).getNodeIds();

if (!currentRouteNodes.contains(finalNode)) {
return Double.POSITIVE_INFINITY;
Expand Down Expand Up @@ -485,7 +486,7 @@ public IRoadPosition refineRoadPosition(IRoadPosition roadPosition) {
* @return A node if a valid one is found, otherwise {@code null}.
*/
INode getNextNodeOnRoute(String routeId, IRoadPosition roadPosition, Predicate<INode> nodeCondition) {
VehicleRoute currentRoute = routeMap.get(routeId);
VehicleRoute currentRoute = getAllRoutes().get(routeId);

int indexOfUpcomingNode = currentRoute.getNodeIds().indexOf(roadPosition.getUpcomingNode().getId());
// check if there is an upcoming node
Expand All @@ -505,12 +506,12 @@ INode getNextNodeOnRoute(String routeId, IRoadPosition roadPosition, Predicate<I
}

/**
* Returns an unmodifiable view of {@link #routeMap}.
* Returns an unmodifiable view of {@link #getAllRoutes()}.
*
* @return unmodifiable view of {@link #routeMap}
* @return unmodifiable view of {@link #getAllRoutes()}
*/
Map<String, VehicleRoute> getRouteMap() {
return Collections.unmodifiableMap(routeMap);
return Collections.unmodifiableMap(getAllRoutes());
kschrab marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.eclipse.mosaic.fed.application.ambassador.navigation;

import org.eclipse.mosaic.lib.geo.GeoPoint;
import org.eclipse.mosaic.lib.objects.road.IConnection;
import org.eclipse.mosaic.lib.objects.road.INode;
import org.eclipse.mosaic.lib.objects.road.IRoadPosition;
import org.eclipse.mosaic.lib.objects.vehicle.VehicleData;
Expand Down Expand Up @@ -140,6 +141,14 @@ public interface INavigationModule {
*/
INode getNode(String node);

/**
* Returns data for the specified connection id.
*
* @param connection the id of the node
* @return the {@link IConnection} containing data for the specified connection id.
*/
IConnection getConnection(String connection);

/**
* Returns the node which is closest to specified {@link GeoPoint}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.eclipse.mosaic.fed.application.ambassador.navigation;

import org.eclipse.mosaic.lib.geo.GeoPoint;
import org.eclipse.mosaic.lib.objects.road.IConnection;
import org.eclipse.mosaic.lib.objects.road.INode;
import org.eclipse.mosaic.lib.objects.road.IRoadPosition;
import org.eclipse.mosaic.lib.routing.RoutingParameters;
Expand Down Expand Up @@ -45,6 +46,14 @@ public interface IRoutingModule {
*/
INode getNode(String nodeId);

/**
* Returns data for the specified connection id.
*
* @param connection the id of the node
* @return the {@link IConnection} containing data for the specified connection id.
*/
IConnection getConnection(String connection);

/**
* Returns the node object, which is closest to the given {@link GeoPoint}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.eclipse.mosaic.fed.application.ambassador.SimulationKernel;
import org.eclipse.mosaic.fed.application.ambassador.simulation.AbstractSimulationUnit;
import org.eclipse.mosaic.lib.geo.GeoPoint;
import org.eclipse.mosaic.lib.objects.road.IConnection;
import org.eclipse.mosaic.lib.objects.road.INode;
import org.eclipse.mosaic.lib.objects.road.IRoadPosition;
import org.eclipse.mosaic.lib.objects.vehicle.VehicleData;
Expand Down Expand Up @@ -122,6 +123,7 @@ public boolean switchRoute(CandidateRoute newRoute) {
"NavigationModule#switchRoute: Could not switch to candidate route[{}]",
StringUtils.join(newRoute.getConnectionIds(), ",")
);
belongingUnit.getOsLog().error("Reason", e);
return false;
}
}
Expand Down Expand Up @@ -270,6 +272,11 @@ public INode getNode(String nodeId) {
return SimulationKernel.SimulationKernel.getCentralNavigationComponent().getRouting().getNode(nodeId);
}

@Override
public IConnection getConnection(String connectionId) {
return SimulationKernel.SimulationKernel.getCentralNavigationComponent().getRouting().getConnection(connectionId);
}

@Override
public INode getClosestNode(GeoPoint geoPoint) {
return SimulationKernel.SimulationKernel.getCentralNavigationComponent().getRouting().findClosestNode(geoPoint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -687,8 +687,8 @@ public void processInteraction_VehicleRoutesInitialization() throws InternalFede
ambassador.processInteraction(vehicleRoutesInitialization);

// ASSERT: vehicles routes have been propagated
assertEquals(routes.get("0"), SimulationKernel.SimulationKernel.getRoutesView().get("0"));
assertEquals(routes.get("1"), SimulationKernel.SimulationKernel.getRoutesView().get("1"));
assertEquals(routes.get("0"), SimulationKernel.SimulationKernel.getRoutes().get("0"));
assertEquals(routes.get("1"), SimulationKernel.SimulationKernel.getRoutes().get("1"));

// finish simulation
ambassador.processTimeAdvanceGrant(recentAdvanceTime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
Expand All @@ -35,8 +37,9 @@
import org.eclipse.mosaic.interactions.traffic.VehicleRoutesInitialization;
import org.eclipse.mosaic.interactions.vehicle.VehicleRouteChange;
import org.eclipse.mosaic.interactions.vehicle.VehicleRouteRegistration;
import org.eclipse.mosaic.lib.database.road.Node;
import org.eclipse.mosaic.lib.geo.GeoPoint;
import org.eclipse.mosaic.lib.objects.road.IConnection;
import org.eclipse.mosaic.lib.objects.road.INode;
import org.eclipse.mosaic.lib.objects.vehicle.VehicleData;
import org.eclipse.mosaic.lib.objects.vehicle.VehicleRoute;
import org.eclipse.mosaic.lib.routing.CandidateRoute;
Expand All @@ -46,7 +49,6 @@
import org.eclipse.mosaic.lib.routing.RoutingPosition;
import org.eclipse.mosaic.lib.routing.RoutingRequest;
import org.eclipse.mosaic.lib.routing.config.CRouting;
import org.eclipse.mosaic.lib.routing.database.LazyLoadingNode;
import org.eclipse.mosaic.lib.routing.norouting.NoRouting;
import org.eclipse.mosaic.rti.TIME;
import org.eclipse.mosaic.rti.api.IllegalValueException;
Expand All @@ -59,7 +61,6 @@
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -132,11 +133,10 @@ public void initialize_vehicleRoutesInitializationSent() throws InternalFederate
public void getTargetPositionOfRoute() throws InternalFederateException {
//PREPARE
cnc.initialize(rtiAmbassadorMock);
when(routingMock.getNode(Mockito.eq("1"))).thenReturn(new LazyLoadingNode(new Node("1", GeoPoint.lonLat(1, 1))));
when(routingMock.getNode(Mockito.eq("2"))).thenReturn(new LazyLoadingNode(new Node("2", GeoPoint.lonLat(2, 2))));
when(routingMock.getNode(Mockito.eq("3"))).thenReturn(new LazyLoadingNode(new Node("3", GeoPoint.lonLat(3, 3))));
when(routingMock.getNode(Mockito.eq("4"))).thenReturn(new LazyLoadingNode(new Node("4", GeoPoint.lonLat(4, 4))));

doReturn(createConnectionMock(GeoPoint.lonLat(1, 1))).when(routingMock).getConnection(eq("1_1_2_1"));
doReturn(createConnectionMock(GeoPoint.lonLat(2, 2))).when(routingMock).getConnection(eq("3_2_5_2"));
doReturn(createConnectionMock(GeoPoint.lonLat(3, 3))).when(routingMock).getConnection(eq("2_2_4_2"));
doReturn(createConnectionMock(GeoPoint.lonLat(4, 4))).when(routingMock).getConnection(eq("2_2_4_3"));

// RUN + ASSERT (Last node of route "0" = 4)
final GeoPoint gpEndOf0 = cnc.getTargetPositionOfRoute("0");
Expand All @@ -155,6 +155,13 @@ public void getTargetPositionOfRoute() throws InternalFederateException {
assertNull(gpEndOf2);
}

private IConnection createConnectionMock(GeoPoint endPoint) {
IConnection connection = mock(IConnection.class);
when(connection.getEndNode()).thenReturn(mock(INode.class));
when(connection.getEndNode().getPosition()).thenReturn(endPoint);
return connection;
}

@Test
public void findRoutes_requestRoutesOnly_noRouteChangeInitiated() throws InternalFederateException, IllegalValueException {
// PREPARE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,11 +301,13 @@ private void addNotYetAddedVehicles(long time) throws InternalFederateException

bridge.getSimulationControl().addVehicle(vehicleId, routeId, vehicleType, laneId, departPos, departSpeed);

applyChangesInVehicleTypeForVehicle(
vehicleId,
vehicleRegistration.getMapping().getVehicleType(),
cachedVehicleTypesInitialization.getTypes().get(vehicleType)
);
final VehicleType cachedType = cachedVehicleTypesInitialization.getTypes().get(vehicleType);
if (cachedType != null) {
applyChangesInVehicleTypeForVehicle(vehicleId, vehicleRegistration.getMapping().getVehicleType(), cachedType);
} else {
log.warn("Unknown vehicle type {}. Ensure that a suitable vType is configured in the SUMO configuration.", vehicleType);
}

if (externalVehicleState != null) {
externalVehicleState.setAdded(true);
}
Expand Down Expand Up @@ -359,7 +361,6 @@ private void subscribeToNotYetSubscribedVehicles(long time) throws InternalFeder
iterator.remove();
}
}

}

private void applyChangesInVehicleTypeForVehicle(String vehicleId, VehicleType actualVehicleType, VehicleType baseVehicleType) throws InternalFederateException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public Aggregator() {
}

public Aggregator add(double value) {
if (Double.isNaN(value)) {
return this;
}

min = Math.min(min, value);
max = Math.max(max, value);
sum += value;
Expand Down
Loading
Loading