blob: 71989ffa55a9c1b914e368036c5ccd3ced56360c [file] [log] [blame]
Philipp Schradere8ad6382017-04-09 21:51:21 +00001#include "frc971/shooter_interpolation/interpolation.h"
2
3#include <algorithm>
4#include <utility>
5#include <vector>
6
7namespace frc971 {
8namespace shooter_interpolation {
9
10namespace {
11
12double Blend(double coefficient, double a1, double a2) {
13 return (1 - coefficient) * a1 + coefficient * a2;
14}
15
16ShotParams Blend(double coefficient, ShotParams a1, ShotParams a2) {
17 return ShotParams{Blend(coefficient, a1.angle, a2.angle),
18 Blend(coefficient, a1.power, a2.power)};
19}
20
21} // namespace
22
23InterpolationTable::InterpolationTable(
24 ::std::vector<::std::pair<double, ShotParams>> interpolation_table) {
25 interpolation_table_ = ::std::move(interpolation_table);
26 ::std::sort(interpolation_table_.begin(), interpolation_table_.end(),
27 [](const ::std::pair<double, ShotParams> &a,
28 const ::std::pair<double, ShotParams> &b) {
29 return a.first < b.first;
30 });
31}
32
33ShotParams InterpolationTable::GetShooterData(double distance) {
34 // Points to to the smallest item such that it->first >= dist, or end() if no
35 // such item exists.
36 auto it =
37 std::lower_bound(interpolation_table_.begin(), interpolation_table_.end(),
38 distance, [](const ::std::pair<double, ShotParams> &a,
39 double dist) { return a.first < dist; });
40 if (it == interpolation_table_.begin()) {
41 return it->second;
42 } else if (it == interpolation_table_.end()) {
43 return interpolation_table_.back().second;
44 } else {
45 auto x_a2 = it;
46 auto x_a1 = it - 1;
47 double x1 = x_a1->first;
48 double x2 = x_a2->first;
49 double coefficient = (distance - x1) / (x2 - x1);
50 return Blend(coefficient, x_a1->second, x_a2->second);
51 }
52}
53
54} // namespace shooter_interpolation
55} // namespace frc971