blob: 3b5c840a7fd1ddb440af0d929fd45076110ab05c [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
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -080018namespace y2018::control_loops::superstructure::intake {
Sabina Davis8d20ca82018-02-19 13:17:45 -080019
20class IntakeController {
21 public:
22 IntakeController();
23
24 // Sets the current encoder position in radians
25 void set_position(double spring_angle, double output_position);
26
27 // Populates the status structure.
Alex Perrycb7da4b2019-08-28 19:35:56 -070028 void SetStatus(superstructure::IntakeSideStatus::Builder *status,
Sabina Davis8d20ca82018-02-19 13:17:45 -080029 const double *unsafe_goal);
30
31 // Returns the control loop calculated voltage.
32 double voltage() const;
33
Austin Schuh96341532018-03-09 21:17:24 -080034 double output_position() const { return loop_->X_hat(0); }
Alex Perrycb7da4b2019-08-28 19:35:56 -070035 double motor_position() const { return loop_->X_hat(2); }
Austin Schuh96341532018-03-09 21:17:24 -080036
Sabina Davis8d20ca82018-02-19 13:17:45 -080037 // Executes the control loop for a cycle.
38 void Update(bool disabled, const double *unsafe_goal);
39
40 // Resets the kalman filter and any other internal state.
41 void Reset();
42
43 // Sets the goal angle from unsafe_goal.
44 double goal_angle(const double *unsafe_goal);
45
Sabina Davis8d20ca82018-02-19 13:17:45 -080046 constexpr static double kDt =
James Kuszmaul61750662021-06-21 21:32:33 -070047 ::aos::time::DurationInSeconds(::frc971::controls::kLoopFrequency);
Sabina Davis8d20ca82018-02-19 13:17:45 -080048
49 // Sets the offset of the controller to be the zeroing estimator offset when
50 // possible otherwise zero.
51 void UpdateOffset(double offset);
52
Alex Perrycb7da4b2019-08-28 19:35:56 -070053 const ::frc971::constants::Range intake_range() const {
54 return intake_range_;
55 }
56
57 private:
58 // The control loop.
59 ::std::unique_ptr<
60 StateFeedbackLoop<5, 1, 2, double, StateFeedbackPlant<5, 1, 2>,
61 StateFeedbackObserver<5, 1, 2>>>
62 loop_;
63
Sabina Davis8d20ca82018-02-19 13:17:45 -080064 const ::frc971::constants::Range intake_range_;
65
66 // Stores the current zeroing estimator offset.
67 double offset_ = 0.0;
68
Sabina Davis8d20ca82018-02-19 13:17:45 -080069 bool reset_ = true;
70
71 // The current sensor measurement.
72 Eigen::Matrix<double, 2, 1> Y_;
73
74 DISALLOW_COPY_AND_ASSIGN(IntakeController);
75};
76
77class IntakeSide {
78 public:
79 IntakeSide(const ::frc971::constants::PotAndAbsoluteEncoderZeroingConstants
Stephan Massalta769ca22019-01-09 05:29:13 +000080 &zeroing_constants,
81 const double spring_offset);
Sabina Davis8d20ca82018-02-19 13:17:45 -080082
83 // The operating voltage.
84 static constexpr double kOperatingVoltage() { return 12.0; }
85
Alex Perrycb7da4b2019-08-28 19:35:56 -070086 flatbuffers::Offset<superstructure::IntakeSideStatus> Iterate(
87 const double *unsafe_goal,
88 const superstructure::IntakeElasticSensors *position,
89 superstructure::IntakeVoltageT *output,
90 flatbuffers::FlatBufferBuilder *fbb);
Sabina Davis8d20ca82018-02-19 13:17:45 -080091
92 void Reset();
93
94 enum class State : int32_t {
95 UNINITIALIZED,
96 ZEROING,
97 RUNNING,
98 ESTOP,
99 };
100
101 State state() const { return state_; }
102
Alex Perrycb7da4b2019-08-28 19:35:56 -0700103 bool estopped() const { return state_ == State::ESTOP; }
Stephan Massalta769ca22019-01-09 05:29:13 +0000104
Alex Perrycb7da4b2019-08-28 19:35:56 -0700105 bool zeroed() const { return zeroing_estimator_.zeroed(); }
106
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700107 bool clear_of_box() const { return controller_.output_position() < -0.1; }
Austin Schuh96341532018-03-09 21:17:24 -0800108
Neil Balchba9cbba2018-04-06 22:26:38 -0700109 double output_position() const { return controller_.output_position(); }
110
Sabina Davis8d20ca82018-02-19 13:17:45 -0800111 private:
112 IntakeController controller_;
113
Austin Schuh72db9a12019-01-21 18:02:51 -0800114 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator zeroing_estimator_;
Austin Schuh17dd0892018-03-02 20:06:31 -0800115
Stephan Massalta769ca22019-01-09 05:29:13 +0000116 const double spring_offset_;
117
118 double spring_range() const {
119 return ::y2018::constants::Values::kIntakeSpringRatio() * (2 * M_PI);
120 }
121
Stephan Massalt4d1e74f2020-01-11 17:50:39 -0800122 ::frc971::zeroing::UnwrapSensor spring_unwrap_{spring_offset_,
123 spring_range()};
Stephan Massalta769ca22019-01-09 05:29:13 +0000124
125 State state_ = State::UNINITIALIZED;
126
Austin Schuh17dd0892018-03-02 20:06:31 -0800127 double intake_last_position_ = 0.0;
Sabina Davis8d20ca82018-02-19 13:17:45 -0800128};
129
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -0800130} // namespace y2018::control_loops::superstructure::intake
Sabina Davis8d20ca82018-02-19 13:17:45 -0800131
132#endif // Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_INTAKE_INTAKE_H_