package de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.xml; import java.io.FileInputStream; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.VehicleInformationContainer; import de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.csv.RoadSideUnitInformationHandler; import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.SimulationSetupExtractor; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.VehicleController; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetwork; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.exception.NoAdditionalRouteAvailableException; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.exception.NoExitAvailableException; public class XMLSimulationController implements VehicleController, SimulationSetupExtractor, Runnable { private String _vehicleDataPath; private String _roadSideUnitDataPath; private List _vehicles; private Map> _positonsByTimestamp = new HashMap<>(); private int _futureInformation = 0; private boolean _initalized = false; private VehicleDataInformationHandler _vehicleDataInformationHandler = new VehicleDataInformationHandler(); private RoadSideUnitInformationHandler _roadSideUnitInformationHandler = new RoadSideUnitInformationHandler(); private double _start = -1; private double _step; public XMLSimulationController(String pVehicleDataPath, String pRoadSideUnitDataPath) { this(pVehicleDataPath); _roadSideUnitDataPath = pRoadSideUnitDataPath; } public XMLSimulationController(String pVehicleDataPath) { _vehicleDataPath = pVehicleDataPath; } @Override public void init() { if (!_initalized) { if (_vehicleDataPath != null) { Thread thread = new Thread(this); thread.start(); for (int i = 0; i < _futureInformation; i++) { nextStep(); } } if (_roadSideUnitDataPath != null) { _roadSideUnitInformationHandler.parseIntersectionsFile(_roadSideUnitDataPath); } _initalized = true; } } @Override public Location getVehiclePosition(String pVehicleID) { return getVehiclePosition(_step, pVehicleID); } public VehicleInformationContainer requestVehicleInformation(String pVehicleID) { return _vehicleDataInformationHandler.getVehiclePositions().get(pVehicleID); } @Override public boolean nextStep() { _vehicleDataInformationHandler.readNext(); _step = _vehicleDataInformationHandler.getStep() - _futureInformation; if (_start == -1) { _start = _vehicleDataInformationHandler.getStep(); } double newStep = _step + _futureInformation; if (!_positonsByTimestamp.containsKey(newStep)) { Map vehiclePositions = new HashMap<>(); _positonsByTimestamp.put(newStep, vehiclePositions); List allVehicles = new ArrayList<>(_vehicleDataInformationHandler.getVehiclePositions().keySet()); for (String vehicle : allVehicles) { VehicleInformationContainer vehiclePosition = requestVehicleInformation(vehicle); if (vehiclePosition != null) { vehiclePositions.put(vehicle, vehiclePosition); } } } return !_vehicleDataInformationHandler.isTerminated(); } @Override public List getAllVehicles() { return getAllVehicles(_step); } @Override public double getStep() { return _step; } @Override public double getStart() { return _start; } @Override public void run() { try { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); parser.parse(new FileInputStream(_vehicleDataPath), _vehicleDataInformationHandler); } catch (RuntimeException e) { throw e; } catch (Exception e) { e.printStackTrace(); } } @Override public void setObservedArea(double pStartX, double pStartY, double pEndX, double pEndY) { _vehicleDataInformationHandler.setObservedArea(pStartX, pStartY, pEndX, pEndY); _roadSideUnitInformationHandler.setObservedArea(pStartX, pStartY, pEndX, pEndY); } @Override public Location getVehiclePosition(double pStep, String pVehicleID) { Map map = _positonsByTimestamp.get(pStep); return map.get(pVehicleID).getPosition(); } @Override public List getAllVehicles(double pStep) { Map map = _positonsByTimestamp.get(pStep); return new ArrayList<>(map.keySet()); } @Override public double getMaximumAvailablePrediction() { double max = Collections.max(_positonsByTimestamp.keySet()); return max; } @Override public List getAllIntersections(boolean pCluster) { return _roadSideUnitInformationHandler.getIntersections(); } @Override public double getScenarioWidth() { return -1; } @Override public double getScenarioHeight() { return -1; } @Override public RoadNetworkRoute getCurrentRoute(String pVehicleID) { throw new UnsupportedOperationException("This method is not supported for " + getClass().getSimpleName()); } @Override public RoadNetwork getRoadNetwork() { return null; } @Override public void rerouteVehicle(String pVehicle, RoadNetworkRoute pRoute) { throw new UnsupportedOperationException("This method is not supported for " + getClass().getSimpleName()); } @Override public RoadNetworkRoute findNewRoute(String pVehicle) throws NoAdditionalRouteAvailableException { throw new UnsupportedOperationException("This method is not supported for " + getClass().getSimpleName()); } @Override public RoadNetworkRoute findNewRoute(String pVehicle, List pEdgesToAvoid, boolean pKeepDestination) throws NoAdditionalRouteAvailableException, NoExitAvailableException { throw new UnsupportedOperationException("This method is not supported for " + getClass().getSimpleName()); } @Override public void stopVehicle(String pVehicle) { throw new UnsupportedOperationException("This method is not supported for " + getClass().getSimpleName()); } @Override public double getVehicleSpeed(String pVehicleID) { return _vehicleDataInformationHandler.getVehiclePositions().get(pVehicleID).getSpeed(); } @Override public double getVehicleHeading(String pVehicleID) { return _vehicleDataInformationHandler.getVehiclePositions().get(pVehicleID).getHeading(); } }