001/*----------------------------------------------------------------------------*/
002/* Copyright (c) 2008-2018 FIRST. All Rights Reserved.                        */
003/* Open Source Software - may be modified and shared by FRC teams. The code   */
004/* must be accompanied by the FIRST BSD license file in the root directory of */
005/* the project.                                                               */
006/*----------------------------------------------------------------------------*/
007
008package edu.wpi.first.wpilibj;
009
010import edu.wpi.first.wpilibj.hal.HAL;
011
012/**
013 * GenericHID Interface.
014 */
015public abstract class GenericHID {
016  /**
017   * Represents a rumble output on the JoyStick.
018   */
019  public enum RumbleType {
020    kLeftRumble, kRightRumble
021  }
022
023  public enum HIDType {
024    kUnknown(-1),
025    kXInputUnknown(0),
026    kXInputGamepad(1),
027    kXInputWheel(2),
028    kXInputArcadeStick(3),
029    kXInputFlightStick(4),
030    kXInputDancePad(5),
031    kXInputGuitar(6),
032    kXInputGuitar2(7),
033    kXInputDrumKit(8),
034    kXInputGuitar3(11),
035    kXInputArcadePad(19),
036    kHIDJoystick(20),
037    kHIDGamepad(21),
038    kHIDDriving(22),
039    kHIDFlight(23),
040    kHID1stPerson(24);
041
042    @SuppressWarnings("MemberName")
043    public final int value;
044
045    HIDType(int value) {
046      this.value = value;
047    }
048  }
049
050  /**
051   * Which hand the Human Interface Device is associated with.
052   */
053  public enum Hand {
054    kLeft(0), kRight(1);
055
056    @SuppressWarnings("MemberName")
057    public final int value;
058
059    Hand(int value) {
060      this.value = value;
061    }
062  }
063
064  private DriverStation m_ds;
065  private final int m_port;
066  private int m_outputs;
067  private short m_leftRumble;
068  private short m_rightRumble;
069
070  public GenericHID(int port) {
071    m_ds = DriverStation.getInstance();
072    m_port = port;
073  }
074
075  /**
076   * Get the x position of the HID.
077   *
078   * @return the x position of the HID
079   */
080  public final double getX() {
081    return getX(Hand.kRight);
082  }
083
084  /**
085   * Get the x position of HID.
086   *
087   * @param hand which hand, left or right
088   * @return the x position
089   */
090  public abstract double getX(Hand hand);
091
092  /**
093   * Get the y position of the HID.
094   *
095   * @return the y position
096   */
097  public final double getY() {
098    return getY(Hand.kRight);
099  }
100
101  /**
102   * Get the y position of the HID.
103   *
104   * @param hand which hand, left or right
105   * @return the y position
106   */
107  public abstract double getY(Hand hand);
108
109  /**
110   * Get the button value (starting at button 1).
111   *
112   * <p>The buttons are returned in a single 16 bit value with one bit representing the state of
113   * each button. The appropriate button is returned as a boolean value.
114   *
115   * @param button The button number to be read (starting at 1)
116   * @return The state of the button.
117   */
118  public boolean getRawButton(int button) {
119    return m_ds.getStickButton(m_port, (byte) button);
120  }
121
122  /**
123   * Whether the button was pressed since the last check. Button indexes begin at
124   * 1.
125   *
126   * @param button The button index, beginning at 1.
127   * @return Whether the button was pressed since the last check.
128   */
129  public boolean getRawButtonPressed(int button) {
130    return m_ds.getStickButtonPressed(m_port, (byte) button);
131  }
132
133  /**
134   * Whether the button was released since the last check. Button indexes begin at
135   * 1.
136   *
137   * @param button The button index, beginning at 1.
138   * @return Whether the button was released since the last check.
139   */
140  public boolean getRawButtonReleased(int button) {
141    return m_ds.getStickButtonReleased(m_port, button);
142  }
143
144  /**
145   * Get the value of the axis.
146   *
147   * @param axis The axis to read, starting at 0.
148   * @return The value of the axis.
149   */
150  public double getRawAxis(int axis) {
151    return m_ds.getStickAxis(m_port, axis);
152  }
153
154  /**
155   * Get the angle in degrees of a POV on the HID.
156   *
157   * <p>The POV angles start at 0 in the up direction, and increase clockwise (eg right is 90,
158   * upper-left is 315).
159   *
160   * @param pov The index of the POV to read (starting at 0)
161   * @return the angle of the POV in degrees, or -1 if the POV is not pressed.
162   */
163  public int getPOV(int pov) {
164    return m_ds.getStickPOV(m_port, pov);
165  }
166
167  public int getPOV() {
168    return getPOV(0);
169  }
170
171  /**
172   * Get the number of axes for the HID.
173   *
174   * @return the number of axis for the current HID
175   */
176  public int getAxisCount() {
177    return m_ds.getStickAxisCount(m_port);
178  }
179
180  /**
181   * For the current HID, return the number of POVs.
182   */
183  public int getPOVCount() {
184    return m_ds.getStickPOVCount(m_port);
185  }
186
187  /**
188   * For the current HID, return the number of buttons.
189   */
190  public int getButtonCount() {
191    return m_ds.getStickButtonCount(m_port);
192  }
193
194  /**
195   * Get the type of the HID.
196   *
197   * @return the type of the HID.
198   */
199  public HIDType getType() {
200    return HIDType.values()[m_ds.getJoystickType(m_port)];
201  }
202
203  /**
204   * Get the name of the HID.
205   *
206   * @return the name of the HID.
207   */
208  public String getName() {
209    return m_ds.getJoystickName(m_port);
210  }
211
212  /**
213   * Get the axis type of a joystick axis.
214   *
215   * @return the axis type of a joystick axis.
216   */
217  public int getAxisType(int axis) {
218    return m_ds.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}