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/*----------------------------------------------------------------------------*/ 007package edu.wpi.first.wpilibj; 008 009import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType; 010import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary; 011import edu.wpi.first.wpilibj.communication.UsageReporting; 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 */ 019public class Joystick extends GenericHID { 020 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 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 104 105 /** 106 * Represents a rumble output on the JoyStick 107 */ 108 public static class RumbleType { 109 110 /** 111 * The integer value representing this enumeration 112 */ 113 public final int value; 114 static final int kLeftRumble_val = 0; 115 static final int kRightRumble_val = 1; 116 /** 117 * Left Rumble 118 */ 119 public static final RumbleType kLeftRumble = new RumbleType((kLeftRumble_val)); 120 /** 121 * Right Rumble 122 */ 123 public static final RumbleType kRightRumble = new RumbleType(kRightRumble_val); 124 125 private RumbleType(int value) { 126 this.value = value; 127 } 128 } 129 130 private DriverStation m_ds; 131 private final int m_port; 132 private final byte[] m_axes; 133 private final byte[] m_buttons; 134 private int m_outputs; 135 private short m_leftRumble; 136 private short m_rightRumble; 137 138 /** 139 * Construct an instance of a joystick. 140 * The joystick index is the usb port on the drivers station. 141 * 142 * @param port The port on the driver station that the joystick is plugged into. 143 */ 144 public Joystick(final int port) { 145 this(port, AxisType.kNumAxis.value, ButtonType.kNumButton.value); 146 147 m_axes[AxisType.kX.value] = kDefaultXAxis; 148 m_axes[AxisType.kY.value] = kDefaultYAxis; 149 m_axes[AxisType.kZ.value] = kDefaultZAxis; 150 m_axes[AxisType.kTwist.value] = kDefaultTwistAxis; 151 m_axes[AxisType.kThrottle.value] = kDefaultThrottleAxis; 152 153 m_buttons[ButtonType.kTrigger.value] = kDefaultTriggerButton; 154 m_buttons[ButtonType.kTop.value] = kDefaultTopButton; 155 156 UsageReporting.report(tResourceType.kResourceType_Joystick, port); 157 } 158 159 /** 160 * Protected version of the constructor to be called by sub-classes. 161 * 162 * This constructor allows the subclass to configure the number of constants 163 * for axes and buttons. 164 * 165 * @param port The port on the driver station that the joystick is plugged into. 166 * @param numAxisTypes The number of axis types in the enum. 167 * @param numButtonTypes The number of button types in the enum. 168 */ 169 protected Joystick(int port, int numAxisTypes, int numButtonTypes) { 170 m_ds = DriverStation.getInstance(); 171 m_axes = new byte[numAxisTypes]; 172 m_buttons = new byte[numButtonTypes]; 173 m_port = port; 174 } 175 176 /** 177 * Get the X value of the joystick. 178 * This depends on the mapping of the joystick connected to the current port. 179 * 180 * @param hand Unused 181 * @return The X value of the joystick. 182 */ 183 public double getX(Hand hand) { 184 return getRawAxis(m_axes[AxisType.kX.value]); 185 } 186 187 /** 188 * Get the Y value of the joystick. 189 * This depends on the mapping of the joystick connected to the current port. 190 * 191 * @param hand Unused 192 * @return The Y value of the joystick. 193 */ 194 public double getY(Hand hand) { 195 return getRawAxis(m_axes[AxisType.kY.value]); 196 } 197 198 /** 199 * Get the Z value of the joystick. 200 * This depends on the mapping of the joystick connected to the current port. 201 * 202 * @param hand Unused 203 * @return The Z value of the joystick. 204 */ 205 public double getZ(Hand hand) { 206 return getRawAxis(m_axes[AxisType.kZ.value]); 207 } 208 209 /** 210 * Get the twist value of the current joystick. 211 * This depends on the mapping of the joystick connected to the current port. 212 * 213 * @return The Twist value of the joystick. 214 */ 215 public double getTwist() { 216 return getRawAxis(m_axes[AxisType.kTwist.value]); 217 } 218 219 /** 220 * Get the throttle value of the current joystick. 221 * This depends on the mapping of the joystick connected to the current port. 222 * 223 * @return The Throttle value of the joystick. 224 */ 225 public double getThrottle() { 226 return getRawAxis(m_axes[AxisType.kThrottle.value]); 227 } 228 229 /** 230 * Get the value of the axis. 231 * 232 * @param axis The axis to read, starting at 0. 233 * @return The value of the axis. 234 */ 235 public double getRawAxis(final int axis) { 236 return m_ds.getStickAxis(m_port, axis); 237 } 238 239 /** 240 * For the current joystick, return the axis determined by the argument. 241 * 242 * This is for cases where the joystick axis is returned programatically, otherwise one of the 243 * previous functions would be preferable (for example getX()). 244 * 245 * @param axis The axis to read. 246 * @return The value of the axis. 247 */ 248 public double getAxis(final AxisType axis) { 249 switch (axis.value) { 250 case AxisType.kX_val: 251 return getX(); 252 case AxisType.kY_val: 253 return getY(); 254 case AxisType.kZ_val: 255 return getZ(); 256 case AxisType.kTwist_val: 257 return getTwist(); 258 case AxisType.kThrottle_val: 259 return getThrottle(); 260 default: 261 return 0.0; 262 } 263 } 264 265 /** 266 * For the current joystick, return the number of axis 267 */ 268 public int getAxisCount(){ 269 return m_ds.getStickAxisCount(m_port); 270 } 271 272 /** 273 * Read the state of the trigger on the joystick. 274 * 275 * Look up which button has been assigned to the trigger and read its state. 276 * 277 * @param hand This parameter is ignored for the Joystick class and is only here to complete the GenericHID interface. 278 * @return The state of the trigger. 279 */ 280 public boolean getTrigger(Hand hand) { 281 return getRawButton(m_buttons[ButtonType.kTrigger.value]); 282 } 283 284 /** 285 * Read the state of the top button on the joystick. 286 * 287 * Look up which button has been assigned to the top and read its state. 288 * 289 * @param hand This parameter is ignored for the Joystick class and is only here to complete the GenericHID interface. 290 * @return The state of the top button. 291 */ 292 public boolean getTop(Hand hand) { 293 return getRawButton(m_buttons[ButtonType.kTop.value]); 294 } 295 296 /** 297 * This is not supported for the Joystick. 298 * This method is only here to complete the GenericHID interface. 299 * 300 * @param hand This parameter is ignored for the Joystick class and is only here to complete the GenericHID interface. 301 * @return The state of the bumper (always false) 302 */ 303 public boolean getBumper(Hand hand) { 304 return false; 305 } 306 307 /** 308 * Get the button value (starting at button 1) 309 * 310 * The appropriate button is returned as a boolean value. 311 * 312 * @param button The button number to be read (starting at 1). 313 * @return The state of the button. 314 */ 315 public boolean getRawButton(final int button) { 316 return m_ds.getStickButton(m_port, (byte)button); 317 } 318 319 /** 320 * For the current joystick, return the number of buttons 321 */ 322 public int getButtonCount(){ 323 return m_ds.getStickButtonCount(m_port); 324 } 325 326 /** 327 * Get the state of a POV on the joystick. 328 * 329 * @param pov The index of the POV to read (starting at 0) 330 * @return the angle of the POV in degrees, or -1 if the POV is not pressed. 331 */ 332 public int getPOV(int pov) { 333 return m_ds.getStickPOV(m_port, pov); 334 } 335 336 /** 337 * For the current joystick, return the number of POVs 338 */ 339 public int getPOVCount(){ 340 return m_ds.getStickPOVCount(m_port); 341 } 342 343 /** 344 * Get buttons based on an enumerated type. 345 * 346 * The button type will be looked up in the list of buttons and then read. 347 * 348 * @param button The type of button to read. 349 * @return The state of the button. 350 */ 351 public boolean getButton(ButtonType button) { 352 switch (button.value) { 353 case ButtonType.kTrigger_val: 354 return getTrigger(); 355 case ButtonType.kTop_val: 356 return getTop(); 357 default: 358 return false; 359 } 360 } 361 362 /** 363 * Get the magnitude of the direction vector formed by the joystick's 364 * current position relative to its origin 365 * 366 * @return The magnitude of the direction vector 367 */ 368 public double getMagnitude() { 369 return Math.sqrt(Math.pow(getX(), 2) + Math.pow(getY(), 2)); 370 } 371 372 /** 373 * Get the direction of the vector formed by the joystick and its origin 374 * in radians 375 * 376 * @return The direction of the vector in radians 377 */ 378 public double getDirectionRadians() { 379 return Math.atan2(getX(), -getY()); 380 } 381 382 /** 383 * Get the direction of the vector formed by the joystick and its origin 384 * in degrees 385 * 386 * uses acos(-1) to represent Pi due to absence of readily accessable Pi 387 * constant in C++ 388 * 389 * @return The direction of the vector in degrees 390 */ 391 public double getDirectionDegrees() { 392 return Math.toDegrees(getDirectionRadians()); 393 } 394 395 /** 396 * Get the channel currently associated with the specified axis. 397 * 398 * @param axis The axis to look up the channel for. 399 * @return The channel fr the axis. 400 */ 401 public int getAxisChannel(AxisType axis) { 402 return m_axes[axis.value]; 403 } 404 405 /** 406 * Set the channel associated with a specified axis. 407 * 408 * @param axis The axis to set the channel for. 409 * @param channel The channel to set the axis to. 410 */ 411 public void setAxisChannel(AxisType axis, int channel) { 412 m_axes[axis.value] = (byte) channel; 413 } 414 415 /** 416 * Set the rumble output for the joystick. The DS currently supports 2 rumble values, 417 * left rumble and right rumble 418 * @param type Which rumble value to set 419 * @param value The normalized value (0 to 1) to set the rumble to 420 */ 421 public void setRumble(RumbleType type, float value) { 422 if (value < 0) 423 value = 0; 424 else if (value > 1) 425 value = 1; 426 if (type.value == RumbleType.kLeftRumble_val) 427 m_leftRumble = (short)(value*65535); 428 else 429 m_rightRumble = (short)(value*65535); 430 FRCNetworkCommunicationsLibrary.HALSetJoystickOutputs((byte)m_port, m_outputs, m_leftRumble, m_rightRumble); 431 } 432 433 /** 434 * Set a single HID output value for the joystick. 435 * @param outputNumber The index of the output to set (1-32) 436 * @param value The value to set the output to 437 */ 438 439 public void setOutput(int outputNumber, boolean value) { 440 m_outputs = (m_outputs & ~(1 << (outputNumber-1))) | ((value?1:0) << (outputNumber-1)); 441 FRCNetworkCommunicationsLibrary.HALSetJoystickOutputs((byte)m_port, m_outputs, m_leftRumble, m_rightRumble); 442 } 443 444 /** 445 * Set all HID output values for the joystick. 446 * @param value The 32 bit output value (1 bit for each output) 447 */ 448 public void setOutputs(int value) { 449 m_outputs = value; 450 FRCNetworkCommunicationsLibrary.HALSetJoystickOutputs((byte)m_port, m_outputs, m_leftRumble, m_rightRumble); 451 } 452}