WPILibC++ 2023.4.3
DutyCycleEncoder.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <memory>
8
9#include <hal/SimDevice.h>
10#include <hal/Types.h>
11#include <units/angle.h>
14
15#include "frc/AnalogTrigger.h"
16#include "frc/Counter.h"
17
18namespace frc {
19class DutyCycle;
20class DigitalSource;
21
22/**
23 * Class for supporting duty cycle/PWM encoders, such as the US Digital MA3 with
24 * PWM Output, the CTRE Mag Encoder, the Rev Hex Encoder, and the AM Mag
25 * Encoder.
26 */
28 public wpi::SendableHelper<DutyCycleEncoder> {
29 public:
30 /**
31 * Construct a new DutyCycleEncoder on a specific channel.
32 *
33 * @param channel the channel to attach to
34 */
35 explicit DutyCycleEncoder(int channel);
36
37 /**
38 * Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
39 *
40 * @param dutyCycle the duty cycle to attach to
41 */
42 explicit DutyCycleEncoder(DutyCycle& dutyCycle);
43
44 /**
45 * Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
46 *
47 * @param dutyCycle the duty cycle to attach to
48 */
49 explicit DutyCycleEncoder(DutyCycle* dutyCycle);
50
51 /**
52 * Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
53 *
54 * @param dutyCycle the duty cycle to attach to
55 */
56 explicit DutyCycleEncoder(std::shared_ptr<DutyCycle> dutyCycle);
57
58 /**
59 * Construct a new DutyCycleEncoder attached to a DigitalSource object.
60 *
61 * @param digitalSource the digital source to attach to
62 */
63 explicit DutyCycleEncoder(DigitalSource& digitalSource);
64
65 /**
66 * Construct a new DutyCycleEncoder attached to a DigitalSource object.
67 *
68 * @param digitalSource the digital source to attach to
69 */
70 explicit DutyCycleEncoder(DigitalSource* digitalSource);
71
72 /**
73 * Construct a new DutyCycleEncoder attached to a DigitalSource object.
74 *
75 * @param digitalSource the digital source to attach to
76 */
77 explicit DutyCycleEncoder(std::shared_ptr<DigitalSource> digitalSource);
78
79 ~DutyCycleEncoder() override = default;
80
83
84 /**
85 * Get the frequency in Hz of the duty cycle signal from the encoder.
86 *
87 * @return duty cycle frequency in Hz
88 */
89 int GetFrequency() const;
90
91 /**
92 * Get if the sensor is connected
93 *
94 * This uses the duty cycle frequency to determine if the sensor is connected.
95 * By default, a value of 100 Hz is used as the threshold, and this value can
96 * be changed with SetConnectedFrequencyThreshold.
97 *
98 * @return true if the sensor is connected
99 */
100 bool IsConnected() const;
101
102 /**
103 * Change the frequency threshold for detecting connection used by
104 * IsConnected.
105 *
106 * @param frequency the minimum frequency in Hz.
107 */
109
110 /**
111 * Reset the Encoder distance to zero.
112 */
113 void Reset();
114
115 /**
116 * Get the encoder value since the last reset.
117 *
118 * This is reported in rotations since the last reset.
119 *
120 * @return the encoder value in rotations
121 */
122 units::turn_t Get() const;
123
124 /**
125 * Get the absolute position of the duty cycle encoder encoder.
126 *
127 * <p>GetAbsolutePosition() - GetPositionOffset() will give an encoder
128 * absolute position relative to the last reset. This could potentially be
129 * negative, which needs to be accounted for.
130 *
131 * <p>This will not account for rollovers, and will always be just the raw
132 * absolute position.
133 *
134 * @return the absolute position
135 */
136 double GetAbsolutePosition() const;
137
138 /**
139 * Get the offset of position relative to the last reset.
140 *
141 * GetAbsolutePosition() - GetPositionOffset() will give an encoder absolute
142 * position relative to the last reset. This could potentially be negative,
143 * which needs to be accounted for.
144 *
145 * @return the position offset
146 */
147 double GetPositionOffset() const;
148
149 /**
150 * Set the position offset.
151 *
152 * <p>This must be in the range of 0-1.
153 *
154 * @param offset the offset
155 */
156 void SetPositionOffset(double offset);
157
158 /**
159 * Set the encoder duty cycle range. As the encoder needs to maintain a duty
160 * cycle, the duty cycle cannot go all the way to 0% or all the way to 100%.
161 * For example, an encoder with a 4096 us period might have a minimum duty
162 * cycle of 1 us / 4096 us and a maximum duty cycle of 4095 / 4096 us. Setting
163 * the range will result in an encoder duty cycle less than or equal to the
164 * minimum being output as 0 rotation, the duty cycle greater than or equal to
165 * the maximum being output as 1 rotation, and values in between linearly
166 * scaled from 0 to 1.
167 *
168 * @param min minimum duty cycle (0-1 range)
169 * @param max maximum duty cycle (0-1 range)
170 */
171 void SetDutyCycleRange(double min, double max);
172
173 /**
174 * Set the distance per rotation of the encoder. This sets the multiplier used
175 * to determine the distance driven based on the rotation value from the
176 * encoder. Set this value based on the how far the mechanism travels in 1
177 * rotation of the encoder, and factor in gearing reductions following the
178 * encoder shaft. This distance can be in any units you like, linear or
179 * angular.
180 *
181 * @param distancePerRotation the distance per rotation of the encoder
182 */
183 void SetDistancePerRotation(double distancePerRotation);
184
185 /**
186 * Get the distance per rotation for this encoder.
187 *
188 * @return The scale factor that will be used to convert rotation to useful
189 * units.
190 */
192
193 /**
194 * Get the distance the sensor has driven since the last reset as scaled by
195 * the value from SetDistancePerRotation.
196 *
197 * @return The distance driven since the last reset
198 */
199 double GetDistance() const;
200
201 /**
202 * Get the FPGA index for the DutyCycleEncoder.
203 *
204 * @return the FPGA index
205 */
206 int GetFPGAIndex() const;
207
208 /**
209 * Get the channel of the source.
210 *
211 * @return the source channel
212 */
213 int GetSourceChannel() const;
214
215 void InitSendable(wpi::SendableBuilder& builder) override;
216
217 private:
218 void Init();
219 double MapSensorRange(double pos) const;
220
221 std::shared_ptr<DutyCycle> m_dutyCycle;
222 std::unique_ptr<AnalogTrigger> m_analogTrigger;
223 std::unique_ptr<Counter> m_counter;
224 int m_frequencyThreshold = 100;
225 double m_positionOffset = 0;
226 double m_distancePerRotation = 1.0;
227 mutable units::turn_t m_lastPosition{0.0};
228 double m_sensorMin = 0;
229 double m_sensorMax = 1;
230
231 hal::SimDevice m_simDevice;
232 hal::SimDouble m_simPosition;
233 hal::SimDouble m_simAbsolutePosition;
234 hal::SimDouble m_simDistancePerRotation;
235 hal::SimBoolean m_simIsConnected;
236};
237} // namespace frc
DigitalSource Interface.
Definition: DigitalSource.h:22
Class for supporting duty cycle/PWM encoders, such as the US Digital MA3 with PWM Output,...
Definition: DutyCycleEncoder.h:28
DutyCycleEncoder(std::shared_ptr< DigitalSource > digitalSource)
Construct a new DutyCycleEncoder attached to a DigitalSource object.
DutyCycleEncoder(DutyCycle &dutyCycle)
Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
double GetAbsolutePosition() const
Get the absolute position of the duty cycle encoder encoder.
DutyCycleEncoder(DutyCycle *dutyCycle)
Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
double GetDistance() const
Get the distance the sensor has driven since the last reset as scaled by the value from SetDistancePe...
bool IsConnected() const
Get if the sensor is connected.
DutyCycleEncoder(DigitalSource &digitalSource)
Construct a new DutyCycleEncoder attached to a DigitalSource object.
void SetPositionOffset(double offset)
Set the position offset.
DutyCycleEncoder(DigitalSource *digitalSource)
Construct a new DutyCycleEncoder attached to a DigitalSource object.
double GetDistancePerRotation() const
Get the distance per rotation for this encoder.
~DutyCycleEncoder() override=default
int GetFrequency() const
Get the frequency in Hz of the duty cycle signal from the encoder.
int GetSourceChannel() const
Get the channel of the source.
void SetDistancePerRotation(double distancePerRotation)
Set the distance per rotation of the encoder.
int GetFPGAIndex() const
Get the FPGA index for the DutyCycleEncoder.
DutyCycleEncoder(std::shared_ptr< DutyCycle > dutyCycle)
Construct a new DutyCycleEncoder attached to an existing DutyCycle object.
void InitSendable(wpi::SendableBuilder &builder) override
Initializes this Sendable object.
units::turn_t Get() const
Get the encoder value since the last reset.
DutyCycleEncoder & operator=(DutyCycleEncoder &&)=default
double GetPositionOffset() const
Get the offset of position relative to the last reset.
void Reset()
Reset the Encoder distance to zero.
void SetDutyCycleRange(double min, double max)
Set the encoder duty cycle range.
void SetConnectedFrequencyThreshold(int frequency)
Change the frequency threshold for detecting connection used by IsConnected.
DutyCycleEncoder(int channel)
Construct a new DutyCycleEncoder on a specific channel.
DutyCycleEncoder(DutyCycleEncoder &&)=default
Class to read a duty cycle PWM input.
Definition: DutyCycle.h:31
Definition: SendableBuilder.h:18
A helper class for use with objects that add themselves to SendableRegistry.
Definition: SendableHelper.h:19
Interface for Sendable objects.
Definition: Sendable.h:16
constexpr common_t< T1, T2 > max(const T1 x, const T2 y) noexcept
Compile-time pairwise maximum function.
Definition: max.hpp:35
constexpr common_t< T1, T2 > min(const T1 x, const T2 y) noexcept
Compile-time pairwise minimum function.
Definition: min.hpp:35
Definition: AprilTagFieldLayout.h:22