/* * Copyright 2014-2016 Cel Skeggs * * This file is part of the CCRE, the Common Chicken Runtime Engine. * * The CCRE is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * The CCRE is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with the CCRE. If not, see <http://www.gnu.org/licenses/>. */ package ccre.frc.devices; import ccre.channel.BooleanInput; import ccre.channel.DerivedBooleanInput; import ccre.discrete.DerivedDiscreteInput; import ccre.discrete.DiscreteInput; import ccre.frc.Device; import ccre.frc.FRCMode; import ccre.frc.components.BooleanTextComponent; import ccre.frc.components.SpacingComponent; import ccre.frc.components.TextComponent; /** * A device allowing for changing the virtual robot's mode and * enabling/disabling it. * * @author skeggsc */ public class RobotModeDevice extends Device { // null, "AUTO", "TELE", "TEST" private final BooleanTextComponent enabled = new BooleanTextComponent("DISABLED", "ENABLED").setEditable(true); private final BooleanTextComponent autoLight = new BooleanTextComponent("AUTO") { @Override public void onPress(int x, int y) { setMode(FRCMode.AUTONOMOUS); } }; private final BooleanTextComponent teleLight = new BooleanTextComponent("TELE") { @Override public void onPress(int x, int y) { setMode(FRCMode.TELEOP); } }; private final BooleanTextComponent testLight = new BooleanTextComponent("TEST") { @Override public void onPress(int x, int y) { setMode(FRCMode.TEST); } }; // except for DISABLED private FRCMode selectedMode = FRCMode.TELEOP; private void setMode(FRCMode mode) { if (enabled.get()) { return;// Can't change mode while enabled. } this.selectedMode = mode; autoLight.safeSet(mode == FRCMode.AUTONOMOUS); teleLight.safeSet(mode == FRCMode.TELEOP); testLight.safeSet(mode == FRCMode.TEST); } /** * Create a new FRCModeDevice. */ public RobotModeDevice() { add(new SpacingComponent(20)); add(new TextComponent("Mode")); add(enabled); setMode(FRCMode.TELEOP); add(autoLight); add(teleLight); add(testLight); } /** * Return a BooleanInput representing if the robot is in the specified mode. * * @param mode the mode to monitor. * @return the channel representing if the robot is in that mode. */ public BooleanInput getIsMode(final FRCMode mode) { if (mode == FRCMode.DISABLED) { return enabled.asInput().not(); } else { return new DerivedBooleanInput(enabled.asInput()) { // updates only matter when enabled changes... the mode (and so // the result) can't change when the mode is enabled. // and when disabled, the result is false anyway... until // enabled becomes true. @Override protected boolean apply() { return enabled.get() && selectedMode == mode; } }; } } /** * Return a BooleanInput representing if the robot is enabled. * * @return the channel representing if the robot is enabled. */ public BooleanInput getIsEnabled() { return enabled.asInput(); } /** * Gets the mode as a discrete input, which will update as the mode changes. * * @return the discrete input for the robot control mode. */ public DiscreteInput<FRCMode> getMode() { return new DerivedDiscreteInput<FRCMode>(FRCMode.discreteType, enabled.asInput()) { @Override protected FRCMode apply() { return enabled.get() ? selectedMode : FRCMode.DISABLED; } }; } }