blob: a4187f7d9f25c748356771eb2da406e8b619ce2e [file] [log] [blame]
#include "frc971/control_loops/catapult/catapult_controller.h"
namespace frc971::control_loops::catapult {
CatapultController::CatapultController(StateFeedbackPlant<2, 1, 1> plant,
size_t horizon)
: generator_(std::move(plant), horizon) {
problems_.reserve(generator_.horizon());
for (size_t i = generator_.horizon(); i > 0; --i) {
problems_.emplace_back(generator_.MakeProblem(i));
}
Reset();
}
void CatapultController::Reset() {
current_controller_ = 0;
solve_time_ = 0.0;
}
void CatapultController::SetState(Eigen::Matrix<double, 2, 1> X_initial,
Eigen::Matrix<double, 2, 1> X_final) {
if (current_controller_ >= problems_.size()) {
return;
}
problems_[current_controller_]->SetState(X_initial, X_final);
}
bool CatapultController::Solve() {
if (current_controller_ >= problems_.size()) {
return true;
}
const bool result = problems_[current_controller_]->Solve();
solve_time_ = problems_[current_controller_]->solve_time();
return result;
}
std::optional<double> CatapultController::Next() {
if (current_controller_ >= problems_.size()) {
return std::nullopt;
}
double u;
size_t solution_number = 0;
if (current_controller_ == 0u) {
while (solution_number < problems_[current_controller_]->horizon() &&
problems_[current_controller_]->U(solution_number) < 0.01) {
u = problems_[current_controller_]->U(solution_number);
++solution_number;
}
}
u = problems_[current_controller_]->U(solution_number);
if (current_controller_ + 1u + solution_number < problems_.size()) {
problems_[current_controller_ + solution_number + 1]->WarmStart(
*problems_[current_controller_]);
}
current_controller_ += 1u + solution_number;
return u;
}
} // namespace frc971::control_loops::catapult