示例#1
0
 /** 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.");
   }
 }
示例#2
0
  @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);
  }