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.FRCNetComm.tResourceType;
011import edu.wpi.first.wpilibj.hal.HAL;
012
013/**
014 * Handle input from standard Joysticks connected to the Driver Station.
015 *
016 * <p>This class handles standard input that comes from the Driver Station. Each time a value is
017 * requested the most recent value is returned. There is a single class instance for each joystick
018 * and the mapping of ports to hardware buttons depends on the code in the Driver Station.
019 */
020public class Joystick extends GenericHID {
021  static final byte kDefaultXAxis = 0;
022  static final byte kDefaultYAxis = 1;
023  static final byte kDefaultZAxis = 2;
024  static final byte kDefaultTwistAxis = 2;
025  static final byte kDefaultThrottleAxis = 3;
026
027  /**
028   * Represents an analog axis on a joystick.
029   */
030  public enum AxisType {
031    kX(0), kY(1), kZ(2), kTwist(3), kThrottle(4);
032
033    @SuppressWarnings("MemberName")
034    public final int value;
035
036    AxisType(int value) {
037      this.value = value;
038    }
039  }
040
041  /**
042   * Represents a digital button on a joystick.
043   */
044  public enum ButtonType {
045    kTrigger(1), kTop(2);
046
047    @SuppressWarnings("MemberName")
048    public final int value;
049
050    ButtonType(int value) {
051      this.value = value;
052    }
053  }
054
055  /**
056   * Represents a digital button on a joystick.
057   */
058  private enum Button {
059    kTrigger(1), kTop(2);
060
061    @SuppressWarnings("MemberName")
062    public final int value;
063
064    Button(int value) {
065      this.value = value;
066    }
067  }
068
069  /**
070   * Represents an analog axis on a joystick.
071   */
072  private enum Axis {
073    kX(0), kY(1), kZ(2), kTwist(3), kThrottle(4), kNumAxes(5);
074
075    @SuppressWarnings("MemberName")
076    public final int value;
077
078    Axis(int value) {
079      this.value = value;
080    }
081  }
082
083  private final byte[] m_axes = new byte[Axis.kNumAxes.value];
084
085  /**
086   * Construct an instance of a joystick. The joystick index is the USB port on the drivers
087   * station.
088   *
089   * @param port The port on the Driver Station that the joystick is plugged into.
090   */
091  public Joystick(final int port) {
092    super(port);
093
094    m_axes[Axis.kX.value] = kDefaultXAxis;
095    m_axes[Axis.kY.value] = kDefaultYAxis;
096    m_axes[Axis.kZ.value] = kDefaultZAxis;
097    m_axes[Axis.kTwist.value] = kDefaultTwistAxis;
098    m_axes[Axis.kThrottle.value] = kDefaultThrottleAxis;
099
100    HAL.report(tResourceType.kResourceType_Joystick, port);
101  }
102
103  /**
104   * Set the channel associated with the X axis.
105   *
106   * @param channel The channel to set the axis to.
107   */
108  public void setXChannel(int channel) {
109    m_axes[Axis.kX.value] = (byte) channel;
110  }
111
112  /**
113   * Set the channel associated with the Y axis.
114   *
115   * @param channel The channel to set the axis to.
116   */
117  public void setYChannel(int channel) {
118    m_axes[Axis.kY.value] = (byte) channel;
119  }
120
121  /**
122   * Set the channel associated with the Z axis.
123   *
124   * @param channel The channel to set the axis to.
125   */
126  public void setZChannel(int channel) {
127    m_axes[Axis.kZ.value] = (byte) channel;
128  }
129
130  /**
131   * Set the channel associated with the throttle axis.
132   *
133   * @param channel The channel to set the axis to.
134   */
135  public void setThrottleChannel(int channel) {
136    m_axes[Axis.kThrottle.value] = (byte) channel;
137  }
138
139  /**
140   * Set the channel associated with the twist axis.
141   *
142   * @param channel The channel to set the axis to.
143   */
144  public void setTwistChannel(int channel) {
145    m_axes[Axis.kTwist.value] = (byte) channel;
146  }
147
148  /**
149   * Set the channel associated with a specified axis.
150   *
151   * @deprecated    Use the more specific axis channel setter functions.
152   * @param axis    The axis to set the channel for.
153   * @param channel The channel to set the axis to.
154   */
155  @Deprecated
156  public void setAxisChannel(AxisType axis, int channel) {
157    m_axes[axis.value] = (byte) channel;
158  }
159
160  /**
161   * Get the channel currently associated with the X axis.
162   *
163   * @return The channel for the axis.
164   */
165  public int getXChannel() {
166    return m_axes[Axis.kX.value];
167  }
168
169  /**
170   * Get the channel currently associated with the Y axis.
171   *
172   * @return The channel for the axis.
173   */
174  public int getYChannel() {
175    return m_axes[Axis.kY.value];
176  }
177
178  /**
179   * Get the channel currently associated with the Z axis.
180   *
181   * @return The channel for the axis.
182   */
183  public int getZChannel() {
184    return m_axes[Axis.kZ.value];
185  }
186
187  /**
188   * Get the channel currently associated with the twist axis.
189   *
190   * @return The channel for the axis.
191   */
192  public int getTwistChannel() {
193    return m_axes[Axis.kTwist.value];
194  }
195
196  /**
197   * Get the channel currently associated with the throttle axis.
198   *
199   * @return The channel for the axis.
200   */
201  public int getThrottleChannel() {
202    return m_axes[Axis.kThrottle.value];
203  }
204
205  /**
206   * Get the channel currently associated with the specified axis.
207   *
208   * @deprecated Use the more specific axis channel getter functions.
209   * @param axis The axis to look up the channel for.
210   * @return The channel for the axis.
211   */
212  @Deprecated
213  public int getAxisChannel(AxisType axis) {
214    return m_axes[axis.value];
215  }
216
217  /**
218   * Get the X value of the joystick. This depends on the mapping of the joystick connected to the
219   * current port.
220   *
221   * @param hand Unused
222   * @return The X value of the joystick.
223   */
224  @Override
225  public final double getX(Hand hand) {
226    return getRawAxis(m_axes[Axis.kX.value]);
227  }
228
229  /**
230   * Get the Y value of the joystick. This depends on the mapping of the joystick connected to the
231   * current port.
232   *
233   * @param hand Unused
234   * @return The Y value of the joystick.
235   */
236  @Override
237  public final double getY(Hand hand) {
238    return getRawAxis(m_axes[Axis.kY.value]);
239  }
240
241  /**
242   * Get the z position of the HID.
243   *
244   * @return the z position
245   */
246  public double getZ() {
247    return getRawAxis(m_axes[Axis.kZ.value]);
248  }
249
250  /**
251   * Get the twist value of the current joystick. This depends on the mapping of the joystick
252   * connected to the current port.
253   *
254   * @return The Twist value of the joystick.
255   */
256  public double getTwist() {
257    return getRawAxis(m_axes[Axis.kTwist.value]);
258  }
259
260  /**
261   * Get the throttle value of the current joystick. This depends on the mapping of the joystick
262   * connected to the current port.
263   *
264   * @return The Throttle value of the joystick.
265   */
266  public double getThrottle() {
267    return getRawAxis(m_axes[Axis.kThrottle.value]);
268  }
269
270  /**
271   * For the current joystick, return the axis determined by the argument.
272   *
273   * <p>This is for cases where the joystick axis is returned programmatically, otherwise one of the
274   * previous functions would be preferable (for example getX()).
275   *
276   * @deprecated Use the more specific axis getter functions.
277   * @param axis The axis to read.
278   * @return The value of the axis.
279   */
280  @Deprecated
281  public double getAxis(final AxisType axis) {
282    switch (axis) {
283      case kX:
284        return getX();
285      case kY:
286        return getY();
287      case kZ:
288        return getZ();
289      case kTwist:
290        return getTwist();
291      case kThrottle:
292        return getThrottle();
293      default:
294        return 0.0;
295    }
296  }
297
298  /**
299   * Read the state of the trigger on the joystick.
300   *
301   * @return The state of the trigger.
302   */
303  public boolean getTrigger() {
304    return getRawButton(Button.kTrigger.value);
305  }
306
307  /**
308   * Whether the trigger was pressed since the last check.
309   *
310   * @return Whether the button was pressed since the last check.
311   */
312  public boolean getTriggerPressed() {
313    return getRawButtonPressed(Button.kTrigger.value);
314  }
315
316  /**
317   * Whether the trigger was released since the last check.
318   *
319   * @return Whether the button was released since the last check.
320   */
321  public boolean getTriggerReleased() {
322    return getRawButtonReleased(Button.kTrigger.value);
323  }
324
325  /**
326   * Read the state of the top button on the joystick.
327   *
328   * @return The state of the top button.
329   */
330  public boolean getTop() {
331    return getRawButton(Button.kTop.value);
332  }
333
334  /**
335   * Whether the top button was pressed since the last check.
336   *
337   * @return Whether the button was pressed since the last check.
338   */
339  public boolean getTopPressed() {
340    return getRawButtonPressed(Button.kTop.value);
341  }
342
343  /**
344   * Whether the top button was released since the last check.
345   *
346   * @return Whether the button was released since the last check.
347   */
348  public boolean getTopReleased() {
349    return getRawButtonReleased(Button.kTop.value);
350  }
351
352  /**
353   * Get buttons based on an enumerated type.
354   *
355   * <p>The button type will be looked up in the list of buttons and then read.
356   *
357   * @deprecated Use Button enum values instead of ButtonType.
358   * @param button The type of button to read.
359   * @return The state of the button.
360   */
361  @Deprecated
362  public boolean getButton(ButtonType button) {
363    return getRawButton(button.value);
364  }
365
366  /**
367   * Get the magnitude of the direction vector formed by the joystick's current position relative to
368   * its origin.
369   *
370   * @return The magnitude of the direction vector
371   */
372  public double getMagnitude() {
373    return Math.sqrt(Math.pow(getX(), 2) + Math.pow(getY(), 2));
374  }
375
376  /**
377   * Get the direction of the vector formed by the joystick and its origin in radians.
378   *
379   * @return The direction of the vector in radians
380   */
381  public double getDirectionRadians() {
382    return Math.atan2(getX(), -getY());
383  }
384
385  /**
386   * Get the direction of the vector formed by the joystick and its origin in degrees.
387   *
388   * @return The direction of the vector in degrees
389   */
390  public double getDirectionDegrees() {
391    return Math.toDegrees(getDirectionRadians());
392  }
393}