@Override public void handleEvent(Event e) { if (!(e instanceof PDPModelEvent)) { return; } final List<Parcel> route = new ArrayList<>(vehicle.getRoute()); final Parcel newlyAddedParcel = ((PDPModelEvent) e).parcel; route.add(newlyAddedParcel); route.add(newlyAddedParcel); vehicle.setRoute(route); } }, PDPModelEventType.NEW_PARCEL);
@Override public void handleEvent(Event e) { if (!(e instanceof PDPModelEvent)) { return; } final List<Parcel> route = new ArrayList<>(vehicle.getRoute()); final Parcel newlyAddedParcel = ((PDPModelEvent) e).parcel; route.add(newlyAddedParcel); route.add(newlyAddedParcel); vehicle.setRoute(route); } }, PDPModelEventType.NEW_PARCEL);
@SuppressWarnings("synthetic-access") @Override public void onEntry(StateEvent event, RouteFollowingVehicle context) { checkState( getPDPModel().getVehicleState(context) == VehicleState.IDLE, "We can only be in Wait state when the vehicle is idle, " + "vehicle is %s.", getPDPModel().getVehicleState(context)); if (event == DefaultEvent.NOGO) { checkArgument(isDiversionAllowed); } if (context.newRoute.isPresent()) { context.setRoute(context.newRoute.get()); } }
@SuppressWarnings("synthetic-access") @Override public void onEntry(StateEvent event, RouteFollowingVehicle context) { checkState( getPDPModel().getVehicleState(context) == VehicleState.IDLE, "We can only be in Wait state when the vehicle is idle, " + "vehicle is %s.", getPDPModel().getVehicleState(context)); if (event == DefaultEvent.NOGO) { checkArgument(isDiversionAllowed); } if (context.newRoute.isPresent()) { context.setRoute(context.newRoute.get()); } }
@Override public void tick(TimeLapse timeLapse) { if (hasChanged) { hasChanged = false; // TODO check to see that this is called the first possible moment after // the add parcel event was dispatched // TODO it must be checked whether the calculated routes end up in the // correct vehicles final Set<RouteFollowingVehicle> vehicles = roadModel .getObjectsOfType(RouteFollowingVehicle.class); // gather current routes final ImmutableList.Builder<ImmutableList<Parcel>> currentRouteBuilder = ImmutableList .builder(); for (final RouteFollowingVehicle vehicle : vehicles) { final ImmutableList<Parcel> l = ImmutableList.copyOf(vehicle .getRoute()); currentRouteBuilder.add(l); } final Iterator<ImmutableList<Parcel>> routes = solverAdapter .solve( SolveArgs.create() .useAllParcels() .useCurrentRoutes(currentRouteBuilder.build())) .iterator(); for (final RouteFollowingVehicle vehicle : vehicles) { vehicle.setRoute(routes.next()); } } }
/** * Tests agent behavior when diversion is attempted in the wait state. This is * always allowed. */ @Test public void diversionTestInWaitState() { assertEquals(d.waitState, d.stateMachine.getCurrentState()); d.setRoute(asList(p1)); assertEquals(Optional.absent(), d.newRoute); assertEquals(new LinkedList<>(asList(p1)), d.route); d.setRoute(asList(p1, p2, p1, p2)); assertEquals(Optional.absent(), d.newRoute); assertEquals(new LinkedList<>(asList(p1, p2, p1, p2)), d.route); d.setRoute(asList(p2, p2, p1, p1)); assertEquals(Optional.absent(), d.newRoute); assertEquals(new LinkedList<>(asList(p2, p2, p1, p1)), d.route); }
d.setRoute(asList(p1, p1, p1)); } catch (final IllegalArgumentException e) { exception = true; d.setRoute(asList(p1)); tick(0, 10); assertEquals(ParcelState.IN_CARGO, pm.getParcelState(p1)); boolean exception2 = false; try { d2.setRoute(asList(p1)); } catch (final IllegalArgumentException e) { exception2 = true; d.setRoute(asList(p1, p1)); } catch (final IllegalArgumentException e) { exception3 = true;
/** * Test that an already delivered parcel is rejected by setRoute. */ @Test public void setRouteTest1() { d.setRoute(asList(p2, p2)); // when delivering the route may still contain p2 tick(0, 25); assertEquals(ParcelState.DELIVERING, pm.getParcelState(p2)); d.setRoute(asList(p2)); // when delivered the route may no longer contain p2 tick(25, 30); assertEquals(ParcelState.DELIVERED, pm.getParcelState(p2)); boolean exception = false; try { d.setRoute(asList(p2)); } catch (final IllegalArgumentException e) { exception = true; } assertThat(exception).isSameAs(routeAdjuster == RouteAdjusters.NOP); }
/** * Checks whether delayed route changing is rejected if necessary. */ @Test public void setRouteTest4() { d.setRoute(asList(p1, p1)); tick(12, 15); assertEquals(ParcelState.PICKING_UP, pm.getParcelState(p1)); assertEquals(VehicleState.PICKING_UP, pm.getVehicleState(d)); boolean exception = false; try { d.setRoute(asList(p2)); assertEquals(asList(p2), d.newRoute.get()); } catch (final IllegalArgumentException e) { exception = true; } assertThat(exception).isNotSameAs(allowDelayedRouteChanges); }
/** * Tests a check what happens if someone else is picking up a parcel that a * vehicle wants to pick up. */ @Test public void testParcelOwnerShip() { d.setRoute(asList(p1)); d2.setRoute(asList(p1)); tick(0, 7); assertEquals(ParcelState.PICKING_UP, pm.getParcelState(p1)); boolean exception = false; try { d2.checkCurrentParcelOwnership(); } catch (final IllegalStateException e) { exception = true; } assertTrue(exception); }
/** * Tests that the delay adjuster adds parcels in cargo. */ @Test public void setRouteSafeTest6() { d.setRoute(asList(p1, p1)); tick(0, 8); assertThat(pm.getParcelState(p1)).isSameAs(ParcelState.IN_CARGO); d.setRoute(asList(p2, p2)); if (routeAdjuster == RouteAdjusters.DELAY_ADJUSTER) { assertThat(d.getRoute()).containsExactly(p2, p2, p1).inOrder(); } else { assertThat(d.getRoute()).containsExactly(p2, p2).inOrder(); } }
/** * Test for: A parcel in the route that is being picked up by another vehicle. */ @Test public void setRouteSafeTest4() { d.setRoute(asList(p1, p1)); tick(0, 7); assertThat(pm.getParcelState(p1)).isSameAs(ParcelState.PICKING_UP); assertThat(d.getRoute()).containsExactly(p1, p1); boolean fail = false; try { // it is being picked up by the other vehicle, so this should be ignored d2.setRoute(asList(p1, p1)); assertThat(d2.getRoute()).isEmpty(); } catch (final IllegalArgumentException e) { assertThat(e.getMessage()).contains( "When a parcel in the route is in PICKING UP state the vehicle " + "must also be in that state"); fail = true; } assertThat(routeAdjuster == RouteAdjusters.NOP).isEqualTo(fail); }
/** * Test for: A parcel that occurs in the route has been delivered, all * occurrences of this parcel will be removed from the route. */ @Test public void setRouteSafeTest1() { d.setRoute(asList(p1, p1)); tick(0, 17); assertThat(pm.getParcelState(p1)).isSameAs(ParcelState.DELIVERED); assertThat(d.getRoute()).isEmpty(); // p1 is already delivered, therefore it can not occur in the route boolean fail = false; try { d.setRoute(asList(p1, p2, p1, p2)); assertThat(d.getRoute()).containsExactly(p2, p2).inOrder(); } catch (final IllegalArgumentException e) { assertThat(e.getMessage()).contains( "A parcel that is already delivered can not be part of a route."); fail = true; } assertThat(routeAdjuster == RouteAdjusters.NOP).isEqualTo(fail); }
/** * Test for: A parcel that occurs twice in the route but has already been * picked up by this vehicle, the first occurrence in the route will be * removed. */ @Test public void setRouteSafeTest3() { d.setRoute(asList(p1, p1)); tick(0, 8); assertThat(pm.getParcelState(p1)).isSameAs(ParcelState.IN_CARGO); assertThat(d.getRoute()).containsExactly(p1); boolean fail = false; // p1 is already in cargo, therefore it can occur only once in the route try { d.setRoute(asList(p1, p2, p1, p2)); assertThat(d.getRoute()).containsExactly(p2, p1, p2).inOrder(); } catch (final IllegalArgumentException e) { fail = true; assertThat(e.getMessage()).contains( "A parcel that is in cargo may not occur more than once in a route"); } assertThat(routeAdjuster == RouteAdjusters.NOP).isEqualTo(fail); d.setRoute(asList(p1, p2, p2)); assertThat(d.getRoute()).containsExactly(p1, p2, p2).inOrder(); }
/** * Test illegal argument: delivered state. */ @Test(expected = IllegalArgumentException.class) public void isTooEarlyDeliveredStateFail() { d.setRoute(asList(p1, p1)); tick(0, 60); assertEquals(ParcelState.DELIVERED, pm.getParcelState(p1)); d.isTooEarly(p1, time(2)); }
/** * Test illegal argument: transition state. */ @Test(expected = IllegalArgumentException.class) public void isTooEarlyTransitionStateFail() { d.setRoute(asList(p1)); tick(3, 6); assertEquals(ParcelState.PICKING_UP, pm.getParcelState(p1)); d.isTooEarly(p1, time(2)); }
/** * Tests the REROUTE event. */ @Test public void testRerouteEvent() { d.setRoute(asList(p1)); tick(0, 5, 20); assertEquals(d.waitForServiceState, d.stateMachine.getCurrentState()); boolean exception = false; try { d.setRoute(Arrays.<Parcel>asList(p2)); tick(12, 13); if (diversionIsAllowed) { // route has changed, here the actual REROUTE event will be sent assertEquals(d.gotoState, d.stateMachine.getCurrentState()); assertEquals(new LinkedList<>(asList(p2)), d.route); assertFalse(d.newRoute.isPresent()); } else { // route has not yet changed assertEquals(d.serviceState, d.stateMachine.getCurrentState()); assertEquals(new LinkedList<>(asList(p1)), d.route); assertEquals(asList(p2), d.newRoute.get()); } } catch (final IllegalArgumentException e) { exception = true; } assertEquals(!allowDelayedRouteChanges && !diversionIsAllowed, exception); }
/** * Tests the NOGO event. */ @Test public void testNogoEvent() { d.setRoute(asList(p2)); tick(0, 11); tick(11, 12); assertEquals(d.gotoState, d.stateMachine.getCurrentState()); boolean exception = false; try { d.setRoute(Arrays.<Parcel>asList()); tick(12, 13); if (diversionIsAllowed) { // route has changed, here the actual NOGO event will be sent assertEquals(d.waitState, d.stateMachine.getCurrentState()); assertEquals(new LinkedList<>(), d.route); assertFalse(d.newRoute.isPresent()); } else { // route has not yet changed assertEquals(d.gotoState, d.stateMachine.getCurrentState()); assertEquals(new LinkedList<>(asList(p2)), d.route); assertEquals(asList(), d.newRoute.get()); } } catch (final IllegalArgumentException e) { exception = true; } assertEquals(!allowDelayedRouteChanges && !diversionIsAllowed, exception); }
/** * */ @Test public void brokenWaitState() { d.setRoute(asList(p1)); tick(4, 5, 30); assertEquals(d.gotoState, d.stateMachine.getCurrentState()); if (allowDelayedRouteChanges) { d.setRoute(Arrays.<Parcel>asList()); rm.moveTo(d, p1, time(minute(0), minute(10))); assertTrue(rm.equalPosition(d, p1)); pm.pickup(d, p1, time(minute(16), minute(17))); assertEquals(VehicleState.PICKING_UP, pm.getVehicleState(d)); if (diversionIsAllowed) { boolean exception = false; try { tick(5, 6); } catch (final IllegalStateException e) { exception = true; } assertTrue(exception); } } }
/** * Tests that the statemachine dispatches the correct events in the correct * order when there is no service time. */ @Test @SuppressWarnings("ModifyingCollectionWithItself") public void noServiceTime() { final Parcel noServ = Parcel .builder(new Point(1, 2), new Point(1, 4)) .pickupTimeWindow(TimeWindow.create(minute(5), minute(15))) .deliveryTimeWindow(TimeWindow.create(minute(16), minute(30))) .pickupDuration(minute(0)) .deliveryDuration(minute(0)) .build(); PDPTWTestUtil.register(rm, pm, noServ); final List<DefaultEvent> expected = new ArrayList<>(asList(GOTO, ARRIVED, READY_TO_SERVICE, DONE)); expected.addAll(expected); final List<DefaultEvent> actual = new ArrayList<>(); d.stateMachine.getEventAPI().addListener(new Listener() { @Override public void handleEvent(Event e) { actual.add((DefaultEvent) ((StateTransitionEvent) e).trigger); } }, StateMachineEvent.STATE_TRANSITION); d.setRoute(asList(noServ, noServ)); tick(0, 100); assertThat(actual).containsExactlyElementsIn(expected).inOrder(); }