001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.wpilibj; 006 007import edu.wpi.first.hal.HAL; 008import java.util.HashMap; 009import java.util.Map; 010 011/** 012 * Handle input from standard HID devices connected to the Driver Station. 013 * 014 * <p>This class handles standard input that comes from the Driver Station. Each time a value is 015 * requested the most recent value is returned. There is a single class instance for each device and 016 * the mapping of ports to hardware buttons depends on the code in the Driver Station. 017 */ 018public class GenericHID { 019 /** Represents a rumble output on the JoyStick. */ 020 public enum RumbleType { 021 kLeftRumble, 022 kRightRumble 023 } 024 025 public enum HIDType { 026 kUnknown(-1), 027 kXInputUnknown(0), 028 kXInputGamepad(1), 029 kXInputWheel(2), 030 kXInputArcadeStick(3), 031 kXInputFlightStick(4), 032 kXInputDancePad(5), 033 kXInputGuitar(6), 034 kXInputGuitar2(7), 035 kXInputDrumKit(8), 036 kXInputGuitar3(11), 037 kXInputArcadePad(19), 038 kHIDJoystick(20), 039 kHIDGamepad(21), 040 kHIDDriving(22), 041 kHIDFlight(23), 042 kHID1stPerson(24); 043 044 public final int value; 045 046 @SuppressWarnings("PMD.UseConcurrentHashMap") 047 private static final Map<Integer, HIDType> map = new HashMap<>(); 048 049 HIDType(int value) { 050 this.value = value; 051 } 052 053 static { 054 for (HIDType hidType : HIDType.values()) { 055 map.put(hidType.value, hidType); 056 } 057 } 058 059 public static HIDType of(int value) { 060 return map.get(value); 061 } 062 } 063 064 private final int m_port; 065 private int m_outputs; 066 private short m_leftRumble; 067 private short m_rightRumble; 068 069 /** 070 * Construct an instance of a device. 071 * 072 * @param port The port index on the Driver Station that the device is plugged into. 073 */ 074 public GenericHID(int port) { 075 m_port = port; 076 } 077 078 /** 079 * Get the button value (starting at button 1). 080 * 081 * <p>The buttons are returned in a single 16 bit value with one bit representing the state of 082 * each button. The appropriate button is returned as a boolean value. 083 * 084 * <p>This method returns true if the button is being held down at the time that this method is 085 * being called. 086 * 087 * @param button The button number to be read (starting at 1) 088 * @return The state of the button. 089 */ 090 public boolean getRawButton(int button) { 091 return DriverStation.getStickButton(m_port, (byte) button); 092 } 093 094 /** 095 * Whether the button was pressed since the last check. Button indexes begin at 1. 096 * 097 * <p>This method returns true if the button went from not pressed to held down since the last 098 * time this method was called. This is useful if you only want to call a function once when you 099 * press the button. 100 * 101 * @param button The button index, beginning at 1. 102 * @return Whether the button was pressed since the last check. 103 */ 104 public boolean getRawButtonPressed(int button) { 105 return DriverStation.getStickButtonPressed(m_port, (byte) button); 106 } 107 108 /** 109 * Whether the button was released since the last check. Button indexes begin at 1. 110 * 111 * <p>This method returns true if the button went from held down to not pressed since the last 112 * time this method was called. This is useful if you only want to call a function once when you 113 * release the button. 114 * 115 * @param button The button index, beginning at 1. 116 * @return Whether the button was released since the last check. 117 */ 118 public boolean getRawButtonReleased(int button) { 119 return DriverStation.getStickButtonReleased(m_port, button); 120 } 121 122 /** 123 * Get the value of the axis. 124 * 125 * @param axis The axis to read, starting at 0. 126 * @return The value of the axis. 127 */ 128 public double getRawAxis(int axis) { 129 return DriverStation.getStickAxis(m_port, axis); 130 } 131 132 /** 133 * Get the angle in degrees of a POV on the HID. 134 * 135 * <p>The POV angles start at 0 in the up direction, and increase clockwise (eg right is 90, 136 * upper-left is 315). 137 * 138 * @param pov The index of the POV to read (starting at 0). Defaults to 0. 139 * @return the angle of the POV in degrees, or -1 if the POV is not pressed. 140 */ 141 public int getPOV(int pov) { 142 return DriverStation.getStickPOV(m_port, pov); 143 } 144 145 /** 146 * Get the angle in degrees of the default POV (index 0) on the HID. 147 * 148 * <p>The POV angles start at 0 in the up direction, and increase clockwise (eg right is 90, 149 * upper-left is 315). 150 * 151 * @return the angle of the POV in degrees, or -1 if the POV is not pressed. 152 */ 153 public int getPOV() { 154 return getPOV(0); 155 } 156 157 /** 158 * Get the number of axes for the HID. 159 * 160 * @return the number of axis for the current HID 161 */ 162 public int getAxisCount() { 163 return DriverStation.getStickAxisCount(m_port); 164 } 165 166 /** 167 * For the current HID, return the number of POVs. 168 * 169 * @return the number of POVs for the current HID 170 */ 171 public int getPOVCount() { 172 return DriverStation.getStickPOVCount(m_port); 173 } 174 175 /** 176 * For the current HID, return the number of buttons. 177 * 178 * @return the number of buttons for the current HID 179 */ 180 public int getButtonCount() { 181 return DriverStation.getStickButtonCount(m_port); 182 } 183 184 /** 185 * Get if the HID is connected. 186 * 187 * @return true if the HID is connected 188 */ 189 public boolean isConnected() { 190 return DriverStation.isJoystickConnected(m_port); 191 } 192 193 /** 194 * Get the type of the HID. 195 * 196 * @return the type of the HID. 197 */ 198 public HIDType getType() { 199 return HIDType.of(DriverStation.getJoystickType(m_port)); 200 } 201 202 /** 203 * Get the name of the HID. 204 * 205 * @return the name of the HID. 206 */ 207 public String getName() { 208 return DriverStation.getJoystickName(m_port); 209 } 210 211 /** 212 * Get the axis type of a joystick axis. 213 * 214 * @param axis The axis to read, starting at 0. 215 * @return the axis type of a joystick axis. 216 */ 217 public int getAxisType(int axis) { 218 return DriverStation.getJoystickAxisType(m_port, axis); 219 } 220 221 /** 222 * Get the port number of the HID. 223 * 224 * @return The port number of the HID. 225 */ 226 public int getPort() { 227 return m_port; 228 } 229 230 /** 231 * Set a single HID output value for the HID. 232 * 233 * @param outputNumber The index of the output to set (1-32) 234 * @param value The value to set the output to 235 */ 236 public void setOutput(int outputNumber, boolean value) { 237 m_outputs = (m_outputs & ~(1 << (outputNumber - 1))) | ((value ? 1 : 0) << (outputNumber - 1)); 238 HAL.setJoystickOutputs((byte) m_port, m_outputs, m_leftRumble, m_rightRumble); 239 } 240 241 /** 242 * Set all HID output values for the HID. 243 * 244 * @param value The 32 bit output value (1 bit for each output) 245 */ 246 public void setOutputs(int value) { 247 m_outputs = value; 248 HAL.setJoystickOutputs((byte) m_port, m_outputs, m_leftRumble, m_rightRumble); 249 } 250 251 /** 252 * Set the rumble output for the HID. The DS currently supports 2 rumble values, left rumble and 253 * right rumble. 254 * 255 * @param type Which rumble value to set 256 * @param value The normalized value (0 to 1) to set the rumble to 257 */ 258 public void setRumble(RumbleType type, double value) { 259 if (value < 0) { 260 value = 0; 261 } else if (value > 1) { 262 value = 1; 263 } 264 if (type == RumbleType.kLeftRumble) { 265 m_leftRumble = (short) (value * 65535); 266 } else { 267 m_rightRumble = (short) (value * 65535); 268 } 269 HAL.setJoystickOutputs((byte) m_port, m_outputs, m_leftRumble, m_rightRumble); 270 } 271}