diff options
| author | Jacob Palecki <[email protected]> | 2021-04-07 23:13:01 -0700 |
|---|---|---|
| committer | Jacob Palecki <[email protected]> | 2021-04-07 23:13:01 -0700 |
| commit | 8b3409bdd892481b459a1afbfa6fddea9b7bb448 (patch) | |
| tree | 7f9d5df9083feca782a95e2cf08d6dde27d37095 | |
| parent | Add active value labels for gain switch (diff) | |
| download | rawaccel-8b3409bdd892481b459a1afbfa6fddea9b7bb448.tar.xz rawaccel-8b3409bdd892481b459a1afbfa6fddea9b7bb448.zip | |
Add arbitrary lut struct
| -rw-r--r-- | common/accel-lookup.hpp | 103 |
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); + } + } + } + }; } |