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(perception): simplified configuration for perception index #351

Merged
merged 12 commits into from
Oct 4, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"messageCacheTime": "30s",
"encodePayloads": true,
"eventSchedulerThreads": 1,
"navigationConfiguration": {
"type": "database"
},
"perceptionConfiguration": {
"vehicleIndex": {
"enabled": true
},
"trafficLightIndex": {
"enabled": true
},
"wallIndex": {
"enabled": false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,10 @@ this, new StartApplications(chargingStationUnit.getId(), chargingStationRegistra
* @param trafficLightRegistration traffic light
*/
public void registerTrafficLight(TrafficLightRegistration trafficLightRegistration) {
if (!trafficLightRegistration.getMapping().hasApplication()
&& SimulationKernel.SimulationKernel.getConfiguration().perceptionConfiguration.trafficLightIndex == null) {
// if traffic light index is enabled, we need traffic light state information for all traffic lights via subscriptions
boolean isTrafficLightIndexEnabled = SimulationKernel.SimulationKernel.getConfiguration().perceptionConfiguration.trafficLightIndex != null &&
SimulationKernel.SimulationKernel.getConfiguration().perceptionConfiguration.trafficLightIndex.enabled;
if (!trafficLightRegistration.getMapping().hasApplication() && !isTrafficLightIndexEnabled) {
kschrab marked this conversation as resolved.
Show resolved Hide resolved
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,13 @@ public VehicleUnit(String vehicleName, VehicleType vehicleType, final GeoPoint i
.getCentralNavigationComponent().getRouting()).getScenarioDatabase();
}

if (SimulationKernel.SimulationKernel.getConfiguration().perceptionConfiguration.vehicleIndex != null) {
perceptionModule = SimulationKernel.SimulationKernel.getConfiguration().perceptionConfiguration.vehicleIndex
.createPerceptionModule(this, database, getOsLog());
if (SimulationKernel.SimulationKernel.getCentralPerceptionComponent().getTrafficObjectIndex() != null) {
perceptionModule = SimulationKernel.SimulationKernel.getCentralPerceptionComponent()
.getTrafficObjectIndex().createPerceptionModule(this, database, getOsLog());
} else {
perceptionModule = new NopPerceptionModule(this, database, getOsLog());
}

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,21 @@

import org.eclipse.mosaic.fed.application.ambassador.SimulationKernel;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.TrafficObjectIndex;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.objects.TrafficLightObject;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.objects.VehicleObject;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.providers.TrafficLightMap;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.providers.VehicleMap;
import org.eclipse.mosaic.fed.application.config.CApplicationAmbassador;
import org.eclipse.mosaic.fed.application.config.CPerception;
import org.eclipse.mosaic.interactions.traffic.TrafficLightUpdates;
import org.eclipse.mosaic.interactions.traffic.VehicleUpdates;
import org.eclipse.mosaic.lib.database.Database;
import org.eclipse.mosaic.lib.geo.CartesianRectangle;
import org.eclipse.mosaic.lib.math.Vector3d;
import org.eclipse.mosaic.lib.objects.trafficlight.TrafficLightGroup;
import org.eclipse.mosaic.lib.objects.trafficlight.TrafficLightGroupInfo;
import org.eclipse.mosaic.lib.objects.vehicle.VehicleData;
import org.eclipse.mosaic.lib.objects.vehicle.VehicleType;
import org.eclipse.mosaic.lib.routing.Routing;
import org.eclipse.mosaic.lib.spatial.Edge;
import org.eclipse.mosaic.lib.util.PerformanceMonitor;
import org.eclipse.mosaic.rti.api.InternalFederateException;

import com.google.common.collect.Iterables;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
* The {@link CentralPerceptionComponent} is responsible for keeping a spatial index of all vehicles,
* which allows fast querying of nearby vehicles.
Expand All @@ -57,7 +44,7 @@ public class CentralPerceptionComponent {
/**
* Configuration containing parameters for setting up the spatial indexes.
*/
private final CApplicationAmbassador.CPerception configuration;
private final CPerception configuration;

/**
* The spatial index used to store and find objects by their positions.
Expand All @@ -84,7 +71,7 @@ public class CentralPerceptionComponent {
*/
private boolean updateTrafficLightIndex = false;

public CentralPerceptionComponent(CApplicationAmbassador.CPerception perceptionConfiguration) {
public CentralPerceptionComponent(CPerception perceptionConfiguration) {
this.configuration = Validate.notNull(perceptionConfiguration, "perceptionConfiguration must not be null");
}

Expand All @@ -99,38 +86,21 @@ public void initialize() throws InternalFederateException {
// evaluate bounding box for perception
scenarioBounds = configuration.perceptionArea == null
? routing.getScenarioBounds() : configuration.perceptionArea.toCartesian();
// see what backends are configured
boolean vehicleIndexConfigured = configuration.vehicleIndex != null;
boolean trafficLightIndexConfigured = configuration.trafficLightIndex != null;

TrafficObjectIndex.Builder indexBuilder = new TrafficObjectIndex.Builder(LOG);
if (scenarioBounds.getArea() <= 0) {
LOG.warn("The bounding area of the scenario could not be determined. Defaulting to low performance spatial index.");
if (vehicleIndexConfigured) { // if configured default to map index
indexBuilder.withVehicleIndex(new VehicleMap());
}
if (trafficLightIndexConfigured) { // if configured default to map index
indexBuilder.withTrafficLightIndex(new TrafficLightMap());
}
} else {
if (vehicleIndexConfigured) {
indexBuilder.withVehicleIndex(configuration.vehicleIndex);
}
if (trafficLightIndexConfigured) {
indexBuilder.withTrafficLightIndex(configuration.trafficLightIndex);
}
if (configuration.vehicleIndex != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We lost the validation of the scenarioBounds here, but maybe this isn't really necessary in the first place

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I also didn't see the reason for this check.

indexBuilder.withVehicleIndex(configuration.vehicleIndex.create());
}
if (configuration.trafficLightIndex != null) {
indexBuilder.withTrafficLightIndex(configuration.trafficLightIndex.create());
}
if (routing instanceof Database) {
Database dbRouting = (Database) routing;
if (!dbRouting.getBuildings().isEmpty()) {
indexBuilder.withWallIndex(configuration.wallIndex, (Database) routing);
if (!dbRouting.getBuildings().isEmpty() && configuration.wallIndex != null) {
indexBuilder.withWallIndex(configuration.wallIndex.create(), (Database) routing);
}
}
trafficObjectIndex = indexBuilder.build();

if (configuration.measurePerformance) {
trafficObjectIndex = new MonitoringTrafficObjectIndexProvider(trafficObjectIndex, PerformanceMonitor.getInstance());
}
} catch (Exception e) {
throw new InternalFederateException("Couldn't initialize CentralPerceptionComponent", e);
}
Expand Down Expand Up @@ -212,63 +182,4 @@ public void updateTrafficLights(TrafficLightUpdates trafficLightUpdates) {
updateTrafficLightIndex = true;
}

/**
* Wrapper class to measure atomic calls of update, search and remove of the used spatial index.
*/
static class MonitoringTrafficObjectIndexProvider extends TrafficObjectIndex {
private final PerformanceMonitor monitor;

MonitoringTrafficObjectIndexProvider(TrafficObjectIndex parent, PerformanceMonitor monitor) {
super(parent);
this.monitor = monitor;
}

@Override
public List<VehicleObject> getVehiclesInRange(PerceptionModel searchRange) {
try (PerformanceMonitor.Measurement m = monitor.start("search-vehicle")) {
m.setProperties(getNumberOfVehicles(), SimulationKernel.SimulationKernel.getCurrentSimulationTime()).restart();
return super.getVehiclesInRange(searchRange);
}
}

@Override
public void removeVehicles(Iterable<String> vehiclesToRemove) {
try (PerformanceMonitor.Measurement m = monitor.start("remove-vehicle")) {
m.setProperties(getNumberOfVehicles(), SimulationKernel.SimulationKernel.getCurrentSimulationTime()).restart();
super.removeVehicles(vehiclesToRemove);
}
}

@Override
public void updateVehicles(Iterable<VehicleData> vehiclesToUpdate) {
try (PerformanceMonitor.Measurement m = monitor.start("update-vehicle")) {
m.setProperties(getNumberOfVehicles(), SimulationKernel.SimulationKernel.getCurrentSimulationTime()).restart();
super.updateVehicles(vehiclesToUpdate);
}
}

@Override
public List<TrafficLightObject> getTrafficLightsInRange(PerceptionModel perceptionModel) {
try (PerformanceMonitor.Measurement m = monitor.start("search-traffic-light")) {
m.setProperties(SimulationKernel.SimulationKernel.getCurrentSimulationTime()).restart();
return super.getTrafficLightsInRange(perceptionModel);
}
}

@Override
public void updateTrafficLights(Map<String, TrafficLightGroupInfo> trafficLightsToUpdate) {
try (PerformanceMonitor.Measurement m = monitor.start("update-traffic-light")) {
m.setProperties(SimulationKernel.SimulationKernel.getCurrentSimulationTime()).restart();
super.updateTrafficLights(trafficLightsToUpdate);
}
}

@Override
public Collection<Edge<Vector3d>> getSurroundingWalls(PerceptionModel perceptionModel) {
try (PerformanceMonitor.Measurement m = monitor.start("search-walls")) {
m.setProperties(SimulationKernel.SimulationKernel.getCurrentSimulationTime()).restart();
return super.getSurroundingWalls(perceptionModel);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@

package org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index;

import org.eclipse.mosaic.fed.application.ambassador.simulation.VehicleUnit;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.NopPerceptionModule;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.PerceptionModel;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.SimplePerceptionConfiguration;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.objects.TrafficLightObject;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.objects.VehicleObject;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.providers.TrafficLightIndex;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.providers.VehicleIndex;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.providers.WallIndex;
import org.eclipse.mosaic.fed.application.app.api.perception.PerceptionModule;
import org.eclipse.mosaic.lib.database.Database;
import org.eclipse.mosaic.lib.math.Vector3d;
import org.eclipse.mosaic.lib.objects.trafficlight.TrafficLightGroup;
Expand Down Expand Up @@ -189,6 +193,13 @@ public Collection<Edge<Vector3d>> getSurroundingWalls(PerceptionModel perception
return wallIndex.getSurroundingWalls(perceptionModel);
}

public PerceptionModule<SimplePerceptionConfiguration> createPerceptionModule(VehicleUnit vehicleUnit, Database database, Logger osLog) {
if (vehicleIndex != null) {
return vehicleIndex.createPerceptionModule(vehicleUnit, database, log);
}
return new NopPerceptionModule(vehicleUnit, database, log);
}

public static class Builder {
private final Logger log;
private VehicleIndex vehicleIndex = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,14 @@
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.PerceptionModel;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.TrafficObjectIndex;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.objects.TrafficLightObject;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.util.TrafficLightIndexTypeAdapterFactory;
import org.eclipse.mosaic.lib.objects.trafficlight.TrafficLightGroup;
import org.eclipse.mosaic.lib.objects.trafficlight.TrafficLightGroupInfo;
import org.eclipse.mosaic.lib.objects.trafficlight.TrafficLightState;

import com.google.gson.annotations.JsonAdapter;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@JsonAdapter(TrafficLightIndexTypeAdapterFactory.class)
public abstract class TrafficLightIndex {

/**
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import org.eclipse.mosaic.lib.spatial.KdTree;
import org.eclipse.mosaic.lib.spatial.SpatialTreeTraverser;

import com.google.gson.annotations.Expose;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
Expand All @@ -32,13 +30,16 @@
*/
public class TrafficLightTree extends TrafficLightIndex {

@Expose
public int bucketSize = 20;
private final int bucketSize;

private KdTree<TrafficLightObject> trafficLightTree;

private SpatialTreeTraverser.InRadius<TrafficLightObject> treeTraverser;

public TrafficLightTree(int bucketSize) {
this.bucketSize = bucketSize;
}

@Override
public void initialize() {
// initialization at first update
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,27 @@
import org.eclipse.mosaic.lib.geo.CartesianRectangle;
import org.eclipse.mosaic.lib.spatial.BoundingBox;
import org.eclipse.mosaic.lib.spatial.Grid;
import org.eclipse.mosaic.lib.util.gson.UnitFieldAdapter;

import com.google.gson.annotations.JsonAdapter;
import org.slf4j.Logger;

import java.util.List;

public class VehicleGrid extends VehicleIndex {

@JsonAdapter(UnitFieldAdapter.DistanceMeters.class)
public double cellWidth = 200;
private final double cellWidth;

@JsonAdapter(UnitFieldAdapter.DistanceMeters.class)
public double cellHeight = 200;
private final double cellHeight;

/**
* The Grid to be used for spatial search of {@link VehicleObject}s.
*/
private Grid<VehicleObject> vehicleGrid;

public VehicleGrid(double cellWidth, double cellHeight) {
this.cellWidth = cellWidth;
this.cellHeight = cellHeight;
}

/**
* Configures a grid as a spatial index for vehicles.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,18 @@
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.SimplePerceptionConfiguration;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.TrafficObjectIndex;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.index.objects.VehicleObject;
import org.eclipse.mosaic.fed.application.ambassador.simulation.perception.util.VehicleIndexTypeAdapterFactory;
import org.eclipse.mosaic.fed.application.app.api.perception.PerceptionModule;
import org.eclipse.mosaic.lib.database.Database;
import org.eclipse.mosaic.lib.geo.CartesianPoint;
import org.eclipse.mosaic.lib.objects.vehicle.VehicleData;
import org.eclipse.mosaic.lib.objects.vehicle.VehicleType;

import com.google.gson.annotations.JsonAdapter;
import org.slf4j.Logger;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@JsonAdapter(VehicleIndexTypeAdapterFactory.class)
public abstract class VehicleIndex {

/**
Expand Down
Loading