blob: 388832c96c19b6ca3ff12641c99702da657ee997 [file] [log] [blame]
Brian Silverman26e4e522015-12-17 01:56:40 -05001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2008. All Rights Reserved.
3 */
4/* Open Source Software - may be modified and shared by FRC teams. The code */
5/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
6/*----------------------------------------------------------------------------*/
7
8#include "Joystick.h"
9#include "DriverStation.h"
10#include "WPIErrors.h"
11#include <math.h>
12#include <string.h>
13
14const uint32_t Joystick::kDefaultXAxis;
15const uint32_t Joystick::kDefaultYAxis;
16const uint32_t Joystick::kDefaultZAxis;
17const uint32_t Joystick::kDefaultTwistAxis;
18const uint32_t Joystick::kDefaultThrottleAxis;
19const uint32_t Joystick::kDefaultTriggerButton;
20const uint32_t Joystick::kDefaultTopButton;
21static Joystick *joysticks[DriverStation::kJoystickPorts];
22static 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 *
28 * @param port The port on the driver station that the joystick is plugged into
29 * (0-5).
30 */
31Joystick::Joystick(uint32_t port)
32 : Joystick(port, kNumAxisTypes, kNumButtonTypes) {
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;
38
39 m_buttons[kTriggerButton] = kDefaultTriggerButton;
40 m_buttons[kTopButton] = kDefaultTopButton;
41
42 HALReport(HALUsageReporting::kResourceType_Joystick, port);
43}
44
45/**
46 * Version of the constructor to be called by sub-classes.
47 *
48 * This constructor allows the subclass to configure the number of constants
49 * for axes and buttons.
50 *
51 * @param port The port on the driver station that the joystick is plugged into.
52 * @param numAxisTypes The number of axis types in the enum.
53 * @param numButtonTypes The number of button types in the enum.
54 */
55Joystick::Joystick(uint32_t port, uint32_t numAxisTypes,
56 uint32_t numButtonTypes)
57 : m_ds(DriverStation::GetInstance()),
58 m_port(port),
59 m_axes(numAxisTypes),
60 m_buttons(numButtonTypes) {
61 if (!joySticksInitialized) {
62 for (auto& joystick : joysticks) joystick = nullptr;
63 joySticksInitialized = true;
64 }
65 if (m_port >= DriverStation::kJoystickPorts) {
66 wpi_setWPIError(BadJoystickIndex);
67 } else {
68 joysticks[m_port] = this;
69 }
70}
71
72Joystick *Joystick::GetStickForPort(uint32_t port) {
73 Joystick *stick = joysticks[port];
74 if (stick == nullptr) {
75 stick = new Joystick(port);
76 joysticks[port] = stick;
77 }
78 return stick;
79}
80
81/**
82 * Get the X value of the joystick.
83 * This depends on the mapping of the joystick connected to the current port.
84 * @param hand This parameter is ignored for the Joystick class and is only here
85 * to complete the GenericHID interface.
86 */
87float Joystick::GetX(JoystickHand hand) const {
88 return GetRawAxis(m_axes[kXAxis]);
89}
90
91/**
92 * Get the Y value of the joystick.
93 * This depends on the mapping of the joystick connected to the current port.
94 * @param hand This parameter is ignored for the Joystick class and is only here
95 * to complete the GenericHID interface.
96 */
97float Joystick::GetY(JoystickHand hand) const {
98 return GetRawAxis(m_axes[kYAxis]);
99}
100
101/**
102 * Get the Z value of the current joystick.
103 * This depends on the mapping of the joystick connected to the current port.
104 */
105float Joystick::GetZ() const { return GetRawAxis(m_axes[kZAxis]); }
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 */
111float Joystick::GetTwist() const { return GetRawAxis(m_axes[kTwistAxis]); }
112
113/**
114 * Get the throttle value of the current joystick.
115 * This depends on the mapping of the joystick connected to the current port.
116 */
117float Joystick::GetThrottle() const {
118 return GetRawAxis(m_axes[kThrottleAxis]);
119}
120
121/**
122 * Get the value of the axis.
123 *
124 * @param axis The axis to read, starting at 0.
125 * @return The value of the axis.
126 */
127float Joystick::GetRawAxis(uint32_t axis) const {
128 return m_ds.GetStickAxis(m_port, axis);
129}
130
131/**
132 * For the current joystick, return the axis determined by the argument.
133 *
134 * This is for cases where the joystick axis is returned programatically,
135 * otherwise one of the
136 * previous functions would be preferable (for example GetX()).
137 *
138 * @param axis The axis to read.
139 * @return The value of the axis.
140 */
141float Joystick::GetAxis(AxisType axis) const {
142 switch (axis) {
143 case kXAxis:
144 return this->GetX();
145 case kYAxis:
146 return this->GetY();
147 case kZAxis:
148 return this->GetZ();
149 case kTwistAxis:
150 return this->GetTwist();
151 case kThrottleAxis:
152 return this->GetThrottle();
153 default:
154 wpi_setWPIError(BadJoystickAxis);
155 return 0.0;
156 }
157}
158
159/**
160 * Read the state of the trigger on the joystick.
161 *
162 * Look up which button has been assigned to the trigger and read its state.
163 *
164 * @param hand This parameter is ignored for the Joystick class and is only here
165 * to complete the GenericHID interface.
166 * @return The state of the trigger.
167 */
168bool Joystick::GetTrigger(JoystickHand hand) const {
169 return GetRawButton(m_buttons[kTriggerButton]);
170}
171
172/**
173 * Read the state of the top button on the joystick.
174 *
175 * Look up which button has been assigned to the top and read its state.
176 *
177 * @param hand This parameter is ignored for the Joystick class and is only here
178 * to complete the GenericHID interface.
179 * @return The state of the top button.
180 */
181bool Joystick::GetTop(JoystickHand hand) const {
182 return GetRawButton(m_buttons[kTopButton]);
183}
184
185/**
186 * This is not supported for the Joystick.
187 * This method is only here to complete the GenericHID interface.
188 */
189bool Joystick::GetBumper(JoystickHand hand) const {
190 // Joysticks don't have bumpers.
191 return false;
192}
193
194/**
195 * Get the button value (starting at button 1)
196 *
197 * The buttons are returned in a single 16 bit value with one bit representing
198 * the state
199 * of each button. The appropriate button is returned as a boolean value.
200 *
201 * @param button The button number to be read (starting at 1)
202 * @return The state of the button.
203 **/
204bool Joystick::GetRawButton(uint32_t button) const {
205 return m_ds.GetStickButton(m_port, button);
206}
207
208/**
209 * Get the state of a POV on the joystick.
210 *
211 * @param pov The index of the POV to read (starting at 0)
212 * @return the angle of the POV in degrees, or -1 if the POV is not pressed.
213 */
214int Joystick::GetPOV(uint32_t pov) const {
215 return m_ds.GetStickPOV(m_port, pov);
216}
217
218/**
219 * Get buttons based on an enumerated type.
220 *
221 * The button type will be looked up in the list of buttons and then read.
222 *
223 * @param button The type of button to read.
224 * @return The state of the button.
225 */
226bool Joystick::GetButton(ButtonType button) const {
227 switch (button) {
228 case kTriggerButton:
229 return GetTrigger();
230 case kTopButton:
231 return GetTop();
232 default:
233 return false;
234 }
235}
236
237/**
238 * Get the number of axis for a joystick
239 *
240 * @return the number of axis for the current joystick
241 */
242int Joystick::GetAxisCount() const { return m_ds.GetStickAxisCount(m_port); }
243
244/**
245 * Get the value of isXbox for the joystick.
246 *
247 * @return A boolean that is true if the joystick is an xbox controller.
248 */
249bool Joystick::GetIsXbox() const { return m_ds.GetJoystickIsXbox(m_port); }
250
251/**
252 * Get the HID type of the controller.
253 *
254 * @return the HID type of the controller.
255 */
256Joystick::HIDType Joystick::GetType() const {
257 return static_cast<HIDType>(m_ds.GetJoystickType(m_port));
258}
259
260/**
261 * Get the name of the joystick.
262 *
263 * @return the name of the controller.
264 */
265std::string Joystick::GetName() const { return m_ds.GetJoystickName(m_port); }
266
267// int Joystick::GetAxisType(uint8_t axis) const
268//{
269// return m_ds.GetJoystickAxisType(m_port, axis);
270//}
271
272/**
273 * Get the number of axis for a joystick
274 *
275* @return the number of buttons on the current joystick
276 */
277int Joystick::GetButtonCount() const {
278 return m_ds.GetStickButtonCount(m_port);
279}
280
281/**
282 * Get the number of axis for a joystick
283 *
284 * @return then umber of POVs for the current joystick
285 */
286int Joystick::GetPOVCount() const { return m_ds.GetStickPOVCount(m_port); }
287
288/**
289 * Get the channel currently associated with the specified axis.
290 *
291 * @param axis The axis to look up the channel for.
292 * @return The channel fr the axis.
293 */
294uint32_t Joystick::GetAxisChannel(AxisType axis) const { return m_axes[axis]; }
295
296/**
297 * Set the channel associated with a specified axis.
298 *
299 * @param axis The axis to set the channel for.
300 * @param channel The channel to set the axis to.
301 */
302void Joystick::SetAxisChannel(AxisType axis, uint32_t channel) {
303 m_axes[axis] = channel;
304}
305
306/**
307 * Get the magnitude of the direction vector formed by the joystick's
308 * current position relative to its origin
309 *
310 * @return The magnitude of the direction vector
311 */
312float Joystick::GetMagnitude() const {
313 return sqrt(pow(GetX(), 2) + pow(GetY(), 2));
314}
315
316/**
317 * Get the direction of the vector formed by the joystick and its origin
318 * in radians
319 *
320 * @return The direction of the vector in radians
321 */
322float Joystick::GetDirectionRadians() const { return atan2(GetX(), -GetY()); }
323
324/**
325 * Get the direction of the vector formed by the joystick and its origin
326 * in degrees
327 *
328 * uses acos(-1) to represent Pi due to absence of readily accessible Pi
329 * constant in C++
330 *
331 * @return The direction of the vector in degrees
332 */
333float Joystick::GetDirectionDegrees() const {
334 return (180 / acos(-1)) * GetDirectionRadians();
335}
336
337/**
338 * Set the rumble output for the joystick. The DS currently supports 2 rumble
339 * values,
340 * left rumble and right rumble
341 * @param type Which rumble value to set
342 * @param value The normalized value (0 to 1) to set the rumble to
343 */
344void Joystick::SetRumble(RumbleType type, float value) {
345 if (value < 0)
346 value = 0;
347 else if (value > 1)
348 value = 1;
349 if (type == kLeftRumble)
350 m_leftRumble = value * 65535;
351 else
352 m_rightRumble = value * 65535;
353 HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
354}
355
356/**
357 * Set a single HID output value for the joystick.
358 * @param outputNumber The index of the output to set (1-32)
359 * @param value The value to set the output to
360 */
361
362void Joystick::SetOutput(uint8_t outputNumber, bool value) {
363 m_outputs =
364 (m_outputs & ~(1 << (outputNumber - 1))) | (value << (outputNumber - 1));
365
366 HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
367}
368
369/**
370 * Set all HID output values for the joystick.
371 * @param value The 32 bit output value (1 bit for each output)
372 */
373void Joystick::SetOutputs(uint32_t value) {
374 m_outputs = value;
375 HALSetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
376}