blob: 3c32e864947c8d558ece5486f148f97e0508688d [file] [log] [blame]
Brian Silverman26e4e522015-12-17 01:56:40 -05001/*----------------------------------------------------------------------------*/
Brian Silverman1a675112016-02-20 20:42:49 -05002/* Copyright (c) FIRST 2008-2016. All Rights Reserved. */
Brian Silverman26e4e522015-12-17 01:56:40 -05003/* Open Source Software - may be modified and shared by FRC teams. The code */
Brian Silverman1a675112016-02-20 20:42:49 -05004/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
Brian Silverman26e4e522015-12-17 01:56:40 -05006/*----------------------------------------------------------------------------*/
7
8#include "Joystick.h"
9#include "DriverStation.h"
Brian Silverman26e4e522015-12-17 01:56:40 -050010#include "WPIErrors.h"
11#include <math.h>
Brian Silverman1a675112016-02-20 20:42:49 -050012#include <memory>
Brian Silverman26e4e522015-12-17 01:56:40 -050013
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 *
Brian Silverman1a675112016-02-20 20:42:49 -050028 * @param port The port on the driver station that the joystick is plugged into.
Brian Silverman26e4e522015-12-17 01:56:40 -050029 */
30Joystick::Joystick(uint32_t port)
Brian Silverman1a675112016-02-20 20:42:49 -050031 : 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 Silverman26e4e522015-12-17 01:56:40 -050038
Brian Silverman1a675112016-02-20 20:42:49 -050039 m_buttons[kTriggerButton] = kDefaultTriggerButton;
40 m_buttons[kTopButton] = kDefaultTopButton;
Brian Silverman26e4e522015-12-17 01:56:40 -050041}
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 Silverman1a675112016-02-20 20:42:49 -050053Joystick::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 Silverman26e4e522015-12-17 01:56:40 -050067}
68
Brian Silverman1a675112016-02-20 20:42:49 -050069Joystick * 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 Silverman26e4e522015-12-17 01:56:40 -050078}
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 Silverman26e4e522015-12-17 01:56:40 -050083 */
Brian Silverman1a675112016-02-20 20:42:49 -050084float Joystick::GetX(JoystickHand hand) const
85{
86 return GetRawAxis(m_axes[kXAxis]);
Brian Silverman26e4e522015-12-17 01:56:40 -050087}
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 Silverman26e4e522015-12-17 01:56:40 -050092 */
Brian Silverman1a675112016-02-20 20:42:49 -050093float Joystick::GetY(JoystickHand hand) const
94{
95 return GetRawAxis(m_axes[kYAxis]);
Brian Silverman26e4e522015-12-17 01:56:40 -050096}
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 Silverman1a675112016-02-20 20:42:49 -0500102float Joystick::GetZ() const
103{
104 return GetRawAxis(m_axes[kZAxis]);
105}
Brian Silverman26e4e522015-12-17 01:56:40 -0500106
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 Silverman1a675112016-02-20 20:42:49 -0500111float Joystick::GetTwist() const
112{
113 return GetRawAxis(m_axes[kTwistAxis]);
114}
Brian Silverman26e4e522015-12-17 01:56:40 -0500115
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 Silverman1a675112016-02-20 20:42:49 -0500120float Joystick::GetThrottle() const
121{
122 return GetRawAxis(m_axes[kThrottleAxis]);
Brian Silverman26e4e522015-12-17 01:56:40 -0500123}
124
125/**
126 * Get the value of the axis.
127 *
Brian Silverman1a675112016-02-20 20:42:49 -0500128 * @param axis The axis to read [1-6].
Brian Silverman26e4e522015-12-17 01:56:40 -0500129 * @return The value of the axis.
130 */
Brian Silverman1a675112016-02-20 20:42:49 -0500131float Joystick::GetRawAxis(uint32_t axis) const
132{
133 return m_ds.GetStickAxis(m_port, axis);
Brian Silverman26e4e522015-12-17 01:56:40 -0500134}
135
136/**
137 * For the current joystick, return the axis determined by the argument.
138 *
Brian Silverman1a675112016-02-20 20:42:49 -0500139 * This is for cases where the joystick axis is returned programatically, otherwise one of the
Brian Silverman26e4e522015-12-17 01:56:40 -0500140 * 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 Silverman1a675112016-02-20 20:42:49 -0500145float 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 Silverman26e4e522015-12-17 01:56:40 -0500158}
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 Silverman1a675112016-02-20 20:42:49 -0500165 * @param hand This parameter is ignored for the Joystick class and is only here to complete the GenericHID interface.
Brian Silverman26e4e522015-12-17 01:56:40 -0500166 * @return The state of the trigger.
167 */
Brian Silverman1a675112016-02-20 20:42:49 -0500168bool Joystick::GetTrigger(JoystickHand hand) const
169{
170 return GetRawButton(m_buttons[kTriggerButton]);
Brian Silverman26e4e522015-12-17 01:56:40 -0500171}
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 Silverman1a675112016-02-20 20:42:49 -0500178 * @param hand This parameter is ignored for the Joystick class and is only here to complete the GenericHID interface.
Brian Silverman26e4e522015-12-17 01:56:40 -0500179 * @return The state of the top button.
180 */
Brian Silverman1a675112016-02-20 20:42:49 -0500181bool Joystick::GetTop(JoystickHand hand) const
182{
183 return GetRawButton(m_buttons[kTopButton]);
Brian Silverman26e4e522015-12-17 01:56:40 -0500184}
185
186/**
187 * This is not supported for the Joystick.
188 * This method is only here to complete the GenericHID interface.
189 */
Brian Silverman1a675112016-02-20 20:42:49 -0500190bool Joystick::GetBumper(JoystickHand hand) const
191{
192 // Joysticks don't have bumpers.
193 return false;
Brian Silverman26e4e522015-12-17 01:56:40 -0500194}
195
196/**
Brian Silverman1a675112016-02-20 20:42:49 -0500197 * Get the button value for buttons 1 through 12.
Brian Silverman26e4e522015-12-17 01:56:40 -0500198 *
Brian Silverman1a675112016-02-20 20:42:49 -0500199 * The buttons are returned in a single 16 bit value with one bit representing the state
Brian Silverman26e4e522015-12-17 01:56:40 -0500200 * of each button. The appropriate button is returned as a boolean value.
201 *
Brian Silverman1a675112016-02-20 20:42:49 -0500202 * @param button The button number to be read.
Brian Silverman26e4e522015-12-17 01:56:40 -0500203 * @return The state of the button.
204 **/
Brian Silverman1a675112016-02-20 20:42:49 -0500205bool Joystick::GetRawButton(uint32_t button) const
206{
207 return m_ds.GetStickButton(m_port, button);
Brian Silverman26e4e522015-12-17 01:56:40 -0500208}
209
210/**
Brian Silverman1a675112016-02-20 20:42:49 -0500211* 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 Silverman26e4e522015-12-17 01:56:40 -0500215int Joystick::GetPOV(uint32_t pov) const {
Brian Silverman1a675112016-02-20 20:42:49 -0500216 return 0; // TODO
Brian Silverman26e4e522015-12-17 01:56:40 -0500217}
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 Silverman1a675112016-02-20 20:42:49 -0500227bool 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 Silverman26e4e522015-12-17 01:56:40 -0500236}
237
238/**
Brian Silverman26e4e522015-12-17 01:56:40 -0500239 * 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 Silverman1a675112016-02-20 20:42:49 -0500244uint32_t Joystick::GetAxisChannel(AxisType axis)
245{
246 return m_axes[axis];
247}
Brian Silverman26e4e522015-12-17 01:56:40 -0500248
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 Silverman1a675112016-02-20 20:42:49 -0500255void Joystick::SetAxisChannel(AxisType axis, uint32_t channel)
256{
257 m_axes[axis] = channel;
Brian Silverman26e4e522015-12-17 01:56:40 -0500258}
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 */
266float Joystick::GetMagnitude() const {
Brian Silverman1a675112016-02-20 20:42:49 -0500267 return sqrt(pow(GetX(),2) + pow(GetY(),2) );
Brian Silverman26e4e522015-12-17 01:56:40 -0500268}
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 Silverman1a675112016-02-20 20:42:49 -0500276float Joystick::GetDirectionRadians() const {
277 return atan2(GetX(), -GetY());
278}
Brian Silverman26e4e522015-12-17 01:56:40 -0500279
280/**
281 * Get the direction of the vector formed by the joystick and its origin
282 * in degrees
283 *
Brian Silverman1a675112016-02-20 20:42:49 -0500284 * uses acos(-1) to represent Pi due to absence of readily accessable Pi
Brian Silverman26e4e522015-12-17 01:56:40 -0500285 * constant in C++
286 *
287 * @return The direction of the vector in degrees
288 */
289float Joystick::GetDirectionDegrees() const {
Brian Silverman1a675112016-02-20 20:42:49 -0500290 return (180/acos(-1))*GetDirectionRadians();
Brian Silverman26e4e522015-12-17 01:56:40 -0500291}