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