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 }