blob: fb2536008913df6d10b62abf15acecf20f9fed61 [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
7#include "aos/stl_mutex/stl_mutex.h"
8#include "aos/time/time.h"
Austin Schuh54667ac2019-02-02 16:44:49 -08009#include "frc971/control_loops/control_loops.q.h"
Sabina Davisadc58542019-02-01 22:23:00 -080010#include "frc971/wpilib/ahal/DigitalGlitchFilter.h"
11#include "frc971/wpilib/ahal/DigitalInput.h"
Sabina Davis1ffa4172019-02-01 22:38:33 -080012#include "frc971/wpilib/dma.h"
13#include "frc971/wpilib/dma_edge_counting.h"
Austin Schuh54667ac2019-02-02 16:44:49 -080014#include "frc971/wpilib/encoder_and_potentiometer.h"
Sabina Davisadc58542019-02-01 22:23:00 -080015
16using ::aos::monotonic_clock;
17namespace chrono = ::std::chrono;
18
19namespace frc971 {
20namespace wpilib {
21
22class SensorReader {
23 public:
24 SensorReader();
Austin Schuh2c2cc2e2019-02-02 20:19:45 -080025 virtual ~SensorReader() {}
Sabina Davisadc58542019-02-01 22:23:00 -080026
Austin Schuh45a549f2019-02-02 15:43:56 -080027 // Updates the fast and medium encoder filter frequencies.
28 void UpdateFastEncoderFilterHz(int hz);
29 void UpdateMediumEncoderFilterHz(int hz);
30
Sabina Davisb6317b72019-02-01 22:53:23 -080031 // Sets the left drivetrain encoder.
32 void set_drivetrain_left_encoder(::std::unique_ptr<frc::Encoder> encoder);
33
34 // Sets the right drivetrain encoder.
35 void set_drivetrain_right_encoder(::std::unique_ptr<frc::Encoder> encoder);
36
37 // Sets the dma.
Sabina Davis1ffa4172019-02-01 22:38:33 -080038 void set_dma(::std::unique_ptr<DMA> dma);
39
Austin Schuh2c2cc2e2019-02-02 20:19:45 -080040 void AddToDMA(DMASampleHandlerInterface *handler) {
41 dma_synchronizer_->Add(handler);
42 }
43
Sabina Davisb6317b72019-02-01 22:53:23 -080044 // Sets the pwm trigger.
Sabina Davisadc58542019-02-01 22:23:00 -080045 void set_pwm_trigger(::std::unique_ptr<frc::DigitalInput> pwm_trigger);
46
Sabina Davisa42cc352019-02-01 22:55:50 -080047 // Stops the pwm trigger on the next iteration.
48 void Quit() { run_ = false; }
49
Sabina Davis399dbd82019-02-01 23:06:08 -080050 virtual void RunIteration() = 0;
Austin Schuh2c2cc2e2019-02-02 20:19:45 -080051 virtual void RunDmaIteration() {}
Sabina Davis399dbd82019-02-01 23:06:08 -080052
53 void operator()();
54
Sabina Davisadc58542019-02-01 22:23:00 -080055 protected:
Austin Schuh54667ac2019-02-02 16:44:49 -080056 // Copies a DMAEncoder to a IndexPosition with the correct unit and direction
57 // changes.
58 void CopyPosition(const ::frc971::wpilib::DMAEncoder &encoder,
59 ::frc971::IndexPosition *position,
60 double encoder_counts_per_revolution, double encoder_ratio,
61 bool reverse) {
62 const double multiplier = reverse ? -1.0 : 1.0;
63 position->encoder =
64 multiplier * encoder_translate(encoder.polled_encoder_value(),
65 encoder_counts_per_revolution,
66 encoder_ratio);
67 position->latched_encoder =
68 multiplier * encoder_translate(encoder.last_encoder_value(),
69 encoder_counts_per_revolution,
70 encoder_ratio);
71 position->index_pulses = encoder.index_posedge_count();
72 }
73
74 // Copies a AbsoluteEncoderAndPotentiometer to a PotAndAbsolutePosition with
75 // the correct unit and direction changes.
76 void CopyPosition(
77 const ::frc971::wpilib::AbsoluteEncoderAndPotentiometer &encoder,
78 ::frc971::PotAndAbsolutePosition *position,
79 double encoder_counts_per_revolution, double encoder_ratio,
80 ::std::function<double(double)> potentiometer_translate, bool reverse,
81 double pot_offset) {
82 const double multiplier = reverse ? -1.0 : 1.0;
83 position->pot = multiplier * potentiometer_translate(
84 encoder.ReadPotentiometerVoltage()) +
85 pot_offset;
86 position->encoder =
87 multiplier * encoder_translate(encoder.ReadRelativeEncoder(),
88 encoder_counts_per_revolution,
89 encoder_ratio);
90
91 position->absolute_encoder =
92 (reverse ? (1.0 - encoder.ReadAbsoluteEncoder())
93 : encoder.ReadAbsoluteEncoder()) *
94 encoder_ratio * (2.0 * M_PI);
95 }
96
97 // Copies a DMAEdgeCounter to a HallEffectAndPosition with the correct unit
98 // and direction changes.
99 void CopyPosition(const ::frc971::wpilib::DMAEdgeCounter &counter,
100 ::frc971::HallEffectAndPosition *position,
101 double encoder_counts_per_revolution, double encoder_ratio,
102 bool reverse) {
103 const double multiplier = reverse ? -1.0 : 1.0;
104 position->encoder =
105 multiplier * encoder_translate(counter.polled_encoder(),
106 encoder_counts_per_revolution,
107 encoder_ratio);
108 position->current = !counter.polled_value();
109 position->posedge_count = counter.negative_count();
110 position->negedge_count = counter.positive_count();
111 position->posedge_value =
112 multiplier * encoder_translate(counter.last_negative_encoder_value(),
113 encoder_counts_per_revolution,
114 encoder_ratio);
115 position->negedge_value =
116 multiplier * encoder_translate(counter.last_positive_encoder_value(),
117 encoder_counts_per_revolution,
118 encoder_ratio);
119 }
120
121 double encoder_translate(int32_t value, double counts_per_revolution,
122 double ratio) {
123 return static_cast<double>(value) / counts_per_revolution * ratio *
124 (2.0 * M_PI);
125 }
126
Austin Schuh45a549f2019-02-02 15:43:56 -0800127 frc::DigitalGlitchFilter fast_encoder_filter_, medium_encoder_filter_;
128
129 ::std::unique_ptr<frc::Encoder> drivetrain_left_encoder_,
130 drivetrain_right_encoder_;
131
132 private:
Austin Schuh2c2cc2e2019-02-02 20:19:45 -0800133 // Gets called right before the DMA synchronizer is up and running.
134 virtual void Start() {}
135
Sabina Davisb6317b72019-02-01 22:53:23 -0800136 // Uses the pwm trigger to find the pwm cycle width and offset for that
137 // iteration.
Sabina Davisadc58542019-02-01 22:23:00 -0800138 void RunPWMDetecter();
139
140 ::std::unique_ptr<frc::DigitalInput> pwm_trigger_;
141
Sabina Davisadc58542019-02-01 22:23:00 -0800142 // Mutex to manage access to the period and tick time variables.
143 ::aos::stl_mutex tick_time_mutex_;
144 monotonic_clock::time_point last_tick_time_monotonic_timepoint_ =
145 monotonic_clock::min_time;
Austin Schuh45a549f2019-02-02 15:43:56 -0800146 chrono::nanoseconds last_period_;
Sabina Davisadc58542019-02-01 22:23:00 -0800147
Sabina Davis1ffa4172019-02-01 22:38:33 -0800148 ::std::unique_ptr<::frc971::wpilib::DMASynchronizer> dma_synchronizer_;
149
Sabina Davisadc58542019-02-01 22:23:00 -0800150 ::std::atomic<bool> run_{true};
Sabina Davisadc58542019-02-01 22:23:00 -0800151};
152
153} // namespace wpilib
154} // namespace frc971
155
156#endif // FRC971_WPILIB_SENSOR_READER_H_