@Inject public LaneMoveHandler( HasArea environment, EnvironmentServiceProvider serviceProvider, EnvironmentSharedStateAccess sharedState, EventBus eb, @Named("params.nonStopMode") int nonStopMode) throws UnavailableServiceException { super(environment, serviceProvider, sharedState); this.eventBus = eb; eb.subscribe(this); this.roadEnvironmentService = serviceProvider.getEnvironmentService(RoadEnvironmentService.class); this.speedService = serviceProvider.getEnvironmentService(SpeedService.class); this.nonStopMode = nonStopMode; }
@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; }