Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 1 | /*----------------------------------------------------------------------------*/ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 2 | /* Copyright (c) FIRST 2008-2016. All Rights Reserved. */ |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 3 | /* Open Source Software - may be modified and shared by FRC teams. The code */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 4 | /* must be accompanied by the FIRST BSD license file in the root directory of */ |
| 5 | /* the project. */ |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 6 | /*----------------------------------------------------------------------------*/ |
| 7 | |
| 8 | #include "Joystick.h" |
| 9 | #include "DriverStation.h" |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 10 | #include "WPIErrors.h" |
| 11 | #include <math.h> |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 12 | #include <memory> |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 13 | |
| 14 | const uint32_t Joystick::kDefaultXAxis; |
| 15 | const uint32_t Joystick::kDefaultYAxis; |
| 16 | const uint32_t Joystick::kDefaultZAxis; |
| 17 | const uint32_t Joystick::kDefaultTwistAxis; |
| 18 | const uint32_t Joystick::kDefaultThrottleAxis; |
| 19 | const uint32_t Joystick::kDefaultTriggerButton; |
| 20 | const uint32_t Joystick::kDefaultTopButton; |
| 21 | static Joystick *joysticks[DriverStation::kJoystickPorts]; |
| 22 | static bool joySticksInitialized = false; |
| 23 | |
| 24 | /** |
| 25 | * Construct an instance of a joystick. |
| 26 | * The joystick index is the usb port on the drivers station. |
| 27 | * |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 28 | * @param port The port on the driver station that the joystick is plugged into. |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 29 | */ |
| 30 | Joystick::Joystick(uint32_t port) |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 31 | : Joystick(port, kNumAxisTypes, kNumButtonTypes) |
| 32 | { |
| 33 | m_axes[kXAxis] = kDefaultXAxis; |
| 34 | m_axes[kYAxis] = kDefaultYAxis; |
| 35 | m_axes[kZAxis] = kDefaultZAxis; |
| 36 | m_axes[kTwistAxis] = kDefaultTwistAxis; |
| 37 | m_axes[kThrottleAxis] = kDefaultThrottleAxis; |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 38 | |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 39 | m_buttons[kTriggerButton] = kDefaultTriggerButton; |
| 40 | m_buttons[kTopButton] = kDefaultTopButton; |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 41 | } |
| 42 | |
| 43 | /** |
| 44 | * Version of the constructor to be called by sub-classes. |
| 45 | * |
| 46 | * This constructor allows the subclass to configure the number of constants |
| 47 | * for axes and buttons. |
| 48 | * |
| 49 | * @param port The port on the driver station that the joystick is plugged into. |
| 50 | * @param numAxisTypes The number of axis types in the enum. |
| 51 | * @param numButtonTypes The number of button types in the enum. |
| 52 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 53 | Joystick::Joystick(uint32_t port, uint32_t numAxisTypes, uint32_t numButtonTypes) |
| 54 | : m_port (port), |
| 55 | m_ds(DriverStation::GetInstance()) |
| 56 | { |
| 57 | if ( !joySticksInitialized ) |
| 58 | { |
| 59 | for (unsigned i = 0; i < DriverStation::kJoystickPorts; i++) |
| 60 | joysticks[i] = nullptr; |
| 61 | joySticksInitialized = true; |
| 62 | } |
| 63 | joysticks[m_port] = this; |
| 64 | |
| 65 | m_axes = std::make_unique<uint32_t[]>(numAxisTypes); |
| 66 | m_buttons = std::make_unique<uint32_t[]>(numButtonTypes); |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 67 | } |
| 68 | |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 69 | Joystick * Joystick::GetStickForPort(uint32_t port) |
| 70 | { |
| 71 | Joystick *stick = joysticks[port]; |
| 72 | if (stick == nullptr) |
| 73 | { |
| 74 | stick = new Joystick(port); |
| 75 | joysticks[port] = stick; |
| 76 | } |
| 77 | return stick; |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 78 | } |
| 79 | |
| 80 | /** |
| 81 | * Get the X value of the joystick. |
| 82 | * This depends on the mapping of the joystick connected to the current port. |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 83 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 84 | float Joystick::GetX(JoystickHand hand) const |
| 85 | { |
| 86 | return GetRawAxis(m_axes[kXAxis]); |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 87 | } |
| 88 | |
| 89 | /** |
| 90 | * Get the Y value of the joystick. |
| 91 | * This depends on the mapping of the joystick connected to the current port. |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 92 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 93 | float Joystick::GetY(JoystickHand hand) const |
| 94 | { |
| 95 | return GetRawAxis(m_axes[kYAxis]); |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 96 | } |
| 97 | |
| 98 | /** |
| 99 | * Get the Z value of the current joystick. |
| 100 | * This depends on the mapping of the joystick connected to the current port. |
| 101 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 102 | float Joystick::GetZ() const |
| 103 | { |
| 104 | return GetRawAxis(m_axes[kZAxis]); |
| 105 | } |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 106 | |
| 107 | /** |
| 108 | * Get the twist value of the current joystick. |
| 109 | * This depends on the mapping of the joystick connected to the current port. |
| 110 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 111 | float Joystick::GetTwist() const |
| 112 | { |
| 113 | return GetRawAxis(m_axes[kTwistAxis]); |
| 114 | } |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 115 | |
| 116 | /** |
| 117 | * Get the throttle value of the current joystick. |
| 118 | * This depends on the mapping of the joystick connected to the current port. |
| 119 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 120 | float Joystick::GetThrottle() const |
| 121 | { |
| 122 | return GetRawAxis(m_axes[kThrottleAxis]); |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | /** |
| 126 | * Get the value of the axis. |
| 127 | * |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 128 | * @param axis The axis to read [1-6]. |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 129 | * @return The value of the axis. |
| 130 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 131 | float Joystick::GetRawAxis(uint32_t axis) const |
| 132 | { |
| 133 | return m_ds.GetStickAxis(m_port, axis); |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 134 | } |
| 135 | |
| 136 | /** |
| 137 | * For the current joystick, return the axis determined by the argument. |
| 138 | * |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 139 | * This is for cases where the joystick axis is returned programatically, otherwise one of the |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 140 | * previous functions would be preferable (for example GetX()). |
| 141 | * |
| 142 | * @param axis The axis to read. |
| 143 | * @return The value of the axis. |
| 144 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 145 | float Joystick::GetAxis(AxisType axis) const |
| 146 | { |
| 147 | switch(axis) |
| 148 | { |
| 149 | case kXAxis: return this->GetX(); |
| 150 | case kYAxis: return this->GetY(); |
| 151 | case kZAxis: return this->GetZ(); |
| 152 | case kTwistAxis: return this->GetTwist(); |
| 153 | case kThrottleAxis: return this->GetThrottle(); |
| 154 | default: |
| 155 | wpi_setWPIError(BadJoystickAxis); |
| 156 | return 0.0; |
| 157 | } |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 158 | } |
| 159 | |
| 160 | /** |
| 161 | * Read the state of the trigger on the joystick. |
| 162 | * |
| 163 | * Look up which button has been assigned to the trigger and read its state. |
| 164 | * |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 165 | * @param hand This parameter is ignored for the Joystick class and is only here to complete the GenericHID interface. |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 166 | * @return The state of the trigger. |
| 167 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 168 | bool Joystick::GetTrigger(JoystickHand hand) const |
| 169 | { |
| 170 | return GetRawButton(m_buttons[kTriggerButton]); |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 171 | } |
| 172 | |
| 173 | /** |
| 174 | * Read the state of the top button on the joystick. |
| 175 | * |
| 176 | * Look up which button has been assigned to the top and read its state. |
| 177 | * |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 178 | * @param hand This parameter is ignored for the Joystick class and is only here to complete the GenericHID interface. |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 179 | * @return The state of the top button. |
| 180 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 181 | bool Joystick::GetTop(JoystickHand hand) const |
| 182 | { |
| 183 | return GetRawButton(m_buttons[kTopButton]); |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | /** |
| 187 | * This is not supported for the Joystick. |
| 188 | * This method is only here to complete the GenericHID interface. |
| 189 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 190 | bool Joystick::GetBumper(JoystickHand hand) const |
| 191 | { |
| 192 | // Joysticks don't have bumpers. |
| 193 | return false; |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 194 | } |
| 195 | |
| 196 | /** |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 197 | * Get the button value for buttons 1 through 12. |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 198 | * |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 199 | * The buttons are returned in a single 16 bit value with one bit representing the state |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 200 | * of each button. The appropriate button is returned as a boolean value. |
| 201 | * |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 202 | * @param button The button number to be read. |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 203 | * @return The state of the button. |
| 204 | **/ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 205 | bool Joystick::GetRawButton(uint32_t button) const |
| 206 | { |
| 207 | return m_ds.GetStickButton(m_port, button); |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 208 | } |
| 209 | |
| 210 | /** |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 211 | * Get the state of a POV on the joystick. |
| 212 | * |
| 213 | * @return the angle of the POV in degrees, or -1 if the POV is not pressed. |
| 214 | */ |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 215 | int Joystick::GetPOV(uint32_t pov) const { |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 216 | return 0; // TODO |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 217 | } |
| 218 | |
| 219 | /** |
| 220 | * Get buttons based on an enumerated type. |
| 221 | * |
| 222 | * The button type will be looked up in the list of buttons and then read. |
| 223 | * |
| 224 | * @param button The type of button to read. |
| 225 | * @return The state of the button. |
| 226 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 227 | bool Joystick::GetButton(ButtonType button) const |
| 228 | { |
| 229 | switch (button) |
| 230 | { |
| 231 | case kTriggerButton: return GetTrigger(); |
| 232 | case kTopButton: return GetTop(); |
| 233 | default: |
| 234 | return false; |
| 235 | } |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 236 | } |
| 237 | |
| 238 | /** |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 239 | * Get the channel currently associated with the specified axis. |
| 240 | * |
| 241 | * @param axis The axis to look up the channel for. |
| 242 | * @return The channel fr the axis. |
| 243 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 244 | uint32_t Joystick::GetAxisChannel(AxisType axis) |
| 245 | { |
| 246 | return m_axes[axis]; |
| 247 | } |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 248 | |
| 249 | /** |
| 250 | * Set the channel associated with a specified axis. |
| 251 | * |
| 252 | * @param axis The axis to set the channel for. |
| 253 | * @param channel The channel to set the axis to. |
| 254 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 255 | void Joystick::SetAxisChannel(AxisType axis, uint32_t channel) |
| 256 | { |
| 257 | m_axes[axis] = channel; |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 258 | } |
| 259 | |
| 260 | /** |
| 261 | * Get the magnitude of the direction vector formed by the joystick's |
| 262 | * current position relative to its origin |
| 263 | * |
| 264 | * @return The magnitude of the direction vector |
| 265 | */ |
| 266 | float Joystick::GetMagnitude() const { |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 267 | return sqrt(pow(GetX(),2) + pow(GetY(),2) ); |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 268 | } |
| 269 | |
| 270 | /** |
| 271 | * Get the direction of the vector formed by the joystick and its origin |
| 272 | * in radians |
| 273 | * |
| 274 | * @return The direction of the vector in radians |
| 275 | */ |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 276 | float Joystick::GetDirectionRadians() const { |
| 277 | return atan2(GetX(), -GetY()); |
| 278 | } |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 279 | |
| 280 | /** |
| 281 | * Get the direction of the vector formed by the joystick and its origin |
| 282 | * in degrees |
| 283 | * |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 284 | * uses acos(-1) to represent Pi due to absence of readily accessable Pi |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 285 | * constant in C++ |
| 286 | * |
| 287 | * @return The direction of the vector in degrees |
| 288 | */ |
| 289 | float Joystick::GetDirectionDegrees() const { |
Brian Silverman | 1a67511 | 2016-02-20 20:42:49 -0500 | [diff] [blame^] | 290 | return (180/acos(-1))*GetDirectionRadians(); |
Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame] | 291 | } |