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.FRCNetComm.tResourceType;
008import edu.wpi.first.hal.HAL;
009
010/**
011 * Handle input from Flight Joysticks connected to the Driver Station.
012 *
013 * <p>This class handles standard input that comes from the Driver Station. Each time a value is
014 * requested the most recent value is returned. There is a single class instance for each joystick
015 * and the mapping of ports to hardware buttons depends on the code in the Driver Station.
016 */
017public class Joystick extends GenericHID {
018  public static final byte kDefaultXChannel = 0;
019  public static final byte kDefaultYChannel = 1;
020  public static final byte kDefaultZChannel = 2;
021  public static final byte kDefaultTwistChannel = 2;
022  public static final byte kDefaultThrottleChannel = 3;
023
024  /** Represents an analog axis on a joystick. */
025  public enum AxisType {
026    kX(0),
027    kY(1),
028    kZ(2),
029    kTwist(3),
030    kThrottle(4);
031
032    public final int value;
033
034    AxisType(int value) {
035      this.value = value;
036    }
037  }
038
039  /** Represents a digital button on a joystick. */
040  public enum ButtonType {
041    kTrigger(1),
042    kTop(2);
043
044    public final int value;
045
046    ButtonType(int value) {
047      this.value = value;
048    }
049  }
050
051  private final byte[] m_axes = new byte[AxisType.values().length];
052
053  /**
054   * Construct an instance of a joystick.
055   *
056   * @param port The port index on the Driver Station that the joystick is plugged into.
057   */
058  public Joystick(final int port) {
059    super(port);
060
061    m_axes[AxisType.kX.value] = kDefaultXChannel;
062    m_axes[AxisType.kY.value] = kDefaultYChannel;
063    m_axes[AxisType.kZ.value] = kDefaultZChannel;
064    m_axes[AxisType.kTwist.value] = kDefaultTwistChannel;
065    m_axes[AxisType.kThrottle.value] = kDefaultThrottleChannel;
066
067    HAL.report(tResourceType.kResourceType_Joystick, port + 1);
068  }
069
070  /**
071   * Set the channel associated with the X axis.
072   *
073   * @param channel The channel to set the axis to.
074   */
075  public void setXChannel(int channel) {
076    m_axes[AxisType.kX.value] = (byte) channel;
077  }
078
079  /**
080   * Set the channel associated with the Y axis.
081   *
082   * @param channel The channel to set the axis to.
083   */
084  public void setYChannel(int channel) {
085    m_axes[AxisType.kY.value] = (byte) channel;
086  }
087
088  /**
089   * Set the channel associated with the Z axis.
090   *
091   * @param channel The channel to set the axis to.
092   */
093  public void setZChannel(int channel) {
094    m_axes[AxisType.kZ.value] = (byte) channel;
095  }
096
097  /**
098   * Set the channel associated with the throttle axis.
099   *
100   * @param channel The channel to set the axis to.
101   */
102  public void setThrottleChannel(int channel) {
103    m_axes[AxisType.kThrottle.value] = (byte) channel;
104  }
105
106  /**
107   * Set the channel associated with the twist axis.
108   *
109   * @param channel The channel to set the axis to.
110   */
111  public void setTwistChannel(int channel) {
112    m_axes[AxisType.kTwist.value] = (byte) channel;
113  }
114
115  /**
116   * Get the channel currently associated with the X axis.
117   *
118   * @return The channel for the axis.
119   */
120  public int getXChannel() {
121    return m_axes[AxisType.kX.value];
122  }
123
124  /**
125   * Get the channel currently associated with the Y axis.
126   *
127   * @return The channel for the axis.
128   */
129  public int getYChannel() {
130    return m_axes[AxisType.kY.value];
131  }
132
133  /**
134   * Get the channel currently associated with the Z axis.
135   *
136   * @return The channel for the axis.
137   */
138  public int getZChannel() {
139    return m_axes[AxisType.kZ.value];
140  }
141
142  /**
143   * Get the channel currently associated with the twist axis.
144   *
145   * @return The channel for the axis.
146   */
147  public int getTwistChannel() {
148    return m_axes[AxisType.kTwist.value];
149  }
150
151  /**
152   * Get the channel currently associated with the throttle axis.
153   *
154   * @return The channel for the axis.
155   */
156  public int getThrottleChannel() {
157    return m_axes[AxisType.kThrottle.value];
158  }
159
160  /**
161   * Get the X value of the joystick. This depends on the mapping of the joystick connected to the
162   * current port.
163   *
164   * @return The X value of the joystick.
165   */
166  public final double getX() {
167    return getRawAxis(m_axes[AxisType.kX.value]);
168  }
169
170  /**
171   * Get the Y value of the joystick. This depends on the mapping of the joystick connected to the
172   * current port.
173   *
174   * @return The Y value of the joystick.
175   */
176  public final double getY() {
177    return getRawAxis(m_axes[AxisType.kY.value]);
178  }
179
180  /**
181   * Get the z position of the HID.
182   *
183   * @return the z position
184   */
185  public double getZ() {
186    return getRawAxis(m_axes[AxisType.kZ.value]);
187  }
188
189  /**
190   * Get the twist value of the current joystick. This depends on the mapping of the joystick
191   * connected to the current port.
192   *
193   * @return The Twist value of the joystick.
194   */
195  public double getTwist() {
196    return getRawAxis(m_axes[AxisType.kTwist.value]);
197  }
198
199  /**
200   * Get the throttle value of the current joystick. This depends on the mapping of the joystick
201   * connected to the current port.
202   *
203   * @return The Throttle value of the joystick.
204   */
205  public double getThrottle() {
206    return getRawAxis(m_axes[AxisType.kThrottle.value]);
207  }
208
209  /**
210   * Read the state of the trigger on the joystick.
211   *
212   * @return The state of the trigger.
213   */
214  public boolean getTrigger() {
215    return getRawButton(ButtonType.kTrigger.value);
216  }
217
218  /**
219   * Whether the trigger was pressed since the last check.
220   *
221   * @return Whether the button was pressed since the last check.
222   */
223  public boolean getTriggerPressed() {
224    return getRawButtonPressed(ButtonType.kTrigger.value);
225  }
226
227  /**
228   * Whether the trigger was released since the last check.
229   *
230   * @return Whether the button was released since the last check.
231   */
232  public boolean getTriggerReleased() {
233    return getRawButtonReleased(ButtonType.kTrigger.value);
234  }
235
236  /**
237   * Read the state of the top button on the joystick.
238   *
239   * @return The state of the top button.
240   */
241  public boolean getTop() {
242    return getRawButton(ButtonType.kTop.value);
243  }
244
245  /**
246   * Whether the top button was pressed since the last check.
247   *
248   * @return Whether the button was pressed since the last check.
249   */
250  public boolean getTopPressed() {
251    return getRawButtonPressed(ButtonType.kTop.value);
252  }
253
254  /**
255   * Whether the top button was released since the last check.
256   *
257   * @return Whether the button was released since the last check.
258   */
259  public boolean getTopReleased() {
260    return getRawButtonReleased(ButtonType.kTop.value);
261  }
262
263  /**
264   * Get the magnitude of the direction vector formed by the joystick's current position relative to
265   * its origin.
266   *
267   * @return The magnitude of the direction vector
268   */
269  public double getMagnitude() {
270    return Math.sqrt(Math.pow(getX(), 2) + Math.pow(getY(), 2));
271  }
272
273  /**
274   * Get the direction of the vector formed by the joystick and its origin in radians.
275   *
276   * @return The direction of the vector in radians
277   */
278  public double getDirectionRadians() {
279    return Math.atan2(getX(), -getY());
280  }
281
282  /**
283   * Get the direction of the vector formed by the joystick and its origin in degrees.
284   *
285   * @return The direction of the vector in degrees
286   */
287  public double getDirectionDegrees() {
288    return Math.toDegrees(getDirectionRadians());
289  }
290}