001/*----------------------------------------------------------------------------*/
002/* Copyright (c) FIRST 2016-2017. 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.FRCNetComm.tResourceType;
011import edu.wpi.first.wpilibj.hal.HAL;
012
013/**
014 * Handle input from Xbox 360 or Xbox One controllers connected to the Driver Station.
015 *
016 * <p>This class handles Xbox input that comes from the Driver Station. Each time a value is
017 * requested the most recent value is returend. There is a single class instance for each controller
018 * and the mapping of ports to hardware buttons depends on the code in the Driver Station.
019 */
020public class XboxController extends GamepadBase {
021  private DriverStation m_ds;
022  private int m_outputs;
023  private short m_leftRumble;
024  private short m_rightRumble;
025
026  /**
027   * Construct an instance of a joystick. The joystick index is the USB port on the drivers
028   * station.
029   *
030   * @param port The port on the Driver Station that the joystick is plugged into.
031   */
032  public XboxController(final int port) {
033    super(port);
034    m_ds = DriverStation.getInstance();
035
036    // HAL.report(tResourceType.kResourceType_XboxController, port);
037    HAL.report(tResourceType.kResourceType_Joystick, port);
038  }
039
040  /**
041   * Get the X axis value of the controller.
042   *
043   * @param hand Side of controller whose value should be returned.
044   * @return The X axis value of the controller.
045   */
046  @Override
047  public double getX(Hand hand) {
048    if (hand.equals(Hand.kLeft)) {
049      return getRawAxis(0);
050    } else {
051      return getRawAxis(4);
052    }
053  }
054
055  /**
056   * Get the Y axis value of the controller.
057   *
058   * @param hand Side of controller whose value should be returned.
059   * @return The Y axis value of the controller.
060   */
061  @Override
062  public double getY(Hand hand) {
063    if (hand.equals(Hand.kLeft)) {
064      return getRawAxis(1);
065    } else {
066      return getRawAxis(5);
067    }
068  }
069
070  /**
071   * Get the value of the axis.
072   *
073   * @param axis The axis to read, starting at 0.
074   * @return The value of the axis.
075   */
076  public double getRawAxis(final int axis) {
077    return m_ds.getStickAxis(getPort(), axis);
078  }
079
080  /**
081   * Read the value of the bumper button on the controller.
082   *
083   * @param hand Side of controller whose value should be returned.
084   * @return The state of the button.
085   */
086  @Override
087  public boolean getBumper(Hand hand) {
088    if (hand.equals(Hand.kLeft)) {
089      return getRawButton(5);
090    } else {
091      return getRawButton(6);
092    }
093  }
094
095  /**
096   * This is not supported for the XboxController. This method is only here to complete the
097   * GenericHID interface.
098   *
099   * @param hand This parameter is ignored for the Joystick class and is only here to complete the
100   *             GenericHID interface.
101   * @return The state of the trigger (always false)
102   */
103  @SuppressWarnings("PMD.UnusedFormalParameter")
104  public boolean getTrigger(Hand hand) {
105    return false;
106  }
107
108  /**
109   * This is not supported for the XboxController. This method is only here to complete the
110   * GenericHID interface.
111   *
112   * @param hand This parameter is ignored for the Joystick class and is only here to complete the
113   *             GenericHID interface.
114   * @return The state of the top button (always false)
115   */
116  @SuppressWarnings("PMD.UnusedFormalParameter")
117  public boolean getTop(Hand hand) {
118    return false;
119  }
120
121  /**
122   * Get the button value (starting at button 1).
123   *
124   * <p>The appropriate button is returned as a boolean value.
125   *
126   * @param button The button number to be read (starting at 1).
127   * @return The state of the button.
128   */
129  public boolean getRawButton(final int button) {
130    return m_ds.getStickButton(getPort(), (byte) button);
131  }
132
133  /**
134   * Get the trigger axis value of the controller.
135   *
136   * @param hand Side of controller whose value should be returned.
137   * @return The trigger axis value of the controller.
138   */
139  public double getTriggerAxis(Hand hand) {
140    if (hand.equals(Hand.kLeft)) {
141      return getRawAxis(2);
142    } else {
143      return getRawAxis(3);
144    }
145  }
146
147  /**
148   * Read the value of the A button on the controller.
149   *
150   * @return The state of the button.
151   */
152  public boolean getAButton() {
153    return getRawButton(1);
154  }
155
156  /**
157   * Read the value of the B button on the controller.
158   *
159   * @return The state of the button.
160   */
161  public boolean getBButton() {
162    return getRawButton(2);
163  }
164
165  /**
166   * Read the value of the X button on the controller.
167   *
168   * @return The state of the button.
169   */
170  public boolean getXButton() {
171    return getRawButton(3);
172  }
173
174  /**
175   * Read the value of the Y button on the controller.
176   *
177   * @return The state of the button.
178   */
179  public boolean getYButton() {
180    return getRawButton(4);
181  }
182
183  /**
184   * Read the value of the stick button on the controller.
185   *
186   * @param hand Side of controller whose value should be returned.
187   * @return The state of the button.
188   */
189  @Override
190  public boolean getStickButton(Hand hand) {
191    if (hand.equals(Hand.kLeft)) {
192      return getRawButton(9);
193    } else {
194      return getRawButton(10);
195    }
196  }
197
198  /**
199   * Read the value of the back button on the controller.
200   *
201   * @return The state of the button.
202   */
203  public boolean getBackButton() {
204    return getRawButton(7);
205  }
206
207  /**
208   * Read the value of the start button on the controller.
209   *
210   * @return The state of the button.
211   */
212  public boolean getStartButton() {
213    return getRawButton(8);
214  }
215
216  @Override
217  public int getPOV(int pov) {
218    return m_ds.getStickPOV(getPort(), pov);
219  }
220
221  @Override
222  public int getPOVCount() {
223    return m_ds.getStickPOVCount(getPort());
224  }
225
226  @Override
227  public HIDType getType() {
228    return HIDType.values()[m_ds.getJoystickType(getPort())];
229  }
230
231  @Override
232  public String getName() {
233    return m_ds.getJoystickName(getPort());
234  }
235
236  @Override
237  public void setOutput(int outputNumber, boolean value) {
238    m_outputs = (m_outputs & ~(1 << (outputNumber - 1))) | ((value ? 1 : 0) << (outputNumber - 1));
239    HAL.setJoystickOutputs((byte) getPort(), m_outputs, m_leftRumble, m_rightRumble);
240  }
241
242  @Override
243  public void setOutputs(int value) {
244    m_outputs = value;
245    HAL.setJoystickOutputs((byte) getPort(), m_outputs, m_leftRumble, m_rightRumble);
246  }
247
248  @Override
249  public void setRumble(RumbleType type, double value) {
250    if (value < 0) {
251      value = 0;
252    } else if (value > 1) {
253      value = 1;
254    }
255    if (type == RumbleType.kLeftRumble) {
256      m_leftRumble = (short) (value * 65535);
257    } else {
258      m_rightRumble = (short) (value * 65535);
259    }
260    HAL.setJoystickOutputs((byte) getPort(), m_outputs, m_leftRumble, m_rightRumble);
261  }
262}