blob: 4eba44802a10e234f2d3a09c1024ed89d89a69fe [file] [log] [blame]
#include "frc971/shooter_interpolation/interpolation.h"
#include <algorithm>
#include <utility>
#include <vector>
namespace frc971 {
namespace shooter_interpolation {
namespace {
double Blend(double coefficient, double a1, double a2) {
return (1 - coefficient) * a1 + coefficient * a2;
}
ShotParams Blend(double coefficient, ShotParams a1, ShotParams a2) {
return ShotParams{Blend(coefficient, a1.angle, a2.angle),
Blend(coefficient, a1.power, a2.power)};
}
} // namespace
InterpolationTable::InterpolationTable(
const ::std::vector<::std::pair<double, ShotParams>> &table)
: table_(table) {
::std::sort(table_.begin(), table_.end(),
[](const ::std::pair<double, ShotParams> &a,
const ::std::pair<double, ShotParams> &b) {
return a.first < b.first;
});
}
ShotParams InterpolationTable::GetShooterData(double distance) const {
// Points to to the smallest item such that it->first >= dist, or end() if no
// such item exists.
auto it = ::std::lower_bound(table_.begin(), table_.end(), distance,
[](const ::std::pair<double, ShotParams> &a,
double dist) { return a.first < dist; });
if (it == table_.begin()) {
return it->second;
} else if (it == table_.end()) {
return table_.back().second;
} else {
auto x_a2 = it;
auto x_a1 = it - 1;
double x1 = x_a1->first;
double x2 = x_a2->first;
double coefficient = (distance - x1) / (x2 - x1);
return Blend(coefficient, x_a1->second, x_a2->second);
}
}
} // namespace shooter_interpolation
} // namespace frc971