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