summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Palecki <[email protected]>2021-04-07 23:13:01 -0700
committerJacob Palecki <[email protected]>2021-04-07 23:13:01 -0700
commit8b3409bdd892481b459a1afbfa6fddea9b7bb448 (patch)
tree7f9d5df9083feca782a95e2cf08d6dde27d37095
parentAdd active value labels for gain switch (diff)
downloadrawaccel-8b3409bdd892481b459a1afbfa6fddea9b7bb448.tar.xz
rawaccel-8b3409bdd892481b459a1afbfa6fddea9b7bb448.zip
Add arbitrary lut struct
-rw-r--r--common/accel-lookup.hpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 18c9ea5..6c73605 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -149,4 +149,107 @@ namespace rawaccel {
binlog_lut(args.lut_args) {}
};
+ struct si_pair {
+ double slope = 0;
+ double intercept = 0;
+ };
+
+ struct arbitrary_lut_point {
+ double applicable_speed = 0;
+ si_pair slope_intercept = {};
+ };
+
+ struct arbitrary_lut {
+ fp_rep_range range;
+ arbitrary_lut_point data[LUT_CAPACITY] = {};
+ int log_lookup[LUT_CAPACITY] = {};
+ double first_point_speed;
+ double last_point_speed;
+ int last_index;
+
+ double operator()(double speed) const
+ {
+ int index = 0;
+
+ if (speed < first_point_speed)
+ {
+ // Apply from 0 index
+ }
+ else if (speed > last_point_speed)
+ {
+ index = last_index;
+ }
+ else if (speed > range.stop)
+ {
+ index = search_from(log_lookup[LUT_CAPACITY - 1], speed);
+ }
+ else if (speed < range.start)
+ {
+ index = search_from(0, speed);
+ }
+ else
+ {
+ int log_lookup = get_log_index(speed);
+ index = search_from(log_lookup, speed);
+ }
+
+ return apply(index, speed);
+ }
+
+ int inline get_log_index(double speed) const
+ {
+ double speed_log = log(speed) - range.start;
+ int index = (int)floor(speed_log * range.num);
+ return index;
+ }
+
+ int inline search_from(int index, double speed) const
+ {
+ int prev_index;
+
+ do
+ {
+ prev_index = index;
+ index++;
+ }
+ while (index <= last_index && data[index].applicable_speed < speed);
+
+ index--;
+ }
+
+ double inline apply(int index, double speed) const
+ {
+ si_pair pair = data[index].slope_intercept;
+ return pair.slope + pair.intercept / speed;
+ }
+
+ void fill(vec2d* points, int length) const
+ {
+ vec2d current = {0, 0};
+ vec2d next;
+ int log_index = 0;
+ double log_inner_iterator = range.start;
+ double log_inner_slice = 1 / range.num;
+ double log_value = pow(2, log_inner_iterator);
+
+ for (int i = 0; i < length; i++)
+ {
+ next = points[i];
+ double slope = (next.y - current.y) / (next.x - current.x);
+ double intercept = next.y - slope * next.x;
+ si_pair current_si = { slope, intercept };
+ arbitrary_lut_point current_lut_point = { next.x, current_si };
+
+ this->data[i] = current_lut_point;
+
+ while (log_value < next.x)
+ {
+ this->log_lookup[log_index] = log_value;
+ log_index++;
+ log_inner_iterator += log_inner_slice;
+ log_value = pow(2, log_inner_iterator);
+ }
+ }
+ }
+ };
}