blob: c2150d5a33d644dc827a20e36cc8f3415ff99784 [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;
13
14 start_pos_samples_.reserve(max_sample_count_);
15
16 Reset();
Austin Schuh703b8d42015-02-01 14:56:34 -080017}
18
Adam Snaiderb4119252015-02-15 01:30:57 +000019void ZeroingEstimator::Reset() {
Adam Snaiderc4b3c192015-02-01 01:30:39 +000020 samples_idx_ = 0;
Adam Snaiderb4119252015-02-15 01:30:57 +000021 start_pos_ = 0;
22 start_pos_samples_.clear();
23 zeroed_ = false;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000024}
25
Austin Schuh703b8d42015-02-01 14:56:34 -080026void ZeroingEstimator::UpdateEstimate(const PotAndIndexPosition& info) {
Adam Snaiderc4b3c192015-02-01 01:30:39 +000027 if (start_pos_samples_.size() < max_sample_count_) {
28 start_pos_samples_.push_back(info.pot - info.encoder);
29 } else {
30 start_pos_samples_[samples_idx_] = info.pot - info.encoder;
31 }
Adam Snaiderb4119252015-02-15 01:30:57 +000032
33 // Drop the oldest sample when we run this function the next time around.
Adam Snaiderc4b3c192015-02-01 01:30:39 +000034 samples_idx_ = (samples_idx_ + 1) % max_sample_count_;
35
Adam Snaiderb4119252015-02-15 01:30:57 +000036 double sample_sum = 0.0;
37
Adam Snaiderc4b3c192015-02-01 01:30:39 +000038 for (size_t i = 0; i < start_pos_samples_.size(); ++i) {
Adam Snaiderb4119252015-02-15 01:30:57 +000039 sample_sum += start_pos_samples_[i];
Adam Snaiderc4b3c192015-02-01 01:30:39 +000040 }
41
42 // Calculates the average of the starting position.
Adam Snaiderb4119252015-02-15 01:30:57 +000043 double start_average = sample_sum / start_pos_samples_.size();
44
45 // If there are no index pulses to use or we don't have enough samples yet to
46 // have a well-filtered starting position then we use the filtered value as
47 // our best guess.
48 if (info.index_pulses == 0 || offset_ratio_ready() < 1.0) {
49 start_pos_ = start_average;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000050 } else {
Austin Schuh703b8d42015-02-01 14:56:34 -080051 // We calculate an aproximation of the value of the last index position.
Adam Snaiderb4119252015-02-15 01:30:57 +000052 double index_pos = start_average + info.latched_encoder;
Austin Schuh703b8d42015-02-01 14:56:34 -080053 // We round index_pos to the closest valid value of the index.
Adam Snaiderc4b3c192015-02-01 01:30:39 +000054 double accurate_index_pos = (round(index_pos / index_diff_)) * index_diff_;
Adam Snaiderb4119252015-02-15 01:30:57 +000055 // Now we reverse the first calculation to the accurate start position.
56 start_pos_ = accurate_index_pos - info.latched_encoder;
57
58 // Now that we have an accurate starting position we can consider ourselves
59 // zeroed.
Austin Schuh703b8d42015-02-01 14:56:34 -080060 zeroed_ = true;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000061 }
Adam Snaiderb4119252015-02-15 01:30:57 +000062
63 pos_ = start_pos_ + info.encoder;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000064}
65
Adam Snaiderc4b3c192015-02-01 01:30:39 +000066} // namespace zeroing
67} // namespace frc971