/** Called when the drive is transitioning to the Stop state */ private void driveStopping() { int currentFloor = floorArray.getCurrentFloor(); Hallway h; if (Elevator.hasLanding(currentFloor, Hallway.FRONT)) { if (Elevator.hasLanding(currentFloor, Hallway.BACK)) h = Hallway.BOTH; else h = Hallway.FRONT; } else h = Hallway.BACK; currentFloor--; if (h == Hallway.BOTH) { if (!carLights[currentFloor][Hallway.FRONT.ordinal()].lighted() && !carLights[currentFloor][Hallway.BACK.ordinal()].lighted() && !hallLights[currentFloor][Hallway.FRONT.ordinal()][Direction.UP.ordinal()].lighted() && !hallLights[currentFloor][Hallway.FRONT.ordinal()][Direction.DOWN.ordinal()].lighted() && !hallLights[currentFloor][Hallway.BACK.ordinal()][Direction.UP.ordinal()].lighted() && !hallLights[currentFloor][Hallway.BACK.ordinal()][Direction.DOWN.ordinal()] .lighted()) { warning("R-T6 Violated: Stopped at floor" + currentFloor + " with no pending calls."); } } else if (!carLights[currentFloor][h.ordinal()].lighted() && !hallLights[currentFloor][h.ordinal()][Direction.UP.ordinal()].lighted() && !hallLights[currentFloor][h.ordinal()][Direction.DOWN.ordinal()].lighted()) { warning("R-T6 Violated: Stopped at floor" + currentFloor + " with no pending calls."); } }
@Override public void timerExpired(Object callbackData) { State newState = state; curr_pos = mCarLevelPosition.getPosition(); // We add 100 in order to make sure the floor is being updated correctly. curr_f = (curr_pos + 100) / 5000 + 1; if (curr_f != lastFloor) { lastFloor = curr_f; // System.out.println("resetting overweight"); overweight = false; lastClosedAt = 0; } // System.out.println("curr_pos is " + curr_pos + " and curr_f is " + curr_f); if (Elevator.hasLanding(curr_f, Hallway.FRONT)) { if (Elevator.hasLanding(curr_f, Hallway.BACK)) curr_h = Hallway.BOTH; else curr_h = Hallway.FRONT; } else curr_h = Hallway.BACK; // State Machine switch (state) { // #state State 2: Doors Open case STATE_DOORSOPEN: // State actions for 'DOORSOPEN' waitCounter = waitTime; // If mDesiredDirection.d is STOP, we continue to look for hall and car halls. // mDesiredDirection.d is also set at curr_d // System.out.println("1current desired direction:" + mDesiredFloor.getDirection()); if (mDesiredFloor.getDirection() == Direction.STOP) { /* * NOTE: When nextTarget is called, curr_d is set to the desired direction, * direction is set to the NEXT desired direction and floor is set to * the NEXT target floor. BUT we only want to change the directional * portion of mDesiredFloor, hence we use hallway, curr_f, and curr_d * to set the next Desired Floor. * * If no additional floors are found. Nothing changes so it is safe to * set mDesired dwell to curr_f, hallway, and curr_d still. */ nextTarget(mDriveSpeed.getSpeed(), mCarLevelPosition.getPosition(), curr_d); // Now set the next target. // System.out.println("open floor is " + floor + " next direction is " + direction + " // current direction is " + curr_d + " hallway " + hallway); // System.out.println("changing direction to " + curr_d); mDesiredFloor.set(curr_f, curr_d, hallway); // System.out.println("2current desired direction:" + mDesiredFloor.getDirection()); } // If the car is overweight, dont answer hall calls at this floor until later! if (mCarWeight.getValue() > Elevator.MaxCarCapacity) { overweight = true; } if (hallway == Hallway.BOTH) { // If either side of doors open and we're not at the floor, emergency! // #transition 11.T.4 if ((!mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.FRONT, Side.LEFT)] .getValue() || !mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.BACK, Side.LEFT)] .getValue()) && !mAtFloor[ReplicationComputer.computeReplicationId(curr_f, Hallway.FRONT)] .getValue()) { newState = State.STATE_EMERGENCY; } // #transition 11.T.3 when doors closed. else if ((mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.FRONT, Side.LEFT)] .getValue() && mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.BACK, Side.LEFT)] .getValue())) lastClosedAt = curr_f; newState = State.STATE_DOORSCLOSED; } // if it is not at ANY floor and ANY doors are open, jump to emergency state // #transition 11.T.4 else if ((!mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.FRONT, Side.LEFT)] .getValue() || !mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.BACK, Side.LEFT)] .getValue()) && !mAtFloor[ReplicationComputer.computeReplicationId(curr_f, hallway)].getValue()) { newState = State.STATE_EMERGENCY; } // if no issues, move to the next state when doors closed // #transition 11.T.3 else if ((mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.FRONT, Side.LEFT)] .getValue() && mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.BACK, Side.LEFT)] .getValue())) { lastClosedAt = curr_f; newState = State.STATE_DOORSCLOSED; } else newState = state; break; // State actions for 'Doors Closed' // #state State 1: Doors Closed case STATE_DOORSCLOSED: // If waitForCall flag set, wait for 2 seconds for passenger to make car call. if (waitForCall) { // System.out.println("waiting"); // while counter is greater than zero, keep subtracting; if (waitCounter.isPositive()) waitCounter = SimTime.subtract(waitCounter, period); else { // Reset waitCounter for next time and set waitForCall false waitForCall = false; } break; } else { // System.out.println("not waiting"); // Check both sides for closed doors if that is the case. if (hallway == Hallway.BOTH || curr_h == Hallway.BOTH) { // If we're at the next target floor AND doors are opening, jump to DOORSOPEN // #transition 11.T.1 if (mAtFloor[ReplicationComputer.computeReplicationId(floor, Hallway.FRONT)].getValue() && ((!mDoorClosed[ ReplicationComputer.computeReplicationId(Hallway.FRONT, Side.LEFT)] .getValue() || !mDoorClosed[ ReplicationComputer.computeReplicationId(Hallway.BACK, Side.LEFT)] .getValue()))) { newState = State.STATE_DOORSOPEN; // If car is answering a hall call, wait for carcall after doors close. if (mDesiredFloor.getDirection() != Direction.STOP) waitForCall = true; // curr_d updated within nextTarget() but also updated when we open doors. curr_d = direction; // promised_d = direction; } // If either side of doors open and we're not at any floor, emergency! // #transition 11.T.2 else if ((!mDoorClosed[ ReplicationComputer.computeReplicationId(Hallway.FRONT, Side.LEFT)] .getValue() || !mDoorClosed[ ReplicationComputer.computeReplicationId(Hallway.BACK, Side.LEFT)] .getValue()) && !(mAtFloor[ReplicationComputer.computeReplicationId(curr_f, Hallway.FRONT)] .getValue() || mAtFloor[ReplicationComputer.computeReplicationId(curr_f, Hallway.BACK)] .getValue()) && !mAtFloor[ReplicationComputer.computeReplicationId(floor, Hallway.FRONT)] .getValue()) { newState = State.STATE_EMERGENCY; } else newState = state; } // If we're at the next target floor AND doors are opening, jump to DOORSOPEN // #transition 11.T.1 else if (mAtFloor[ReplicationComputer.computeReplicationId(floor, hallway)].getValue() && ((!mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.FRONT, Side.LEFT)] .getValue() || !mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.BACK, Side.LEFT)] .getValue()))) { newState = State.STATE_DOORSOPEN; curr_d = direction; // promised_d = direction; if (mDesiredFloor.getDirection() != Direction.STOP) waitForCall = true; } // If either side of doors open and we're not at any floor, emergency! // #transition 11.T.2 else if ((!mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.FRONT, Side.LEFT)] .getValue() || !mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.BACK, Side.LEFT)] .getValue()) && !mAtFloor[ReplicationComputer.computeReplicationId(curr_f, curr_h)].getValue() && !mAtFloor[ReplicationComputer.computeReplicationId(floor, hallway)].getValue()) { newState = State.STATE_EMERGENCY; } else newState = state; } // Only change nextTarget if we're not transitioning states if (newState == state) { // Set next Direction and next target Floor nextTarget(mDriveSpeed.getSpeed(), mCarLevelPosition.getPosition(), curr_d); /*This code is invalid. Must check if landing has call as well. * Decide which hallway is valid. If front and back, then both, else either front or back.*/ hallIndexF = ReplicationComputer.computeReplicationId(floor, Hallway.FRONT, direction); carIndexF = ReplicationComputer.computeReplicationId(floor, Hallway.FRONT); hallIndexB = ReplicationComputer.computeReplicationId(floor, Hallway.BACK, direction); carIndexB = ReplicationComputer.computeReplicationId(floor, Hallway.BACK); if (Elevator.hasLanding(floor, Hallway.FRONT)) { if (Elevator.hasLanding(floor, Hallway.BACK)) { // Check both landings for valid calls. If not both, then select one. if ((mHallCall[hallIndexF].getValue() || mCarCall[carIndexF].getValue()) && (mHallCall[hallIndexB].getValue() || mCarCall[carIndexB].getValue())) { hallway = Hallway.BOTH; } else if (mHallCall[hallIndexF].getValue() || mCarCall[carIndexF].getValue()) { hallway = Hallway.FRONT; } else if (mHallCall[hallIndexB].getValue() || mCarCall[carIndexB].getValue()) { hallway = Hallway.BACK; } } else { if (mHallCall[hallIndexF].getValue() || mCarCall[carIndexF].getValue()) { hallway = Hallway.FRONT; } } } else { if (mHallCall[hallIndexB].getValue() || mCarCall[carIndexB].getValue()) { hallway = Hallway.BACK; } } /*if(promised_d != Direction.STOP && promised_d != curr_d ){ mDesiredFloor.setDirection(curr_d); }*/ // log("floor is ", floor, " next direction is ", direction, " current direction is", // curr_d); // System.out.println("Closed floor is " + floor + " next direction is " + direction + " // current direction is " + curr_d + " hallway " + hallway); // Now set the next target. // else{ mDesiredFloor.set(floor, direction, hallway); // } } break; // State actions for 'EMERGENCY' // #state State 3: Emergency case STATE_EMERGENCY: // System.out.println("emergency at supposedly" + curr_f + " but at postion " + // mCarLevelPosition.getPosition() + // " with desiredfloor " + // mDesiredFloor.getFloor()+mDesiredFloor.getHallway()+mDesiredFloor.getDirection()); floor = 1; hallway = Hallway.BOTH; direction = Direction.STOP; // Set the desired floor back down to the lobby! mDesiredFloor.set(floor, hallway, direction); // Once the doors have opened at the lobby, we can return to normal operation. // #transition 11.T.5 if (!mDoorClosed[ReplicationComputer.computeReplicationId(Hallway.FRONT, Side.LEFT)] .getValue() && mAtFloor[ReplicationComputer.computeReplicationId(1, Hallway.FRONT)].getValue()) newState = State.STATE_DOORSOPEN; else newState = state; break; default: throw new RuntimeException("State " + state + " was not recognized."); } /*log the results of this iteration if (state == newState) { log("remains in state: ",state); } else { log("Transition:",state,"->",newState); } */ // update the state variable state = newState; // report the current state setState(STATE_KEY, newState.toString()); // schedule the next iteration of the controller // you must do this at the end of the timer callback in order to restart // the timer timer.start(period); }