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