001 /*----------------------------------------------------------------------------*/
002 /* Copyright (c) FIRST 2008-2012. 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 package edu.wpi.first.wpilibj;
008
009 import com.sun.squawk.util.MathUtils;
010 import edu.wpi.first.wpilibj.communication.UsageReporting;
011 import edu.wpi.first.wpilibj.parsing.IInputOutput;
012
013 /**
014 * Handle input from standard Joysticks connected to the Driver Station.
015 * This class handles standard input that comes from the Driver Station. Each time a value is requested
016 * the most recent value is returned. There is a single class instance for each joystick and the mapping
017 * of ports to hardware buttons depends on the code in the driver station.
018 */
019 public class Joystick extends GenericHID implements IInputOutput{
020
021 static final byte kDefaultXAxis = 1;
022 static final byte kDefaultYAxis = 2;
023 static final byte kDefaultZAxis = 3;
024 static final byte kDefaultTwistAxis = 3;
025 static final byte kDefaultThrottleAxis = 4;
026 static final int kDefaultTriggerButton = 1;
027 static final int kDefaultTopButton = 2;
028
029 /**
030 * Represents an analog axis on a joystick.
031 */
032 public static class AxisType {
033
034 /**
035 * The integer value representing this enumeration
036 */
037 public final int value;
038 static final int kX_val = 0;
039 static final int kY_val = 1;
040 static final int kZ_val = 2;
041 static final int kTwist_val = 3;
042 static final int kThrottle_val = 4;
043 static final int kNumAxis_val = 5;
044 /**
045 * axis: x-axis
046 */
047 public static final AxisType kX = new AxisType(kX_val);
048 /**
049 * axis: y-axis
050 */
051 public static final AxisType kY = new AxisType(kY_val);
052 /**
053 * axis: z-axis
054 */
055 public static final AxisType kZ = new AxisType(kZ_val);
056 /**
057 * axis: twist
058 */
059 public static final AxisType kTwist = new AxisType(kTwist_val);
060 /**
061 * axis: throttle
062 */
063 public static final AxisType kThrottle = new AxisType(kThrottle_val);
064 /**
065 * axis: number of axis
066 */
067 public static final AxisType kNumAxis = new AxisType(kNumAxis_val);
068
069 private AxisType(int value) {
070 this.value = value;
071 }
072 }
073
074 /**
075 * Represents a digital button on the JoyStick
076 */
077 public static class ButtonType {
078
079 /**
080 * The integer value representing this enumeration
081 */
082 public final int value;
083 static final int kTrigger_val = 0;
084 static final int kTop_val = 1;
085 static final int kNumButton_val = 2;
086 /**
087 * button: trigger
088 */
089 public static final ButtonType kTrigger = new ButtonType((kTrigger_val));
090 /**
091 * button: top button
092 */
093 public static final ButtonType kTop = new ButtonType(kTop_val);
094 /**
095 * button: num button types
096 */
097 public static final ButtonType kNumButton = new ButtonType((kNumButton_val));
098
099 private ButtonType(int value) {
100 this.value = value;
101 }
102 }
103 private DriverStation m_ds;
104 private final int m_port;
105 private final byte[] m_axes;
106 private final byte[] m_buttons;
107
108 /**
109 * Construct an instance of a joystick.
110 * The joystick index is the usb port on the drivers station.
111 *
112 * @param port The port on the driver station that the joystick is plugged into.
113 */
114 public Joystick(final int port) {
115 this(port, AxisType.kNumAxis.value, ButtonType.kNumButton.value);
116
117 m_axes[AxisType.kX.value] = kDefaultXAxis;
118 m_axes[AxisType.kY.value] = kDefaultYAxis;
119 m_axes[AxisType.kZ.value] = kDefaultZAxis;
120 m_axes[AxisType.kTwist.value] = kDefaultTwistAxis;
121 m_axes[AxisType.kThrottle.value] = kDefaultThrottleAxis;
122
123 m_buttons[ButtonType.kTrigger.value] = kDefaultTriggerButton;
124 m_buttons[ButtonType.kTop.value] = kDefaultTopButton;
125
126 UsageReporting.report(UsageReporting.kResourceType_Joystick, port);
127 }
128
129 /**
130 * Protected version of the constructor to be called by sub-classes.
131 *
132 * This constructor allows the subclass to configure the number of constants
133 * for axes and buttons.
134 *
135 * @param port The port on the driver station that the joystick is plugged into.
136 * @param numAxisTypes The number of axis types in the enum.
137 * @param numButtonTypes The number of button types in the enum.
138 */
139 protected Joystick(int port, int numAxisTypes, int numButtonTypes) {
140 m_ds = DriverStation.getInstance();
141 m_axes = new byte[numAxisTypes];
142 m_buttons = new byte[numButtonTypes];
143 m_port = port;
144 }
145
146 /**
147 * Get the X value of the joystick.
148 * This depends on the mapping of the joystick connected to the current port.
149 *
150 * @param hand Unused
151 * @return The X value of the joystick.
152 */
153 public double getX(Hand hand) {
154 return getRawAxis(m_axes[AxisType.kX.value]);
155 }
156
157 /**
158 * Get the Y value of the joystick.
159 * This depends on the mapping of the joystick connected to the current port.
160 *
161 * @param hand Unused
162 * @return The Y value of the joystick.
163 */
164 public double getY(Hand hand) {
165 return getRawAxis(m_axes[AxisType.kY.value]);
166 }
167
168 /**
169 * Get the Z value of the joystick.
170 * This depends on the mapping of the joystick connected to the current port.
171 *
172 * @param hand Unused
173 * @return The Z value of the joystick.
174 */
175 public double getZ(Hand hand) {
176 return getRawAxis(m_axes[AxisType.kZ.value]);
177 }
178
179 /**
180 * Get the twist value of the current joystick.
181 * This depends on the mapping of the joystick connected to the current port.
182 *
183 * @return The Twist value of the joystick.
184 */
185 public double getTwist() {
186 return getRawAxis(m_axes[AxisType.kTwist.value]);
187 }
188
189 /**
190 * Get the throttle value of the current joystick.
191 * This depends on the mapping of the joystick connected to the current port.
192 *
193 * @return The Throttle value of the joystick.
194 */
195 public double getThrottle() {
196 return getRawAxis(m_axes[AxisType.kThrottle.value]);
197 }
198
199 /**
200 * Get the value of the axis.
201 *
202 * @param axis The axis to read [1-6].
203 * @return The value of the axis.
204 */
205 public double getRawAxis(final int axis) {
206 return m_ds.getStickAxis(m_port, axis);
207 }
208
209 /**
210 * For the current joystick, return the axis determined by the argument.
211 *
212 * This is for cases where the joystick axis is returned programatically, otherwise one of the
213 * previous functions would be preferable (for example getX()).
214 *
215 * @param axis The axis to read.
216 * @return The value of the axis.
217 */
218 public double getAxis(final AxisType axis) {
219 switch (axis.value) {
220 case AxisType.kX_val:
221 return getX();
222 case AxisType.kY_val:
223 return getY();
224 case AxisType.kZ_val:
225 return getZ();
226 case AxisType.kTwist_val:
227 return getTwist();
228 case AxisType.kThrottle_val:
229 return getThrottle();
230 default:
231 return 0.0;
232 }
233 }
234
235 /**
236 * Read the state of the trigger on the joystick.
237 *
238 * Look up which button has been assigned to the trigger and read its state.
239 *
240 * @param hand This parameter is ignored for the Joystick class and is only here to complete the GenericHID interface.
241 * @return The state of the trigger.
242 */
243 public boolean getTrigger(Hand hand) {
244 return getRawButton(m_buttons[ButtonType.kTrigger.value]);
245 }
246
247 /**
248 * Read the state of the top button on the joystick.
249 *
250 * Look up which button has been assigned to the top and read its state.
251 *
252 * @param hand This parameter is ignored for the Joystick class and is only here to complete the GenericHID interface.
253 * @return The state of the top button.
254 */
255 public boolean getTop(Hand hand) {
256 return getRawButton(m_buttons[ButtonType.kTop.value]);
257 }
258
259 /**
260 * This is not supported for the Joystick.
261 * This method is only here to complete the GenericHID interface.
262 *
263 * @param hand This parameter is ignored for the Joystick class and is only here to complete the GenericHID interface.
264 * @return The state of the bumper (always false)
265 */
266 public boolean getBumper(Hand hand) {
267 return false;
268 }
269
270 /**
271 * Get the button value for buttons 1 through 12.
272 *
273 * The buttons are returned in a single 16 bit value with one bit representing the state
274 * of each button. The appropriate button is returned as a boolean value.
275 *
276 * @param button The button number to be read.
277 * @return The state of the button.
278 */
279 public boolean getRawButton(final int button) {
280 return ((0x1 << (button - 1)) & m_ds.getStickButtons(m_port)) != 0;
281 }
282
283 /**
284 * Get buttons based on an enumerated type.
285 *
286 * The button type will be looked up in the list of buttons and then read.
287 *
288 * @param button The type of button to read.
289 * @return The state of the button.
290 */
291 public boolean getButton(ButtonType button) {
292 switch (button.value) {
293 case ButtonType.kTrigger_val:
294 return getTrigger();
295 case ButtonType.kTop_val:
296 return getTop();
297 default:
298 return false;
299 }
300 }
301
302 /**
303 * Get the magnitude of the direction vector formed by the joystick's
304 * current position relative to its origin
305 *
306 * @return The magnitude of the direction vector
307 */
308 public double getMagnitude() {
309 return Math.sqrt(MathUtils.pow(getX(), 2) + MathUtils.pow(getY(), 2));
310 }
311
312 /**
313 * Get the direction of the vector formed by the joystick and its origin
314 * in radians
315 *
316 * @return The direction of the vector in radians
317 */
318 public double getDirectionRadians() {
319 return MathUtils.atan2(getX(), -getY());
320 }
321
322 /**
323 * Get the direction of the vector formed by the joystick and its origin
324 * in degrees
325 *
326 * uses acos(-1) to represent Pi due to absence of readily accessable Pi
327 * constant in C++
328 *
329 * @return The direction of the vector in degrees
330 */
331 public double getDirectionDegrees() {
332 return Math.toDegrees(getDirectionRadians());
333 }
334
335 /**
336 * Get the channel currently associated with the specified axis.
337 *
338 * @param axis The axis to look up the channel for.
339 * @return The channel fr the axis.
340 */
341 public int getAxisChannel(AxisType axis) {
342 return m_axes[axis.value];
343 }
344
345 /**
346 * Set the channel associated with a specified axis.
347 *
348 * @param axis The axis to set the channel for.
349 * @param channel The channel to set the axis to.
350 */
351 public void setAxisChannel(AxisType axis, int channel) {
352 m_axes[axis.value] = (byte) channel;
353 }
354 }