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