blob: 2ec443972c12d257a062c29ab862fab0f21d2a73 [file] [log] [blame]
Brian Silverman8fce7482020-01-05 13:18:21 -08001/*----------------------------------------------------------------------------*/
Austin Schuh1e69f942020-11-14 15:06:14 -08002/* Copyright (c) 2008-2020 FIRST. All Rights Reserved. */
Brian Silverman8fce7482020-01-05 13:18:21 -08003/* 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 "frc/AnalogGyro.h"
9
10#include <climits>
11#include <utility>
12
13#include <hal/AnalogGyro.h>
14#include <hal/Errors.h>
15#include <hal/FRCUsageReporting.h>
16
17#include "frc/AnalogInput.h"
Austin Schuh1e69f942020-11-14 15:06:14 -080018#include "frc/Base.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080019#include "frc/Timer.h"
20#include "frc/WPIErrors.h"
21#include "frc/smartdashboard/SendableRegistry.h"
22
23using namespace frc;
24
25AnalogGyro::AnalogGyro(int channel)
26 : AnalogGyro(std::make_shared<AnalogInput>(channel)) {
27 SendableRegistry::GetInstance().AddChild(this, m_analog.get());
28}
29
30AnalogGyro::AnalogGyro(AnalogInput* channel)
31 : AnalogGyro(
32 std::shared_ptr<AnalogInput>(channel, NullDeleter<AnalogInput>())) {}
33
34AnalogGyro::AnalogGyro(std::shared_ptr<AnalogInput> channel)
35 : m_analog(channel) {
36 if (channel == nullptr) {
37 wpi_setWPIError(NullParameter);
38 } else {
39 InitGyro();
40 Calibrate();
41 }
42}
43
44AnalogGyro::AnalogGyro(int channel, int center, double offset)
45 : AnalogGyro(std::make_shared<AnalogInput>(channel), center, offset) {
46 SendableRegistry::GetInstance().AddChild(this, m_analog.get());
47}
48
49AnalogGyro::AnalogGyro(std::shared_ptr<AnalogInput> channel, int center,
50 double offset)
51 : m_analog(channel) {
52 if (channel == nullptr) {
53 wpi_setWPIError(NullParameter);
54 } else {
55 InitGyro();
56 int32_t status = 0;
57 HAL_SetAnalogGyroParameters(m_gyroHandle, kDefaultVoltsPerDegreePerSecond,
58 offset, center, &status);
59 if (status != 0) {
60 wpi_setHALError(status);
61 m_gyroHandle = HAL_kInvalidHandle;
62 return;
63 }
64 Reset();
65 }
66}
67
68AnalogGyro::~AnalogGyro() { HAL_FreeAnalogGyro(m_gyroHandle); }
69
70double AnalogGyro::GetAngle() const {
71 if (StatusIsFatal()) return 0.0;
72 int32_t status = 0;
73 double value = HAL_GetAnalogGyroAngle(m_gyroHandle, &status);
74 wpi_setHALError(status);
75 return value;
76}
77
78double AnalogGyro::GetRate() const {
79 if (StatusIsFatal()) return 0.0;
80 int32_t status = 0;
81 double value = HAL_GetAnalogGyroRate(m_gyroHandle, &status);
82 wpi_setHALError(status);
83 return value;
84}
85
86int AnalogGyro::GetCenter() const {
87 if (StatusIsFatal()) return 0;
88 int32_t status = 0;
89 int value = HAL_GetAnalogGyroCenter(m_gyroHandle, &status);
90 wpi_setHALError(status);
91 return value;
92}
93
94double AnalogGyro::GetOffset() const {
95 if (StatusIsFatal()) return 0.0;
96 int32_t status = 0;
97 double value = HAL_GetAnalogGyroOffset(m_gyroHandle, &status);
98 wpi_setHALError(status);
99 return value;
100}
101
102void AnalogGyro::SetSensitivity(double voltsPerDegreePerSecond) {
103 int32_t status = 0;
104 HAL_SetAnalogGyroVoltsPerDegreePerSecond(m_gyroHandle,
105 voltsPerDegreePerSecond, &status);
106 wpi_setHALError(status);
107}
108
109void AnalogGyro::SetDeadband(double volts) {
110 if (StatusIsFatal()) return;
111 int32_t status = 0;
112 HAL_SetAnalogGyroDeadband(m_gyroHandle, volts, &status);
113 wpi_setHALError(status);
114}
115
116void AnalogGyro::Reset() {
117 if (StatusIsFatal()) return;
118 int32_t status = 0;
119 HAL_ResetAnalogGyro(m_gyroHandle, &status);
120 wpi_setHALError(status);
121}
122
123void AnalogGyro::InitGyro() {
124 if (StatusIsFatal()) return;
125 if (m_gyroHandle == HAL_kInvalidHandle) {
126 int32_t status = 0;
127 m_gyroHandle = HAL_InitializeAnalogGyro(m_analog->m_port, &status);
128 if (status == PARAMETER_OUT_OF_RANGE) {
129 wpi_setWPIErrorWithContext(ParameterOutOfRange,
130 " channel (must be accumulator channel)");
131 m_analog = nullptr;
132 m_gyroHandle = HAL_kInvalidHandle;
133 return;
134 }
135 if (status != 0) {
136 wpi_setHALError(status);
137 m_analog = nullptr;
138 m_gyroHandle = HAL_kInvalidHandle;
139 return;
140 }
141 }
142
143 int32_t status = 0;
144 HAL_SetupAnalogGyro(m_gyroHandle, &status);
145 if (status != 0) {
146 wpi_setHALError(status);
147 m_analog = nullptr;
148 m_gyroHandle = HAL_kInvalidHandle;
149 return;
150 }
151
152 HAL_Report(HALUsageReporting::kResourceType_Gyro, m_analog->GetChannel() + 1);
153
154 SendableRegistry::GetInstance().AddLW(this, "AnalogGyro",
155 m_analog->GetChannel());
156}
157
158void AnalogGyro::Calibrate() {
159 if (StatusIsFatal()) return;
160 int32_t status = 0;
161 HAL_CalibrateAnalogGyro(m_gyroHandle, &status);
162 wpi_setHALError(status);
163}
Austin Schuh1e69f942020-11-14 15:06:14 -0800164
165std::shared_ptr<AnalogInput> AnalogGyro::GetAnalogInput() const {
166 return m_analog;
167}