blob: da650a5c3061cfc08a3f4e7024c677415272014c [file] [log] [blame]
Sabina Davisadc58542019-02-01 22:23:00 -08001#ifndef FRC971_WPILIB_SENSOR_READER_H_
2#define FRC971_WPILIB_SENSOR_READER_H_
3
4#include <atomic>
5#include <chrono>
6
Alex Perrycb7da4b2019-08-28 19:35:56 -07007#include "aos/events/event_loop.h"
Austin Schuh217a9782019-12-21 23:02:50 -08008#include "aos/events/shm_event_loop.h"
Sabina Davisadc58542019-02-01 22:23:00 -08009#include "aos/stl_mutex/stl_mutex.h"
10#include "aos/time/time.h"
Maxwell Hendersoncb78f352024-01-15 00:27:16 -080011#include "frc971/control_loops/control_loops_static.h"
Maxwell Hendersonf382b4b2024-01-14 12:31:41 -080012#include "frc971/control_loops/drivetrain/drivetrain_position_static.h"
James Kuszmaul7077d342021-06-09 20:23:58 -070013#include "frc971/input/robot_state_generated.h"
Sabina Davisadc58542019-02-01 22:23:00 -080014#include "frc971/wpilib/ahal/DigitalGlitchFilter.h"
15#include "frc971/wpilib/ahal/DigitalInput.h"
Austin Schuh3b010bc2019-02-24 17:25:37 -080016#include "frc971/wpilib/ahal/DriverStation.h"
Sabina Davis1ffa4172019-02-01 22:38:33 -080017#include "frc971/wpilib/dma.h"
18#include "frc971/wpilib/dma_edge_counting.h"
Austin Schuh54667ac2019-02-02 16:44:49 -080019#include "frc971/wpilib/encoder_and_potentiometer.h"
Sabina Davisadc58542019-02-01 22:23:00 -080020
21using ::aos::monotonic_clock;
22namespace chrono = ::std::chrono;
23
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -080024namespace frc971::wpilib {
Sabina Davisadc58542019-02-01 22:23:00 -080025
26class SensorReader {
27 public:
Austin Schuh217a9782019-12-21 23:02:50 -080028 SensorReader(::aos::ShmEventLoop *event_loop);
Austin Schuh2c2cc2e2019-02-02 20:19:45 -080029 virtual ~SensorReader() {}
Sabina Davisadc58542019-02-01 22:23:00 -080030
Austin Schuh45a549f2019-02-02 15:43:56 -080031 // Updates the fast and medium encoder filter frequencies.
32 void UpdateFastEncoderFilterHz(int hz);
33 void UpdateMediumEncoderFilterHz(int hz);
34
Sabina Davisb6317b72019-02-01 22:53:23 -080035 // Sets the left drivetrain encoder.
36 void set_drivetrain_left_encoder(::std::unique_ptr<frc::Encoder> encoder);
37
38 // Sets the right drivetrain encoder.
39 void set_drivetrain_right_encoder(::std::unique_ptr<frc::Encoder> encoder);
40
Sabina Davis6292bec2019-02-06 22:53:14 -080041 // Adds a sensor to DMA.
Austin Schuh2c2cc2e2019-02-02 20:19:45 -080042 void AddToDMA(DMASampleHandlerInterface *handler) {
Sabina Davis6292bec2019-02-06 22:53:14 -080043 if (!dma_synchronizer_) {
44 dma_synchronizer_.reset(
45 new ::frc971::wpilib::DMASynchronizer(std::make_unique<DMA>()));
46 }
Austin Schuh2c2cc2e2019-02-02 20:19:45 -080047 dma_synchronizer_->Add(handler);
48 }
49
Austin Schuh3b010bc2019-02-24 17:25:37 -080050 // Sets PWM trigger mode. If true, synchronize the control loops with the PWM
51 // pulses. The sensors are sampled 50 uS after the falling edge of the PWM
52 // pulse.
53 void set_pwm_trigger(bool trigger) { pwm_trigger_ = trigger; }
Sabina Davisadc58542019-02-01 22:23:00 -080054
Sabina Davisa42cc352019-02-01 22:55:50 -080055 // Stops the pwm trigger on the next iteration.
56 void Quit() { run_ = false; }
57
Sabina Davis399dbd82019-02-01 23:06:08 -080058 virtual void RunIteration() = 0;
Sabina Davis6292bec2019-02-06 22:53:14 -080059 // Runs the DMA iteration after the synchronizer. This only gets run if a
60 // sensor has been added to DMA.
Austin Schuh2c2cc2e2019-02-02 20:19:45 -080061 virtual void RunDmaIteration() {}
Sabina Davis399dbd82019-02-01 23:06:08 -080062
Sabina Davisadc58542019-02-01 22:23:00 -080063 protected:
Austin Schuh54667ac2019-02-02 16:44:49 -080064 // Copies a DMAEncoder to a IndexPosition with the correct unit and direction
65 // changes.
66 void CopyPosition(const ::frc971::wpilib::DMAEncoder &encoder,
Maxwell Hendersoncb78f352024-01-15 00:27:16 -080067 ::frc971::IndexPositionStatic *position,
Austin Schuh54667ac2019-02-02 16:44:49 -080068 double encoder_counts_per_revolution, double encoder_ratio,
69 bool reverse) {
70 const double multiplier = reverse ? -1.0 : 1.0;
Maxwell Hendersoncb78f352024-01-15 00:27:16 -080071 position->set_encoder(multiplier *
72 encoder_translate(encoder.polled_encoder_value(),
73 encoder_counts_per_revolution,
74 encoder_ratio));
75 position->set_latched_encoder(
Austin Schuh54667ac2019-02-02 16:44:49 -080076 multiplier * encoder_translate(encoder.last_encoder_value(),
77 encoder_counts_per_revolution,
Maxwell Hendersoncb78f352024-01-15 00:27:16 -080078 encoder_ratio));
79 position->set_index_pulses(encoder.index_posedge_count());
Austin Schuh54667ac2019-02-02 16:44:49 -080080 }
81
82 // Copies a AbsoluteEncoderAndPotentiometer to a PotAndAbsolutePosition with
83 // the correct unit and direction changes.
84 void CopyPosition(
85 const ::frc971::wpilib::AbsoluteEncoderAndPotentiometer &encoder,
Maxwell Hendersoncb78f352024-01-15 00:27:16 -080086 ::frc971::PotAndAbsolutePositionStatic *position,
Austin Schuh54667ac2019-02-02 16:44:49 -080087 double encoder_counts_per_revolution, double encoder_ratio,
88 ::std::function<double(double)> potentiometer_translate, bool reverse,
89 double pot_offset) {
90 const double multiplier = reverse ? -1.0 : 1.0;
Maxwell Hendersoncb78f352024-01-15 00:27:16 -080091 position->set_pot(multiplier * potentiometer_translate(
92 encoder.ReadPotentiometerVoltage()) +
93 pot_offset);
94 position->set_encoder(multiplier *
95 encoder_translate(encoder.ReadRelativeEncoder(),
96 encoder_counts_per_revolution,
97 encoder_ratio));
Austin Schuh54667ac2019-02-02 16:44:49 -080098
Maxwell Hendersoncb78f352024-01-15 00:27:16 -080099 position->set_absolute_encoder((reverse
100 ? (1.0 - encoder.ReadAbsoluteEncoder())
101 : encoder.ReadAbsoluteEncoder()) *
102 encoder_ratio * (2.0 * M_PI));
Austin Schuh54667ac2019-02-02 16:44:49 -0800103 }
104
Maxwell Henderson5e7b6e32024-02-20 15:30:33 -0800105 void CopyPosition(
106 const ::frc971::wpilib::DMAAbsoluteEncoderAndPotentiometer &encoder,
107 ::frc971::PotAndAbsolutePositionStatic *position,
108 double encoder_counts_per_revolution, double encoder_ratio,
109 ::std::function<double(double)> potentiometer_translate, bool reverse,
110 double pot_offset) {
111 const double multiplier = reverse ? -1.0 : 1.0;
112 position->set_pot(multiplier * potentiometer_translate(
113 encoder.ReadPotentiometerVoltage()) +
114 pot_offset);
115 position->set_encoder(multiplier *
116 encoder_translate(encoder.ReadRelativeEncoder(),
117 encoder_counts_per_revolution,
118 encoder_ratio));
119
120 position->set_absolute_encoder((reverse
121 ? (1.0 - encoder.ReadAbsoluteEncoder())
122 : encoder.ReadAbsoluteEncoder()) *
123 encoder_ratio * (2.0 * M_PI));
124 }
125
Ravago Jones937587c2020-12-26 17:21:09 -0800126 // Copies an AbsoluteEncoderAndPotentiometer to an AbsoluteAndAbsolutePosition
127 // with the correct unit and direction changes.
128 void CopyPosition(const ::frc971::wpilib::AbsoluteAndAbsoluteEncoder &encoder,
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800129 ::frc971::AbsoluteAndAbsolutePositionStatic *position,
Ravago Jones937587c2020-12-26 17:21:09 -0800130 double encoder_counts_per_revolution, double encoder_ratio,
131 double single_turn_encoder_ratio, bool reverse) {
132 const double multiplier = reverse ? -1.0 : 1.0;
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800133 position->set_encoder(multiplier *
134 encoder_translate(encoder.ReadRelativeEncoder(),
135 encoder_counts_per_revolution,
136 encoder_ratio));
Ravago Jones937587c2020-12-26 17:21:09 -0800137
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800138 position->set_absolute_encoder((reverse
139 ? (1.0 - encoder.ReadAbsoluteEncoder())
140 : encoder.ReadAbsoluteEncoder()) *
141 encoder_ratio * (2.0 * M_PI));
Ravago Jones937587c2020-12-26 17:21:09 -0800142
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800143 position->set_single_turn_absolute_encoder(
Ravago Jones937587c2020-12-26 17:21:09 -0800144 (reverse ? (1.0 - encoder.ReadSingleTurnAbsoluteEncoder())
145 : encoder.ReadSingleTurnAbsoluteEncoder()) *
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800146 single_turn_encoder_ratio * (2.0 * M_PI));
Ravago Jones937587c2020-12-26 17:21:09 -0800147 }
148
Austin Schuh54667ac2019-02-02 16:44:49 -0800149 // Copies a DMAEdgeCounter to a HallEffectAndPosition with the correct unit
150 // and direction changes.
151 void CopyPosition(const ::frc971::wpilib::DMAEdgeCounter &counter,
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800152 ::frc971::HallEffectAndPositionStatic *position,
Austin Schuh54667ac2019-02-02 16:44:49 -0800153 double encoder_counts_per_revolution, double encoder_ratio,
154 bool reverse) {
155 const double multiplier = reverse ? -1.0 : 1.0;
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800156 position->set_encoder(multiplier *
157 encoder_translate(counter.polled_encoder(),
158 encoder_counts_per_revolution,
159 encoder_ratio));
160 position->set_current(!counter.polled_value());
161 position->set_posedge_count(counter.negative_count());
162 position->set_negedge_count(counter.positive_count());
163 position->set_posedge_value(
Austin Schuh54667ac2019-02-02 16:44:49 -0800164 multiplier * encoder_translate(counter.last_negative_encoder_value(),
165 encoder_counts_per_revolution,
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800166 encoder_ratio));
167 position->set_negedge_value(
Austin Schuh54667ac2019-02-02 16:44:49 -0800168 multiplier * encoder_translate(counter.last_positive_encoder_value(),
169 encoder_counts_per_revolution,
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800170 encoder_ratio));
Austin Schuh54667ac2019-02-02 16:44:49 -0800171 }
172
Sabina Davis8d8ac0a2019-02-06 23:51:07 -0800173 // Copies a Absolute Encoder with the correct unit
174 // and direction changes.
Ravago Jones937587c2020-12-26 17:21:09 -0800175 void CopyPosition(const ::frc971::wpilib::AbsoluteEncoder &encoder,
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800176 ::frc971::AbsolutePositionStatic *position,
Ravago Jones937587c2020-12-26 17:21:09 -0800177 double encoder_counts_per_revolution, double encoder_ratio,
178 bool reverse) {
Sabina Davis8d8ac0a2019-02-06 23:51:07 -0800179 const double multiplier = reverse ? -1.0 : 1.0;
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800180 position->set_encoder(multiplier *
181 encoder_translate(encoder.ReadRelativeEncoder(),
182 encoder_counts_per_revolution,
183 encoder_ratio));
Sabina Davis8d8ac0a2019-02-06 23:51:07 -0800184
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800185 position->set_absolute_encoder((reverse
186 ? (1.0 - encoder.ReadAbsoluteEncoder())
187 : encoder.ReadAbsoluteEncoder()) *
188 encoder_ratio * (2.0 * M_PI));
Sabina Davis8d8ac0a2019-02-06 23:51:07 -0800189 }
190
Ravago Jones937587c2020-12-26 17:21:09 -0800191 void CopyPosition(const ::frc971::wpilib::DMAEncoderAndPotentiometer &encoder,
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800192 ::frc971::PotAndIndexPositionStatic *position,
Ravago Jones937587c2020-12-26 17:21:09 -0800193 ::std::function<double(int32_t)> encoder_translate,
194 ::std::function<double(double)> potentiometer_translate,
195 bool reverse, double pot_offset) {
Sabina Davis2243cab2019-02-05 21:45:08 -0800196 const double multiplier = reverse ? -1.0 : 1.0;
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800197 position->set_encoder(multiplier *
198 encoder_translate(encoder.polled_encoder_value()));
199 position->set_pot(multiplier * potentiometer_translate(
200 encoder.polled_potentiometer_voltage()) +
201 pot_offset);
202 position->set_latched_encoder(
203 multiplier * encoder_translate(encoder.last_encoder_value()));
204 position->set_latched_pot(
Sabina Davis2243cab2019-02-05 21:45:08 -0800205 multiplier *
206 potentiometer_translate(encoder.last_potentiometer_voltage()) +
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800207 pot_offset);
208 position->set_index_pulses(encoder.index_posedge_count());
Sabina Davis2243cab2019-02-05 21:45:08 -0800209 }
210
Siddhant Kanwar0e37f592022-02-21 19:26:50 -0800211 // Copies a relative digital encoder.
Alex Perry2712c102020-02-17 19:17:11 -0800212 void CopyPosition(const ::frc::Encoder &encoder,
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800213 ::frc971::RelativePositionStatic *position,
Alex Perry2712c102020-02-17 19:17:11 -0800214 double encoder_counts_per_revolution, double encoder_ratio,
215 bool reverse) {
216 const double multiplier = reverse ? -1.0 : 1.0;
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800217 position->set_encoder(multiplier *
218 encoder_translate(encoder.GetRaw(),
219 encoder_counts_per_revolution,
220 encoder_ratio));
Alex Perry2712c102020-02-17 19:17:11 -0800221 }
222
Siddhant Kanwar0e37f592022-02-21 19:26:50 -0800223 // Copies a potentiometer
224 void CopyPosition(const ::frc::AnalogInput &input,
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800225 ::frc971::RelativePositionStatic *position,
Siddhant Kanwar0e37f592022-02-21 19:26:50 -0800226 ::std::function<double(double)> potentiometer_translate,
227 bool reverse, double pot_offset) {
228 const double multiplier = reverse ? -1.0 : 1.0;
Maxwell Hendersoncb78f352024-01-15 00:27:16 -0800229 position->set_encoder(
230 multiplier * potentiometer_translate(input.GetVoltage()) + pot_offset);
Siddhant Kanwar0e37f592022-02-21 19:26:50 -0800231 }
232
Austin Schuh54667ac2019-02-02 16:44:49 -0800233 double encoder_translate(int32_t value, double counts_per_revolution,
234 double ratio) {
235 return static_cast<double>(value) / counts_per_revolution * ratio *
236 (2.0 * M_PI);
237 }
238
Maxwell Hendersond5ae85b2024-01-08 16:14:28 -0800239 void SendDrivetrainPosition(
Maxwell Hendersonf382b4b2024-01-14 12:31:41 -0800240 aos::Sender<control_loops::drivetrain::PositionStatic>::StaticBuilder
241 builder,
Maxwell Hendersond5ae85b2024-01-08 16:14:28 -0800242 std::function<double(double input)> velocity_translate,
243 std::function<double(double input)> encoder_to_meters, bool left_inverted,
244 bool right_inverted);
245
Austin Schuhdf6cbb12019-02-02 13:46:52 -0800246 ::aos::EventLoop *event_loop_;
247 ::aos::Sender<::aos::RobotState> robot_state_sender_;
248
Austin Schuh45a549f2019-02-02 15:43:56 -0800249 frc::DigitalGlitchFilter fast_encoder_filter_, medium_encoder_filter_;
250
251 ::std::unique_ptr<frc::Encoder> drivetrain_left_encoder_,
252 drivetrain_right_encoder_;
253
254 private:
Austin Schuh2c2cc2e2019-02-02 20:19:45 -0800255 // Gets called right before the DMA synchronizer is up and running.
256 virtual void Start() {}
257
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700258 // Sets up everything during startup.
259 void DoStart();
260
261 // Runs a single iteration.
milind-u61227f22021-08-29 15:58:33 -0700262 void Loop();
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700263
Austin Schuh3b010bc2019-02-24 17:25:37 -0800264 // Returns the monotonic time of the start of the first PWM cycle.
265 // Returns min_time if no start time could be calculated.
266 monotonic_clock::time_point GetPWMStartTime();
Sabina Davisadc58542019-02-01 22:23:00 -0800267
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700268 bool pwm_trigger_ = false;
Sabina Davisadc58542019-02-01 22:23:00 -0800269
Sabina Davis1ffa4172019-02-01 22:38:33 -0800270 ::std::unique_ptr<::frc971::wpilib::DMASynchronizer> dma_synchronizer_;
271
Sabina Davisadc58542019-02-01 22:23:00 -0800272 ::std::atomic<bool> run_{true};
Austin Schuh3b010bc2019-02-24 17:25:37 -0800273 ::frc::DriverStation *ds_;
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700274
275 const int32_t my_pid_;
276
milind-u61227f22021-08-29 15:58:33 -0700277 // Pointer to the timer handler used to modify the wakeup.
278 ::aos::TimerHandler *timer_handler_;
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700279
280 // Last time we got called.
281 ::aos::monotonic_clock::time_point last_monotonic_now_ =
282 ::aos::monotonic_clock::min_time;
283 // The current period.
284 chrono::microseconds period_ = chrono::microseconds(5000);
Sabina Davisadc58542019-02-01 22:23:00 -0800285};
286
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -0800287} // namespace frc971::wpilib
Sabina Davisadc58542019-02-01 22:23:00 -0800288
289#endif // FRC971_WPILIB_SENSOR_READER_H_