public CollisionCheck(UUID pov, RoadLocation startFrom, RoadLocation finishAt) { super(); this.self = pov; this.startFrom = startFrom; this.finishAt = finishAt; // build collision candidate set int startOffset = startFrom.getOffset(); int finishOffset = finishAt.getOffset(); if (finishOffset < startOffset) finishOffset += areaLength; for (int lane = 0; lane < getAreaService().getSizeX(); lane++) { collisionCandidates.addAll(getAgentsInLane(lane, startOffset, finishOffset)); } collisionCandidates.remove(this.self); laneChange = startFrom.getLane() != finishAt.getLane(); for (UUID a : collisionCandidates) { candidateLocs.put(a, (RoadLocation) getLocationService().getAgentLocation(a)); } }
public Set<UUID> checkForCollision() { Set<UUID> collided = new HashSet<UUID>(); int collisionsOccured = 0; Set<UUID> agentsOnCurrentCell = getAreaService().getCell(finishAt.getLane(), finishAt.getOffset(), 0); if (agentsOnCurrentCell.size() > 1) { logger.warn( "Collision Occurred: Multiple agents on one cell. Cell: " + this.finishAt + ", agents: " + agentsOnCurrentCell); collisionsOccured++; for (UUID a : agentsOnCurrentCell) { if (!a.equals(self)) { collided.add(a); } } } for (UUID a : collisionCandidates) { // FIXME ? This stops agents that have left being checked if (getLocationService() == null) { System.out.println(); // stop here } if (a == null) { System.out.println(); // or here } if (!hasLeft(a)) { RoadLocation current = (RoadLocation) getLocationService().getAgentLocation(a); // new code here if ((current.getLane() == finishAt.getLane()) && !laneChange) { // same lane, if he is behind us then it is a collision int hisOffset = current.getOffset(); int myOffset = finishAt.getOffset(); boolean heWrapped = hisOffset < candidateLocs.get(a).getOffset(); boolean iWrapped = myOffset < startFrom.getOffset(); if (!iWrapped && heWrapped) { hisOffset += areaLength; } if (hisOffset < myOffset) { logger.warn( "Collision Occured: Agent " + agentsOnCurrentCell + " went through " + a + " on cell " + finishAt); collisionsOccured++; collided.add(a); } } // commenting out old code /* if (current.getLane() == finishAt.getLane()) { // same lane, if he is behind us then it is a collision int hisOffset = current.getOffset(); int myOffset = finishAt.getOffset(); boolean heWrapped = hisOffset < candidateLocs.get(a).getOffset(); boolean iWrapped = myOffset < startFrom.getOffset(); if(!iWrapped && heWrapped) { hisOffset += areaLength; } if (hisOffset < myOffset) { logger.warn("Collision Occured: Agent " + agentsOnCurrentCell + " went through " + a + " on cell " + finishAt); collisionsOccured++; } } if (laneChange && current.getLane() == startFrom.getLane() && finishAt.getLane() == candidateLocs.get(a).getLane() && current.getOffset() <= finishAt.getOffset()) { logger.warn("Collision Occured: Agent " + agentsOnCurrentCell + " crossed paths with " + a + " between cells " + finishAt); collisionsOccured++; }*/ } } if (collisionsOccured > 0) { System.err.println(collisionsOccured + " collisions occurred."); } return collided; }
@Override public Input handle(Action action, UUID actor) throws ActionHandlingException { CellMove m = (CellMove) action; int prevSpeed = speedService.getAgentSpeed(actor); int maxSpeed = roadEnvironmentService.getMaxSpeed(); int maxAccel = roadEnvironmentService.getMaxAccel(); int maxDecel = roadEnvironmentService.getMaxDecel(); // check move direction is positive or 0 if (m.getY() < 0) { throw new ActionHandlingException("Cannot move backwards. Move was: " + m); } // check move is not too fast if (m.getY() > maxSpeed) { throw new ActionHandlingException( "Cannot move faster than the maximum speed (" + maxSpeed + "). Move was: " + m); } // check acceleration is not too fast if (m.getY() > prevSpeed) { if ((m.getY() - prevSpeed) > maxAccel) { throw new ActionHandlingException( "Cannot accelerate faster than the maximum acceleration (" + maxAccel + "). Move was: " + m + " and previous speed was " + prevSpeed); } } // check deceleration is not too fast if (m.getY() < prevSpeed) { if ((prevSpeed - m.getY()) > maxDecel) { throw new ActionHandlingException( "Cannot decelerate faster than the maximum deceleration (" + maxDecel + "). Move was: " + m + " and previous speed was " + prevSpeed); } } // check move sideways magnitude is 0 or 1 if (Math.abs(m.getX()) > 1) { throw new ActionHandlingException( "Cannot change greater than one lane at once. Move was: " + m); } // cannot change lane without forward movement if (Math.abs(m.getX()) > 0 && (int) m.getY() == 0) { throw new ActionHandlingException("Cannot change lane while stationary"); } RoadLocation start = (RoadLocation) getLocationService().getAgentLocation(actor); RoadLocation target = new RoadLocation(start.add(m)); if (!target.in(environment.getArea())) { // check if it's a junction location if (target.getLane() == -1) { Integer exitPoint = null; Integer startOffset = MathsUtils.mod(start.getOffset(), roadEnvironmentService.getLength()); Integer targetOffset = MathsUtils.mod(target.getOffset(), roadEnvironmentService.getLength()); if (startOffset > targetOffset) { startOffset = startOffset - roadEnvironmentService.getLength(); } for (int junction : roadEnvironmentService.getJunctionLocations()) { if ((startOffset <= junction) && (targetOffset >= junction)) { exitPoint = junction; logger.info("Agent " + actor + " left the road at " + exitPoint); eventBus.publish(new AgentLeftScenario(actor, exitPoint, SimTime.get())); // turning off means avoiding the possibility of crashing... ohwells: sliproads are // LOOOONG return null; } } logger.warn( "Agent " + actor + " tried to turn off using move " + m + " between " + start + " and " + target + " and offsets " + startOffset + "," + targetOffset + " but was not near a junction"); } /*if ( (target.getLane()==-1) && (roadEnvironmentService.isJunctionOffset(target.getOffset())) ) { // do stuff logger.info("Agent " + actor + " left the road at " + target.getOffset()); eventBus.publish(new AgentLeftScenario(actor,target.getOffset(), SimTime.get())); // turning off means avoiding the possibility of crashing... ohwells: sliproads are LOOOONG return null; } else {*/ try { final Move mNew = environment.getArea().getValidMove(start, m); target = new RoadLocation(start.add(mNew)); } catch (EdgeException e) { throw new ActionHandlingException(e); } // } } this.getLocationService().setAgentLocation(actor, target); this.speedService.setAgentSpeed(actor, (int) m.getY()); checks.add(new CollisionCheck(actor, start, target)); logger.info(actor + " move: " + m); return null; }