package com.team254.frc2015.behavior.routines;
import com.team254.frc2015.behavior.Commands;
import com.team254.frc2015.behavior.RobotSetpoints;
import com.team254.lib.util.Latch;
import com.team254.lib.util.TimeDelayedBoolean;
import edu.wpi.first.wpilibj.Timer;
import java.util.Optional;
public class FloorLoadRoutine extends Routine {
public enum States {
START, MOVE_TO_STARTING_POS, WAIT_FOR_TOTE, CLAMP, MOVE_DOWN, MOVE_UP, PUSH_TOP_DOWN, DONE
}
private States m_state = States.START;
private boolean m_is_new_state = true;
Timer m_state_timer = new Timer();
private static final double TOTE_CLEAR_POS = 18.5;
private static final double WHEEL_CUTOFF_HEIGHT = 15;
private static final double REGRASP_POS = 10;
private static final double TOTE_GRAB_POS = 1.0;
private boolean m_moved_down_once = false;
private Latch m_top_carriage_init_latch = new Latch();
private TimeDelayedBoolean m_stalled_motor = new TimeDelayedBoolean();
@Override
public void reset() {
m_state = States.START;
m_is_new_state = true;
m_state_timer.start();
m_state_timer.reset();
m_moved_down_once = false;
}
@Override
public RobotSetpoints update(Commands commands, RobotSetpoints setpoints) {
States new_state = m_state;
boolean do_squeeze = true;
if (m_state != States.START && m_state != States.MOVE_TO_STARTING_POS) {
setpoints.intake_action = RobotSetpoints.IntakeAction.CLOSE;
}
setpoints.roller_action = RobotSetpoints.RollerAction.INTAKE;
boolean should_vent = false;
switch (m_state) {
case START:
new_state = States.MOVE_TO_STARTING_POS;
do_squeeze = false;
break;
case MOVE_TO_STARTING_POS:
if (m_is_new_state) {
setpoints.m_elevator_setpoints.bottom_setpoint = Optional.of(TOTE_CLEAR_POS);
setpoints.m_elevator_setpoints.top_setpoint = Optional.of(TOTE_CLEAR_POS + 12.0);
}
if (!m_is_new_state && bottom_carriage.isOnTarget() || m_state_timer.get() > 2.0) {
new_state = States.WAIT_FOR_TOTE;
}
if (m_top_carriage_init_latch.update(top_carriage.getBreakbeamTriggered())) {
m_moved_down_once = true;
}
do_squeeze = m_moved_down_once;
break;
case WAIT_FOR_TOTE:
do_squeeze = m_moved_down_once;
if (intake.getBreakbeamTriggered()) {
new_state = States.MOVE_DOWN;
}
break;
case CLAMP:
do_squeeze = false;
setpoints.bottom_open_loop_jog = Optional.of(0.0);
if (m_state_timer.get() > .15) {
new_state = States.WAIT_FOR_TOTE;
setpoints.top_open_loop_jog = Optional.of(0.0);
} else {
setpoints.top_open_loop_jog = Optional.of(-.55);
}
break;
case MOVE_DOWN:
if (m_is_new_state) {
bottom_carriage.setFastPositionSetpoint(TOTE_GRAB_POS);
}
if (m_moved_down_once && (bottom_carriage.isOnTarget() || m_state_timer.get() > 2.0)) {
new_state = States.MOVE_UP;
}
if (!m_moved_down_once && bottom_carriage.isOnTarget() && (top_carriage.getHeight() < 5.25 || m_state_timer.get() > .8)) {
new_state = States.MOVE_UP;
}
should_vent = (!m_moved_down_once && top_carriage.getHeight() < 10);
break;
case MOVE_UP:
if (m_is_new_state) {
bottom_carriage.setFastPositionSetpoint(TOTE_CLEAR_POS);
}
if (bottom_carriage.getHeight() < WHEEL_CUTOFF_HEIGHT) {
setpoints.roller_action = RobotSetpoints.RollerAction.STOP;
}
if (bottom_carriage.isOnTarget() || m_state_timer.get() > 2.0) {
m_moved_down_once = true;
new_state = States.CLAMP;
}
if (top_carriage.getHeight() - bottom_carriage.getHeight() < 1.9 && !top_carriage.getBreakbeamTriggered()) {
new_state = States.MOVE_TO_STARTING_POS;
}
should_vent = !m_moved_down_once && (bottom_carriage.getHeight() < REGRASP_POS);
break;
case PUSH_TOP_DOWN:
do_squeeze = false;
setpoints.bottom_open_loop_jog = Optional.of(0.0);
if (m_state_timer.get() > .15) {
new_state = States.DONE;
setpoints.top_open_loop_jog = Optional.of(0.0);
} else {
setpoints.top_open_loop_jog = Optional.of(-.55);
}
break;
case DONE:
if (m_is_new_state) {
setpoints.bottom_open_loop_jog = Optional.of(0.0);
}
// Just in case
if (bottom_carriage.getHeight() >= (TOTE_CLEAR_POS - 5.0) && intake.getBreakbeamTriggered()) {
new_state = States.MOVE_DOWN;
}
break;
}
if (commands.roller_request == Commands.RollerRequest.INTAKE) {
setpoints.roller_action = RobotSetpoints.RollerAction.STOP;
} else if (commands.roller_request == Commands.RollerRequest.EXHAUST) {
setpoints.roller_action = RobotSetpoints.RollerAction.EXHAUST;
}
if (m_state != States.MOVE_TO_STARTING_POS) {
m_top_carriage_init_latch.update(false);
}
if (m_state == States.MOVE_UP && bottom_carriage.fastHitTop()) {
System.out.println("Hit top - floor load, moving to DONE");
new_state = States.PUSH_TOP_DOWN;
}
if (m_stalled_motor.update(m_state == States.MOVE_UP && bottom_carriage.getEncoderVelocity() < 5.0, 1.25)) {
System.out.println("Stalled motor!");
new_state = States.DONE;
}
setpoints.top_carriage_squeeze = do_squeeze && !setpoints.top_open_loop_jog.isPresent();
setpoints.claw_action = should_vent ? RobotSetpoints.TopCarriageClawAction.NEUTRAL : RobotSetpoints.TopCarriageClawAction.CLOSE;
m_is_new_state = false;
if (new_state != m_state) {
m_state = new_state;
m_state_timer.reset();
m_is_new_state = true;
}
return setpoints;
}
public boolean isDoneWithSixStack() {
return m_state == States.DONE;
}
@Override
public void cancel() {
}
@Override
public boolean isFinished() {
return false;
}
@Override
public String getName() {
return "Floor load";
}
}