Skip to content

Commit 4316990

Browse files
committed
Improved elevator example and comments
1 parent 92fb742 commit 4316990

30 files changed

+255
-230
lines changed

JSimpleSim/src/org/simplesim/examples/SimpleAgent.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
import org.simplesim.model.State;
1212

1313
/**
14-
* Example of a simple implementation of an {@code RoutingAgent}
14+
* Simple implementation of a {@code RoutingAgent} as template for own implementations
1515
*/
16-
public class SimpleAgent extends RoutingAgent<SimpleAgent.SimpleAgentState, SimpleAgent.EVENT> {
16+
public class SimpleAgent extends RoutingAgent<SimpleAgent.SimpleAgentState, SimpleAgent.Event> {
1717

18-
enum EVENT {
19-
event1, event2, event3
18+
enum Event {
19+
EVENT1, EVENT2, EVENT3
2020
}
2121

2222
static class SimpleAgentState implements State {
@@ -42,21 +42,27 @@ protected Time doEvent(Time time) {
4242
return getTimeOfNextEvent();
4343
}
4444

45-
private void sendMessage(RoutingAgent<?,?> destination, Object content) {
45+
protected void sendMessage(RoutingAgent<?,?> destination, Object content) {
4646
RoutedMessage message=new RoutedMessage(this.getAddress(),destination.getAddress(),content);
4747
getOutport().write(message);
4848
}
4949

50+
/*
51+
* Do the message handling here.
52+
*/
5053
private void handleMessage(RoutedMessage message) {
51-
/*
52-
* Do the message handling here.
53-
*/
54+
5455
}
5556

56-
private void handleEvent(EVENT event, Time time) {
57-
/*
58-
* Do the event handling here.
59-
*/
57+
/*
58+
* Do the event handling here.
59+
*/
60+
private void handleEvent(Event event, Time time) {
61+
switch(event) {
62+
case EVENT1: ;
63+
case EVENT2: ;
64+
case EVENT3: ;
65+
};
6066
}
6167

6268
}

JSimpleSim/src/org/simplesim/examples/SimpleDomain.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@
1010
import org.simplesim.core.messaging.RoutedMessageForwarding;
1111
import org.simplesim.core.scheduling.Time;
1212
import org.simplesim.model.RoutingDomain;
13+
import org.simplesim.simulator.DynamicDecorator;
1314
import org.simplesim.simulator.SequentialDESimulator;
1415
import org.simplesim.simulator.Simulator;
1516

17+
18+
/**
19+
* Simple implementation of a {@code RoutingDomain}
20+
*/
1621
public class SimpleDomain extends RoutingDomain {
1722

1823
public SimpleDomain() {
@@ -28,9 +33,8 @@ public static void main(String[] args) {
2833
subdomain.addEntity(new SimpleAgent());
2934
root.addEntity(subdomain);
3035
ForwardingStrategy fs=new RoutedMessageForwarding(root);
31-
//final Simulator simulator=new DynamicDecorator(new ConcurrentDESimulator(model,fs));
32-
Simulator simulator=new SequentialDESimulator(root,fs);
33-
simulator.runSimulation(new Time(Time.TICKS_PER_HOUR));
36+
Simulator simulator=new DynamicDecorator(new SequentialDESimulator(root,fs));
37+
simulator.runSimulation(new Time(Time.INFINITY));
3438
}
3539

3640
}

JSimpleSim/src/org/simplesim/examples/elevator/DynamicMain.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,33 @@
88
import org.simplesim.core.messaging.ForwardingStrategy;
99
import org.simplesim.core.messaging.RoutedMessageForwarding;
1010
import org.simplesim.core.scheduling.Time;
11-
import org.simplesim.examples.elevator.core.Limits;
12-
import org.simplesim.examples.elevator.core.View;
1311
import org.simplesim.examples.elevator.dyn.DynamicElevator;
1412
import org.simplesim.examples.elevator.dyn.DynamicModel;
1513
import org.simplesim.examples.elevator.dyn.DynamicVisitor;
1614
import org.simplesim.examples.elevator.dyn.Floor;
15+
import org.simplesim.examples.elevator.shared.Limits;
16+
import org.simplesim.examples.elevator.shared.View;
1717
import org.simplesim.simulator.DynamicDecorator;
1818
import org.simplesim.simulator.SequentialDESimulator;
1919
import org.simplesim.simulator.Simulator;
2020

2121
/**
22-
* Example of a multi-domain agent system with direct messaging
22+
* Example of a multi-domain agent system with routed messaging and dynamic model changes
2323
* <p>
24-
* This
24+
* To illustrate differences of a static and a dynamic modeling approach, both are used with the same simulation problem: the steering strategy of an elevator.
25+
* Common data structure, the steering algorithm and the graphical representation are shared, so the focus lies on
26+
* the differences of both approaches:
27+
* <p>
28+
* <u>Static model:</u><ul>
29+
* <li> Visitors store their current floor in their state.
30+
* <li> Ports of elevator and visitor are connected directly.
31+
* <li>
32+
* </ul>
33+
*
34+
*
35+
* (no model changes) (model is changed during the
36+
* simulation run)
37+
* nThis is the dynamic variant of the elevator simulation example to illustrate differences from the static apporach.
2538
*/
2639
public class DynamicMain {
2740

JSimpleSim/src/org/simplesim/examples/elevator/StaticMain.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
import org.simplesim.core.messaging.DirectMessageForwarding;
1010
import org.simplesim.core.scheduling.Time;
11-
import org.simplesim.examples.elevator.core.Limits;
12-
import org.simplesim.examples.elevator.core.View;
11+
import org.simplesim.examples.elevator.shared.Limits;
12+
import org.simplesim.examples.elevator.shared.View;
1313
import org.simplesim.examples.elevator.stat.StaticElevator;
1414
import org.simplesim.examples.elevator.stat.StaticModel;
1515
import org.simplesim.examples.elevator.stat.StaticVisitor;

JSimpleSim/src/org/simplesim/examples/elevator/core/Visitor.java

Lines changed: 0 additions & 22 deletions
This file was deleted.

JSimpleSim/src/org/simplesim/examples/elevator/core/package-info.java

Lines changed: 0 additions & 10 deletions
This file was deleted.

JSimpleSim/src/org/simplesim/examples/elevator/dyn/DynamicElevator.java

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,50 +5,48 @@
55
*/
66
package org.simplesim.examples.elevator.dyn;
77

8-
import static org.simplesim.examples.elevator.core.Limits.LOBBY;
9-
import static org.simplesim.examples.elevator.core.Limits.START_DAY;
8+
import static org.simplesim.examples.elevator.shared.Limits.LOBBY;
9+
import static org.simplesim.examples.elevator.shared.Limits.START_DAY;
1010

1111
import org.simplesim.core.messaging.RoutedMessage;
1212
import org.simplesim.core.scheduling.Time;
13-
import org.simplesim.examples.elevator.core.Elevator;
14-
import org.simplesim.examples.elevator.core.ElevatorState;
15-
import org.simplesim.examples.elevator.core.ElevatorStrategy;
16-
import org.simplesim.examples.elevator.core.Limits;
17-
import org.simplesim.examples.elevator.core.Request;
13+
import org.simplesim.examples.elevator.shared.Elevator;
14+
import org.simplesim.examples.elevator.shared.ElevatorState;
15+
import org.simplesim.examples.elevator.shared.ElevatorStrategy;
16+
import org.simplesim.examples.elevator.shared.Limits;
17+
import org.simplesim.examples.elevator.shared.Request;
1818
import org.simplesim.model.AbstractAgent;
1919
import org.simplesim.model.RoutingAgent;
2020

2121
/**
22-
* Elevator agent implementing a simple planning strategy
23-
* <ul>
24-
* <li>If there is any request in direction of movement with the same direction, go to the nearest one.
25-
* <li>If there is any other request in direction of movement, go to the farthest one.
26-
* <li>If there is no other request in direction of movement, change direction.
27-
* </ul>
22+
* Part of the dynamic elevator example
23+
*
24+
* @see org.simplesim.elevator.DynamicMain DynamicMain
25+
*
2826
*/
29-
public final class DynamicElevator extends RoutingAgent<ElevatorState, Elevator.EVENT> implements Elevator {
27+
public final class DynamicElevator extends RoutingAgent<ElevatorState, Elevator.Event> implements Elevator {
3028

3129
private final ElevatorStrategy strategy;
3230

3331
public DynamicElevator() {
3432
super(new ElevatorState());
33+
strategy=new ElevatorStrategy(this);
3534
getState().setCurrentFloor(LOBBY);
3635
getState().setDestinationFloor(LOBBY);
3736
getState().setDirection(Limits.IDLE);
38-
strategy=new ElevatorStrategy(this);
39-
enqueueEvent(EVENT.idle,START_DAY);
37+
enqueueEvent(Event.IDLE,START_DAY);
4038
}
4139

4240
@Override
4341
protected Time doEvent(Time time) {
4442
switch (getEventQueue().dequeue()) {
45-
case moved: // just arrived on new floor
43+
case MOVED: // just arrived on new floor
4644
getState().setCurrentFloor(getState().getDestinationFloor());
4745
strategy.processMoveEvent(time);
4846
break;
49-
case idle: // nothing to do, wait for passengers
47+
case IDLE: // nothing to do, wait for passengers
5048
if (getInport().hasMessages()) strategy.processMoveEvent(time);
51-
else enqueueEvent(EVENT.idle,time.add(Limits.IDLE_TIME));
49+
else enqueueEvent(Event.IDLE,time.add(Limits.IDLE_TIME));
5250
break;
5351
default:
5452
throw new UnknownEventType("Unknown event type occured in ElevatorStrategy");
@@ -85,7 +83,7 @@ public void sendMessage(AbstractAgent<?, ?> recipient, Request content) {
8583
* org.simplesim.core.scheduling.Time)
8684
*/
8785
@Override
88-
public void enqueueEvent(EVENT event, Time time) {
86+
public void enqueueEvent(Event event, Time time) {
8987
getEventQueue().enqueue(event,time);
9088
}
9189

JSimpleSim/src/org/simplesim/examples/elevator/dyn/DynamicModel.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
import org.simplesim.model.RoutingDomain;
99

1010
/**
11-
*
12-
*
11+
* Part of the dynamic elevator example
12+
*
13+
* @see org.simplesim.elevator.DynamicMain DynamicMain
14+
*
1315
*/
1416
public class DynamicModel extends RoutingDomain {
1517

JSimpleSim/src/org/simplesim/examples/elevator/dyn/DynamicVisitor.java

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,33 @@
55
*/
66
package org.simplesim.examples.elevator.dyn;
77

8-
import static org.simplesim.examples.elevator.core.Limits.END_WORK;
9-
import static org.simplesim.examples.elevator.core.Limits.IDLE_TIME;
10-
import static org.simplesim.examples.elevator.core.Limits.LOBBY;
11-
import static org.simplesim.examples.elevator.core.Limits.MAX_FLOOR;
12-
import static org.simplesim.examples.elevator.core.Limits.START_DAY;
13-
import static org.simplesim.examples.elevator.core.Limits.START_WORK;
8+
import static org.simplesim.examples.elevator.shared.Limits.END_WORK;
9+
import static org.simplesim.examples.elevator.shared.Limits.IDLE_TIME;
10+
import static org.simplesim.examples.elevator.shared.Limits.LOBBY;
11+
import static org.simplesim.examples.elevator.shared.Limits.MAX_FLOOR;
12+
import static org.simplesim.examples.elevator.shared.Limits.START_DAY;
13+
import static org.simplesim.examples.elevator.shared.Limits.START_WORK;
1414

1515
import java.util.Random;
1616

1717
import org.simplesim.core.dynamic.DomainChangeRequest;
1818
import org.simplesim.core.messaging.RoutedMessage;
1919
import org.simplesim.core.scheduling.Time;
20-
import org.simplesim.examples.elevator.core.Limits;
21-
import org.simplesim.examples.elevator.core.Request;
22-
import org.simplesim.examples.elevator.core.Visitor;
23-
import org.simplesim.examples.elevator.core.VisitorState;
24-
import org.simplesim.examples.elevator.core.VisitorState.ACTIVITY;
20+
import org.simplesim.examples.elevator.shared.Limits;
21+
import org.simplesim.examples.elevator.shared.Request;
22+
import org.simplesim.examples.elevator.shared.Visitor;
23+
import org.simplesim.examples.elevator.shared.VisitorState;
24+
import org.simplesim.examples.elevator.shared.VisitorState.ACTIVITY;
2525
import org.simplesim.model.AbstractAgent;
2626
import org.simplesim.model.RoutingAgent;
2727

2828
/**
29-
*
30-
*
29+
* Part of the dynamic elevator example
30+
*
31+
* @see org.simplesim.elevator.DynamicMain DynamicMain
32+
*
3133
*/
32-
public final class DynamicVisitor extends RoutingAgent<VisitorState, Visitor.EVENT> implements Visitor {
34+
public final class DynamicVisitor extends RoutingAgent<VisitorState, Visitor.Event> implements Visitor {
3335

3436
private static final Random random=new Random();
3537
private final DynamicModel building;
@@ -40,19 +42,19 @@ public DynamicVisitor(DynamicModel model) {
4042
getState().setActivity(ACTIVITY.waiting);
4143
// init arrival time at lobby with a random value before start of work
4244
final Time time=START_DAY.add(random.nextInt((int) (START_WORK.getTicks()-START_DAY.getTicks())));
43-
getEventQueue().enqueue(EVENT.changeFloor,time);
45+
getEventQueue().enqueue(Event.CHANGE_FLOOR,time);
4446
}
4547

4648
@Override
4749
protected Time doEvent(Time time) {
4850
switch (getEventQueue().dequeue()) {
49-
case waiting:
51+
case WAITING:
5052
waitForElevator(time);
5153
break;
52-
case changeFloor:
54+
case CHANGE_FLOOR:
5355
changeFloor(time);
5456
break;
55-
case goHome:
57+
case GO_HOME:
5658
throw new RuntimeException("Never should get here!");
5759
default:
5860
throw new UnknownEventType("Unknown event type occured in "+toString());
@@ -73,14 +75,14 @@ private void waitForElevator(Time time) {
7375
addModelChangeRequest(new DomainChangeRequest(this,dest));
7476

7577
if ((time.compareTo(END_WORK)>=1)&&(request.getDestinationFloor()==LOBBY))
76-
getEventQueue().enqueue(EVENT.goHome,Time.INFINITY); // work is over, going home
78+
getEventQueue().enqueue(Event.GO_HOME,Time.INFINITY); // work is over, going home
7779
// go to another floor after staying here for a random time period
7880
else {
7981
getState().setActivity(ACTIVITY.working);
80-
getEventQueue().enqueue(EVENT.changeFloor,time.add(random.nextInt(Limits.MAX_STAY_TIME)));
82+
getEventQueue().enqueue(Event.CHANGE_FLOOR,time.add(random.nextInt(Limits.MAX_STAY_TIME)));
8183
}
8284
} // else just wait a little longer
83-
else getEventQueue().enqueue(EVENT.waiting,time.add(IDLE_TIME));
85+
else getEventQueue().enqueue(Event.WAITING,time.add(IDLE_TIME));
8486
}
8587

8688
@Override
@@ -99,10 +101,11 @@ private void changeFloor(Time time) {
99101
else while (destination==getCurrentFloor()) destination=1+random.nextInt(MAX_FLOOR);
100102
sendRequest(building.getElevator(),destination,time);
101103
getState().setActivity(ACTIVITY.waiting);
102-
getEventQueue().enqueue(EVENT.waiting,time.add(IDLE_TIME));
104+
getEventQueue().enqueue(Event.WAITING,time.add(IDLE_TIME));
103105
}
104106

105-
private void sendRequest(AbstractAgent<?, ?> dest, int destination, Time time) {
107+
@Override
108+
public void sendRequest(AbstractAgent<?, ?> dest, int destination, Time time) {
106109
final Request request=new Request(this,getCurrentFloor(),destination,time);
107110
final RoutedMessage msg=new RoutedMessage(this.getAddress(),dest.getAddress(),request);
108111
getOutport().write(msg); // send request to elevator

JSimpleSim/src/org/simplesim/examples/elevator/dyn/Floor.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@
1212

1313
import org.simplesim.model.RoutingDomain;
1414

15-
/**
15+
/**
16+
* Part of the dynamic elevator example
17+
*
1618
* The Floor class models one story of the building and contains the level of the floor
17-
*
19+
*
20+
* @see org.simplesim.elevator.DynamicMain DynamicMain
21+
*
1822
*/
1923
public final class Floor extends RoutingDomain {
2024

@@ -31,7 +35,7 @@ public int getFloor() {
3135

3236
@Override
3337
public String getName() {
34-
return "Floor"+getFloor();
38+
return "floor_"+getFloor();
3539
}
3640

3741
}

0 commit comments

Comments
 (0)