blob: 1a0504f1aca7d724af6ec06f7895c6229c43f48c [file] [log] [blame]
Austin Schuhc6423e62017-02-11 16:56:30 -08001#include "frc971/zeroing/wrap.h"
2
3#include <cmath>
4
5namespace frc971 {
6namespace zeroing {
7
Stephan Massalt4d1e74f2020-01-11 17:50:39 -08008UnwrapSensor::UnwrapSensor(double sensor_offset, double sensor_range)
9 : sensor_offset_(sensor_offset), sensor_range_(sensor_range) {
10 Reset();
11}
12
13double UnwrapSensor::Unwrap(double current_sensor_value) {
14 // First time the function is called it will use that value to initialize the
15 // wrap calculation. This catches cases where the offset and first value
16 // difference triggers an unwanted wrap at the first calculation.
17 if (uninitialized_ == true) {
18 uninitialized_ = false;
19 } else {
20 // Calculates the lower sensor value and set the max sensor range
21 // If offset is not 0, this will correct the zeroing offset
22 const double sensor_min_value = sensor_offset_;
23 const double sensor_max_value = sensor_range_ + sensor_min_value;
24
25 // Check if provided sensor value is within the range. This to prevent the
26 // function to get out of sync. Will not throw an error, but continue and
27 // return the value + wrapped factor and not process this value.
28 if (current_sensor_value < sensor_min_value ||
29 current_sensor_value > sensor_max_value) {
30 return current_sensor_value + (sensor_range_ * wrap_count_);
31 }
32
33 // Calculate the positive or negative movement
34 const double sensor_move = current_sensor_value - sensor_last_value_;
35
36 // Function assumes that a movement of more then 1/2 of the range
37 // indicates that we wrapped, instead of moved very fast.
38 if (std::abs(sensor_move) > (sensor_range_ / 2)) {
39 if (sensor_move >= 0) {
40 // sensor moved past the sensor_min_value
41 wrap_count_ -= 1;
42 } else {
43 // sensor moved past the sensor_max_value
44 wrap_count_ += 1;
45 }
46 }
47 }
48 sensor_last_value_ = current_sensor_value;
49 // return the unwrapped sensor value
50 return current_sensor_value + (sensor_range_ * wrap_count_);
51}
52
53void UnwrapSensor::Reset() {
54 wrap_count_ = 0;
55 sensor_last_value_ = sensor_offset_;
56 uninitialized_ = true;
57}
58
Austin Schuh4fae0fc2018-03-27 23:51:42 -070059float Wrap(float nearest, float value, float period) {
60 return remainderf(value - nearest, period) + nearest;
61}
62
Austin Schuhc6423e62017-02-11 16:56:30 -080063double Wrap(double nearest, double value, double period) {
Austin Schuh4fae0fc2018-03-27 23:51:42 -070064 return remainder(value - nearest, period) + nearest;
Austin Schuhc6423e62017-02-11 16:56:30 -080065}
66
67} // namespace zeroing
68} // namespace frc971