blob: e064c0e42fbec472320ce5a62f103ad12d835e27 [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
Stephan Massalta769ca22019-01-09 05:29:13 +00004#include <math.h>
5
John Park33858a32018-09-28 23:05:48 -07006#include "aos/commonmath.h"
7#include "aos/controls/control_loop.h"
Stephan Massalt4d1e74f2020-01-11 17:50:39 -08008#include "frc971/zeroing/wrap.h"
Sabina Davis8d20ca82018-02-19 13:17:45 -08009#include "frc971/zeroing/zeroing.h"
10#include "y2018/constants.h"
11#include "y2018/control_loops/superstructure/intake/intake_delayed_plant.h"
12#include "y2018/control_loops/superstructure/intake/intake_plant.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070013#include "y2018/control_loops/superstructure/superstructure_output_generated.h"
14#include "y2018/control_loops/superstructure/superstructure_position_generated.h"
15#include "y2018/control_loops/superstructure/superstructure_status_generated.h"
Sabina Davis8d20ca82018-02-19 13:17:45 -080016
17namespace y2018 {
18namespace control_loops {
19namespace superstructure {
20namespace intake {
21
22class IntakeController {
23 public:
24 IntakeController();
25
26 // Sets the current encoder position in radians
27 void set_position(double spring_angle, double output_position);
28
29 // Populates the status structure.
Alex Perrycb7da4b2019-08-28 19:35:56 -070030 void SetStatus(superstructure::IntakeSideStatus::Builder *status,
Sabina Davis8d20ca82018-02-19 13:17:45 -080031 const double *unsafe_goal);
32
33 // Returns the control loop calculated voltage.
34 double voltage() const;
35
Austin Schuh96341532018-03-09 21:17:24 -080036 double output_position() const { return loop_->X_hat(0); }
Alex Perrycb7da4b2019-08-28 19:35:56 -070037 double motor_position() const { return loop_->X_hat(2); }
Austin Schuh96341532018-03-09 21:17:24 -080038
Sabina Davis8d20ca82018-02-19 13:17:45 -080039 // Executes the control loop for a cycle.
40 void Update(bool disabled, const double *unsafe_goal);
41
42 // Resets the kalman filter and any other internal state.
43 void Reset();
44
45 // Sets the goal angle from unsafe_goal.
46 double goal_angle(const double *unsafe_goal);
47
Sabina Davis8d20ca82018-02-19 13:17:45 -080048 constexpr static double kDt =
James Kuszmaul651fc3f2019-05-15 21:14:25 -070049 ::aos::time::DurationInSeconds(::aos::controls::kLoopFrequency);
Sabina Davis8d20ca82018-02-19 13:17:45 -080050
51 // Sets the offset of the controller to be the zeroing estimator offset when
52 // possible otherwise zero.
53 void UpdateOffset(double offset);
54
Alex Perrycb7da4b2019-08-28 19:35:56 -070055 const ::frc971::constants::Range intake_range() const {
56 return intake_range_;
57 }
58
59 private:
60 // The control loop.
61 ::std::unique_ptr<
62 StateFeedbackLoop<5, 1, 2, double, StateFeedbackPlant<5, 1, 2>,
63 StateFeedbackObserver<5, 1, 2>>>
64 loop_;
65
Sabina Davis8d20ca82018-02-19 13:17:45 -080066 const ::frc971::constants::Range intake_range_;
67
68 // Stores the current zeroing estimator offset.
69 double offset_ = 0.0;
70
Sabina Davis8d20ca82018-02-19 13:17:45 -080071 bool reset_ = true;
72
73 // The current sensor measurement.
74 Eigen::Matrix<double, 2, 1> Y_;
75
76 DISALLOW_COPY_AND_ASSIGN(IntakeController);
77};
78
79class IntakeSide {
80 public:
81 IntakeSide(const ::frc971::constants::PotAndAbsoluteEncoderZeroingConstants
Stephan Massalta769ca22019-01-09 05:29:13 +000082 &zeroing_constants,
83 const double spring_offset);
Sabina Davis8d20ca82018-02-19 13:17:45 -080084
85 // The operating voltage.
86 static constexpr double kOperatingVoltage() { return 12.0; }
87
Alex Perrycb7da4b2019-08-28 19:35:56 -070088 flatbuffers::Offset<superstructure::IntakeSideStatus> Iterate(
89 const double *unsafe_goal,
90 const superstructure::IntakeElasticSensors *position,
91 superstructure::IntakeVoltageT *output,
92 flatbuffers::FlatBufferBuilder *fbb);
Sabina Davis8d20ca82018-02-19 13:17:45 -080093
94 void Reset();
95
96 enum class State : int32_t {
97 UNINITIALIZED,
98 ZEROING,
99 RUNNING,
100 ESTOP,
101 };
102
103 State state() const { return state_; }
104
Alex Perrycb7da4b2019-08-28 19:35:56 -0700105 bool estopped() const { return state_ == State::ESTOP; }
Stephan Massalta769ca22019-01-09 05:29:13 +0000106
Alex Perrycb7da4b2019-08-28 19:35:56 -0700107 bool zeroed() const { return zeroing_estimator_.zeroed(); }
108
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700109 bool clear_of_box() const { return controller_.output_position() < -0.1; }
Austin Schuh96341532018-03-09 21:17:24 -0800110
Neil Balchba9cbba2018-04-06 22:26:38 -0700111 double output_position() const { return controller_.output_position(); }
112
Sabina Davis8d20ca82018-02-19 13:17:45 -0800113 private:
114 IntakeController controller_;
115
Austin Schuh72db9a12019-01-21 18:02:51 -0800116 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator zeroing_estimator_;
Austin Schuh17dd0892018-03-02 20:06:31 -0800117
Stephan Massalta769ca22019-01-09 05:29:13 +0000118 const double spring_offset_;
119
120 double spring_range() const {
121 return ::y2018::constants::Values::kIntakeSpringRatio() * (2 * M_PI);
122 }
123
Stephan Massalt4d1e74f2020-01-11 17:50:39 -0800124 ::frc971::zeroing::UnwrapSensor spring_unwrap_{spring_offset_,
125 spring_range()};
Stephan Massalta769ca22019-01-09 05:29:13 +0000126
127 State state_ = State::UNINITIALIZED;
128
Austin Schuh17dd0892018-03-02 20:06:31 -0800129 double intake_last_position_ = 0.0;
Sabina Davis8d20ca82018-02-19 13:17:45 -0800130};
131
132} // namespace intake
133} // namespace superstructure
134} // namespace control_loops
135} // namespace y2018
136
137#endif // Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_INTAKE_INTAKE_H_