blob: d45c49fa9cc05b46fbcd3cb643d0eecce1a7ae5f [file] [log] [blame]
Adam Snaiderc4b3c192015-02-01 01:30:39 +00001#include "frc971/zeroing/zeroing.h"
Adam Snaiderb4119252015-02-15 01:30:57 +00002
Adam Snaiderc4b3c192015-02-01 01:30:39 +00003#include <math.h>
4#include <vector>
5
6namespace frc971 {
7namespace zeroing {
8
Austin Schuh703b8d42015-02-01 14:56:34 -08009ZeroingEstimator::ZeroingEstimator(
10 const constants::Values::ZeroingConstants& constants) {
Adam Snaiderb4119252015-02-15 01:30:57 +000011 index_diff_ = constants.index_difference;
12 max_sample_count_ = constants.average_filter_size;
Philipp Schrader030ad182015-02-15 05:40:58 +000013 known_index_pos_ = constants.measured_index_position;
Adam Snaiderb4119252015-02-15 01:30:57 +000014
15 start_pos_samples_.reserve(max_sample_count_);
16
17 Reset();
Austin Schuh703b8d42015-02-01 14:56:34 -080018}
19
Adam Snaiderb4119252015-02-15 01:30:57 +000020void ZeroingEstimator::Reset() {
Adam Snaiderc4b3c192015-02-01 01:30:39 +000021 samples_idx_ = 0;
Adam Snaiderb4119252015-02-15 01:30:57 +000022 start_pos_ = 0;
23 start_pos_samples_.clear();
24 zeroed_ = false;
Philipp Schrader41d82912015-02-15 03:44:23 +000025 wait_for_index_pulse_ = true;
Philipp Schradere828be72015-02-15 07:07:37 +000026 last_used_index_pulse_count_ = 0;
Philipp Schrader53f4b6d2015-02-15 22:32:08 +000027 error_ = false;
28}
29
30void ZeroingEstimator::TriggerError() {
31 if (!error_) {
32 LOG(ERROR, "Manually triggered zeroing error.\n");
33 error_ = true;
34 }
Philipp Schradere828be72015-02-15 07:07:37 +000035}
36
37double ZeroingEstimator::CalculateStartPosition(double start_average,
38 double latched_encoder) const {
39 // We calculate an aproximation of the value of the last index position.
40 // Also account for index pulses not lining up with integer multiples of the
41 // index_diff.
42 double index_pos = start_average + latched_encoder - known_index_pos_;
43 // We round index_pos to the closest valid value of the index.
44 double accurate_index_pos = (round(index_pos / index_diff_)) * index_diff_;
45 // Now we reverse the first calculation to get the accurate start position.
46 return accurate_index_pos - latched_encoder + known_index_pos_;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000047}
48
Austin Schuh703b8d42015-02-01 14:56:34 -080049void ZeroingEstimator::UpdateEstimate(const PotAndIndexPosition& info) {
Philipp Schrader41d82912015-02-15 03:44:23 +000050 // We want to make sure that we encounter at least one index pulse while
51 // zeroing. So we take the index pulse count from the first sample after
52 // reset and wait for that count to change before we consider ourselves
53 // zeroed.
54 if (wait_for_index_pulse_) {
Philipp Schradere828be72015-02-15 07:07:37 +000055 last_used_index_pulse_count_ = info.index_pulses;
Philipp Schrader41d82912015-02-15 03:44:23 +000056 wait_for_index_pulse_ = false;
57 }
58
Adam Snaiderc4b3c192015-02-01 01:30:39 +000059 if (start_pos_samples_.size() < max_sample_count_) {
60 start_pos_samples_.push_back(info.pot - info.encoder);
61 } else {
62 start_pos_samples_[samples_idx_] = info.pot - info.encoder;
63 }
Adam Snaiderb4119252015-02-15 01:30:57 +000064
65 // Drop the oldest sample when we run this function the next time around.
Adam Snaiderc4b3c192015-02-01 01:30:39 +000066 samples_idx_ = (samples_idx_ + 1) % max_sample_count_;
67
Adam Snaiderb4119252015-02-15 01:30:57 +000068 double sample_sum = 0.0;
69
Adam Snaiderc4b3c192015-02-01 01:30:39 +000070 for (size_t i = 0; i < start_pos_samples_.size(); ++i) {
Adam Snaiderb4119252015-02-15 01:30:57 +000071 sample_sum += start_pos_samples_[i];
Adam Snaiderc4b3c192015-02-01 01:30:39 +000072 }
73
74 // Calculates the average of the starting position.
Adam Snaiderb4119252015-02-15 01:30:57 +000075 double start_average = sample_sum / start_pos_samples_.size();
76
77 // If there are no index pulses to use or we don't have enough samples yet to
78 // have a well-filtered starting position then we use the filtered value as
79 // our best guess.
Philipp Schradere828be72015-02-15 07:07:37 +000080 if (!zeroed_ && (info.index_pulses == last_used_index_pulse_count_ ||
81 offset_ratio_ready() < 1.0)) {
Adam Snaiderb4119252015-02-15 01:30:57 +000082 start_pos_ = start_average;
Philipp Schradere828be72015-02-15 07:07:37 +000083 } else if (!zeroed_ || last_used_index_pulse_count_ != info.index_pulses) {
84 // Note the accurate start position and the current index pulse count so
85 // that we only run this logic once per index pulse. That should be more
86 // resilient to corrupted intermediate data.
87 start_pos_ = CalculateStartPosition(start_average, info.latched_encoder);
88 last_used_index_pulse_count_ = info.index_pulses;
Adam Snaiderb4119252015-02-15 01:30:57 +000089
90 // Now that we have an accurate starting position we can consider ourselves
91 // zeroed.
Austin Schuh703b8d42015-02-01 14:56:34 -080092 zeroed_ = true;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000093 }
Adam Snaiderb4119252015-02-15 01:30:57 +000094
95 pos_ = start_pos_ + info.encoder;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000096}
97
Adam Snaiderc4b3c192015-02-01 01:30:39 +000098} // namespace zeroing
99} // namespace frc971