Nathan Leong | dd72800 | 2024-02-03 15:26:53 -0800 | [diff] [blame] | 1 | #include "frc971/control_loops/catapult/catapult_controller.h" |
| 2 | |
| 3 | namespace frc971::control_loops::catapult { |
| 4 | |
| 5 | CatapultController::CatapultController(StateFeedbackPlant<2, 1, 1> plant, |
| 6 | size_t horizon) |
| 7 | : generator_(std::move(plant), horizon) { |
| 8 | problems_.reserve(generator_.horizon()); |
| 9 | for (size_t i = generator_.horizon(); i > 0; --i) { |
| 10 | problems_.emplace_back(generator_.MakeProblem(i)); |
| 11 | } |
| 12 | |
| 13 | Reset(); |
| 14 | } |
| 15 | |
| 16 | void CatapultController::Reset() { |
| 17 | current_controller_ = 0; |
| 18 | solve_time_ = 0.0; |
| 19 | } |
| 20 | |
| 21 | void CatapultController::SetState(Eigen::Matrix<double, 2, 1> X_initial, |
| 22 | Eigen::Matrix<double, 2, 1> X_final) { |
| 23 | if (current_controller_ >= problems_.size()) { |
| 24 | return; |
| 25 | } |
| 26 | problems_[current_controller_]->SetState(X_initial, X_final); |
| 27 | } |
| 28 | |
| 29 | bool CatapultController::Solve() { |
| 30 | if (current_controller_ >= problems_.size()) { |
| 31 | return true; |
| 32 | } |
| 33 | const bool result = problems_[current_controller_]->Solve(); |
| 34 | solve_time_ = problems_[current_controller_]->solve_time(); |
| 35 | return result; |
| 36 | } |
| 37 | |
| 38 | std::optional<double> CatapultController::Next() { |
| 39 | if (current_controller_ >= problems_.size()) { |
| 40 | return std::nullopt; |
| 41 | } |
| 42 | |
| 43 | double u; |
| 44 | size_t solution_number = 0; |
| 45 | if (current_controller_ == 0u) { |
| 46 | while (solution_number < problems_[current_controller_]->horizon() && |
| 47 | problems_[current_controller_]->U(solution_number) < 0.01) { |
| 48 | u = problems_[current_controller_]->U(solution_number); |
| 49 | ++solution_number; |
| 50 | } |
| 51 | } |
| 52 | u = problems_[current_controller_]->U(solution_number); |
| 53 | |
| 54 | if (current_controller_ + 1u + solution_number < problems_.size()) { |
| 55 | problems_[current_controller_ + solution_number + 1]->WarmStart( |
| 56 | *problems_[current_controller_]); |
| 57 | } |
| 58 | current_controller_ += 1u + solution_number; |
| 59 | return u; |
| 60 | } |
| 61 | |
| 62 | } // namespace frc971::control_loops::catapult |