blob: bec5ff645dd5e561d4d8ab9b85577cf4024259a9 [file] [log] [blame]
Sabina Davis8d20ca82018-02-19 13:17:45 -08001#ifndef Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_INTAKE_INTAKE_H_
2#define Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_INTAKE_INTAKE_H_
3
Tyler Chatowbf0609c2021-07-31 16:13:27 -07004#include <cmath>
Stephan Massalta769ca22019-01-09 05:29:13 +00005
John Park33858a32018-09-28 23:05:48 -07006#include "aos/commonmath.h"
James Kuszmaul61750662021-06-21 21:32:33 -07007#include "frc971/control_loops/control_loop.h"
James Kuszmaulec635d22023-08-12 18:39:24 -07008#include "frc971/zeroing/pot_and_absolute_encoder.h"
Stephan Massalt4d1e74f2020-01-11 17:50:39 -08009#include "frc971/zeroing/wrap.h"
Sabina Davis8d20ca82018-02-19 13:17:45 -080010#include "frc971/zeroing/zeroing.h"
11#include "y2018/constants.h"
12#include "y2018/control_loops/superstructure/intake/intake_delayed_plant.h"
13#include "y2018/control_loops/superstructure/intake/intake_plant.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070014#include "y2018/control_loops/superstructure/superstructure_output_generated.h"
15#include "y2018/control_loops/superstructure/superstructure_position_generated.h"
16#include "y2018/control_loops/superstructure/superstructure_status_generated.h"
Sabina Davis8d20ca82018-02-19 13:17:45 -080017
18namespace y2018 {
19namespace control_loops {
20namespace superstructure {
21namespace intake {
22
23class IntakeController {
24 public:
25 IntakeController();
26
27 // Sets the current encoder position in radians
28 void set_position(double spring_angle, double output_position);
29
30 // Populates the status structure.
Alex Perrycb7da4b2019-08-28 19:35:56 -070031 void SetStatus(superstructure::IntakeSideStatus::Builder *status,
Sabina Davis8d20ca82018-02-19 13:17:45 -080032 const double *unsafe_goal);
33
34 // Returns the control loop calculated voltage.
35 double voltage() const;
36
Austin Schuh96341532018-03-09 21:17:24 -080037 double output_position() const { return loop_->X_hat(0); }
Alex Perrycb7da4b2019-08-28 19:35:56 -070038 double motor_position() const { return loop_->X_hat(2); }
Austin Schuh96341532018-03-09 21:17:24 -080039
Sabina Davis8d20ca82018-02-19 13:17:45 -080040 // Executes the control loop for a cycle.
41 void Update(bool disabled, const double *unsafe_goal);
42
43 // Resets the kalman filter and any other internal state.
44 void Reset();
45
46 // Sets the goal angle from unsafe_goal.
47 double goal_angle(const double *unsafe_goal);
48
Sabina Davis8d20ca82018-02-19 13:17:45 -080049 constexpr static double kDt =
James Kuszmaul61750662021-06-21 21:32:33 -070050 ::aos::time::DurationInSeconds(::frc971::controls::kLoopFrequency);
Sabina Davis8d20ca82018-02-19 13:17:45 -080051
52 // Sets the offset of the controller to be the zeroing estimator offset when
53 // possible otherwise zero.
54 void UpdateOffset(double offset);
55
Alex Perrycb7da4b2019-08-28 19:35:56 -070056 const ::frc971::constants::Range intake_range() const {
57 return intake_range_;
58 }
59
60 private:
61 // The control loop.
62 ::std::unique_ptr<
63 StateFeedbackLoop<5, 1, 2, double, StateFeedbackPlant<5, 1, 2>,
64 StateFeedbackObserver<5, 1, 2>>>
65 loop_;
66
Sabina Davis8d20ca82018-02-19 13:17:45 -080067 const ::frc971::constants::Range intake_range_;
68
69 // Stores the current zeroing estimator offset.
70 double offset_ = 0.0;
71
Sabina Davis8d20ca82018-02-19 13:17:45 -080072 bool reset_ = true;
73
74 // The current sensor measurement.
75 Eigen::Matrix<double, 2, 1> Y_;
76
77 DISALLOW_COPY_AND_ASSIGN(IntakeController);
78};
79
80class IntakeSide {
81 public:
82 IntakeSide(const ::frc971::constants::PotAndAbsoluteEncoderZeroingConstants
Stephan Massalta769ca22019-01-09 05:29:13 +000083 &zeroing_constants,
84 const double spring_offset);
Sabina Davis8d20ca82018-02-19 13:17:45 -080085
86 // The operating voltage.
87 static constexpr double kOperatingVoltage() { return 12.0; }
88
Alex Perrycb7da4b2019-08-28 19:35:56 -070089 flatbuffers::Offset<superstructure::IntakeSideStatus> Iterate(
90 const double *unsafe_goal,
91 const superstructure::IntakeElasticSensors *position,
92 superstructure::IntakeVoltageT *output,
93 flatbuffers::FlatBufferBuilder *fbb);
Sabina Davis8d20ca82018-02-19 13:17:45 -080094
95 void Reset();
96
97 enum class State : int32_t {
98 UNINITIALIZED,
99 ZEROING,
100 RUNNING,
101 ESTOP,
102 };
103
104 State state() const { return state_; }
105
Alex Perrycb7da4b2019-08-28 19:35:56 -0700106 bool estopped() const { return state_ == State::ESTOP; }
Stephan Massalta769ca22019-01-09 05:29:13 +0000107
Alex Perrycb7da4b2019-08-28 19:35:56 -0700108 bool zeroed() const { return zeroing_estimator_.zeroed(); }
109
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700110 bool clear_of_box() const { return controller_.output_position() < -0.1; }
Austin Schuh96341532018-03-09 21:17:24 -0800111
Neil Balchba9cbba2018-04-06 22:26:38 -0700112 double output_position() const { return controller_.output_position(); }
113
Sabina Davis8d20ca82018-02-19 13:17:45 -0800114 private:
115 IntakeController controller_;
116
Austin Schuh72db9a12019-01-21 18:02:51 -0800117 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator zeroing_estimator_;
Austin Schuh17dd0892018-03-02 20:06:31 -0800118
Stephan Massalta769ca22019-01-09 05:29:13 +0000119 const double spring_offset_;
120
121 double spring_range() const {
122 return ::y2018::constants::Values::kIntakeSpringRatio() * (2 * M_PI);
123 }
124
Stephan Massalt4d1e74f2020-01-11 17:50:39 -0800125 ::frc971::zeroing::UnwrapSensor spring_unwrap_{spring_offset_,
126 spring_range()};
Stephan Massalta769ca22019-01-09 05:29:13 +0000127
128 State state_ = State::UNINITIALIZED;
129
Austin Schuh17dd0892018-03-02 20:06:31 -0800130 double intake_last_position_ = 0.0;
Sabina Davis8d20ca82018-02-19 13:17:45 -0800131};
132
133} // namespace intake
134} // namespace superstructure
135} // namespace control_loops
136} // namespace y2018
137
138#endif // Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_INTAKE_INTAKE_H_