In: Computer Science
You have been asked to design an elevator system.
The functions of an elevator includes moving up and down, open and close doors, and pick up passengers.
The elevator is supposed to be used in a building having floors numbered from 1 to MaxFloor, where the first floor is the lobby.
There are car call buttons in the car corresponding to each floor.
For every floor except for the top floor and the lobby, there are two hall call buttons for the passengers to call for going up and down.
There is only one down hall call button at the top floor and one up hall call button in the lobby. When the car stops at a floor, the doors are opened and the car lantern indicating the current direction the car is going is illuminated so that the passengers can get to know the current moving direction of the car.
The car moves fast between floors, but it should be able to slow down early enough to stop at a desired floor. In order to certificate system safety, emergency brake will be triggered and the car will be forced to stop under any unsafe conditions.
Follow the process documented above to design the Elevator System.
Questions :
1. Specify the requirements
2. Design a solution
3. Implement the solution with java
4. Test the solution
Requirements:
The elevator is supposed to be used in a building having floors numbered from 1 to MaxFloor, where the first floor is the lobby. There are car(Lift) call buttons in the car corresponding to each floor. For every floor except for the top floor and the lobby, there are two hall call buttons for the passengers to call for going up and down. There is only one down hall call button at the top floor and one up hall call button in the lobby. When the car stops at a floor, the doors are opened and the car lantern indicating the current direction the car is going is illuminated so that the passengers can get to know the current moving direction of the car. The car moves fast between floors, but it should be able to slow down early enough to stop at the desired floor. In order to certificate system safety, emergency brake will be triggered and the car will be forced to stop under any unsafe conditions.
DESIGN:
Based on the above requirements, we have use-cases such as
Based on the use-cases mentioned we have various control classes and control objects to implement the functionalities. The implementation of the system is done in java.
CODE:
public class Elevator {
private float location = 0;
private Direction direction = Direction.UP;
private State state = State.STOPPED;
private Door door = Door.CLOSED;
private Thread processingThread;
private Thread listeningThread;
public class Request {
public long time;
public Integer floor;
public Direction direction;
public Request(long time, Integer floor, Direction direction)
{
this.time = time;
this.floor = floor;
this.direction = direction;
}
}
public enum Direction {
UP, DOWN
}
public enum State {
MOVING, STOPPED
}
public enum Door {
OPEN, CLOSED
}
public Comparator<Request> upComparator = new
Comparator<Request>() {
public int compare(Request u1, Request u2) {
return u1.floor.compareTo(u2.floor);
}
};
public Comparator<Request> downComparator =
upComparator.reversed();
private Queue<Request> upQueue = new
PriorityQueue<>(upComparator);
private Queue<Request> currentQueue = upQueue;
private Queue<Request> downQueue = new
PriorityQueue<>(downComparator);
public void call(int floor, Direction direction) {
if (direction == Direction.UP) {
if (floor >= location) {
currentQueue.add(new Request(System.currentTimeMillis(),
floor,
direction));
} else {
upQueue.add(new Request(System.currentTimeMillis(), floor,
direction));
}
} else {
if (floor <= location) {
currentQueue.add(new Request(System.currentTimeMillis(),
floor,
direction));
} else {
downQueue.add(new Request(System.currentTimeMillis(), floor,
direction));
}
}
}
public void go(int floor) {
call(floor, direction);
}
public void process() {
while (true) {
if (!upQueue.isEmpty() && !downQueue.isEmpty()) {
Request r = currentQueue.poll();
if (r != null) {
goToFloor(r.floor);
} else {
preProcessNextQueue();
}
}
}
}
public void goToFloor(int floor) {
state = State.MOVING;
for (float i = location; i <= floor; i = (float) (i + 0.1))
{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
location = floor;
door = Door.OPEN;
state = State.STOPPED;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
door = Door.CLOSED;
}
private void preProcessNextQueue() {
if (getLowestTimeUpQueue() > getLowestTimeDownQueue()) {
this.direction = Direction.UP;
currentQueue = upQueue;
upQueue = new PriorityQueue<>(upComparator);
} else {
this.direction = Direction.DOWN;
currentQueue = downQueue;
downQueue = new PriorityQueue<>(downComparator);
}
}
private long getLowestTimeUpQueue() {
long lowest = Long.MAX_VALUE;
for (Request r : upQueue) {
if (r.time < lowest)
lowest = r.time;
}
return lowest;
}
private long getLowestTimeDownQueue() {
long lowest = Long.MAX_VALUE;
for (Request r : downQueue) {
if (r.time < lowest)
lowest = r.time;
}
return lowest;
}
public class Process implements Runnable {
@Override
public void run() {
process();
}
}
public class Listen implements Runnable {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(90000);
while (true) {
Socket socket = serverSocket.accept();
Thread thread = new Thread(new Worker(socket));
thread.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Worker implements Runnable {
private Socket s;
public Worker(Socket s) {
this.s = s;
}
@Override
public void run() {
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String line;
while (true) {
if ((line = reader.readLine()) != null) {
String[] tokens = line.split(" ");
if(tokens.length == 3 && tokens[0].equals("call")){
call(Integer.parseInt(tokens[1]),
tokens[2].equals("up")?Direction.UP:Direction.DOWN);
}else if(tokens.length == 2 &&
tokens[0].equals("go")){
go(Integer.parseInt(tokens[1]));
}else{
s.getOutputStream().write("Wrong input".getBytes());
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Elevator elevator = new Elevator();
elevator.listeningThread = new Thread(elevator.new Listen());
elevator.listeningThread.start();
elevator.processingThread = new Thread(elevator.new
Process());
elevator.processingThread.start();
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}