blob: ce50b4b8e8d4b7da9d188a32392b5fd86f2eb2e0 [file] [log] [blame]
Austin Schuh10c2d112016-02-14 13:42:28 -08001#ifndef Y2016_CONTROL_LOOPS_SUPERSTRUCTURE_SUPERSTRUCTURE_CONTROLS_H_
2#define Y2016_CONTROL_LOOPS_SUPERSTRUCTURE_SUPERSTRUCTURE_CONTROLS_H_
3
4#include <memory>
5
6#include "aos/common/controls/control_loop.h"
7#include "frc971/control_loops/state_feedback_loop.h"
Brian Silverman2b1957a2016-02-14 20:29:57 -05008#include "frc971/control_loops/simple_capped_state_feedback_loop.h"
Austin Schuh10c2d112016-02-14 13:42:28 -08009#include "aos/common/util/trapezoid_profile.h"
10
11#include "frc971/zeroing/zeroing.h"
12#include "y2016/control_loops/superstructure/superstructure.q.h"
13
14namespace y2016 {
15namespace control_loops {
16namespace superstructure {
17namespace testing {
18class SuperstructureTest_DisabledGoalTest_Test;
19} // namespace testing
20
Austin Schuh10c2d112016-02-14 13:42:28 -080021class Intake {
22 public:
23 Intake();
24 // Returns whether the estimators have been initialized and zeroed.
25 bool initialized() const { return initialized_; }
26 bool zeroed() const { return zeroed_; }
Diana Vandenberge2843c62016-02-13 17:44:20 -080027 // Returns whether an error has occured
28 bool error() const { return estimator_.error(); }
Austin Schuh10c2d112016-02-14 13:42:28 -080029
30 // Updates our estimator with the latest position.
31 void Correct(::frc971::PotAndIndexPosition position);
Adam Snaider06779722016-02-14 15:26:22 -080032 // Runs the controller and profile generator for a cycle.
33 void Update(bool disabled);
34 // Sets the maximum voltage that will be commanded by the loop.
35 void set_max_voltage(double voltage);
Austin Schuh10c2d112016-02-14 13:42:28 -080036
37 // Forces the current goal to the provided goal, bypassing the profiler.
38 void ForceGoal(double goal);
39 // Sets the unprofiled goal. The profiler will generate a profile to go to
40 // this goal.
41 void set_unprofiled_goal(double unprofiled_goal);
Austin Schuh10c2d112016-02-14 13:42:28 -080042 // Limits our profiles to a max velocity and acceleration for proper motion.
43 void AdjustProfile(double max_angular_velocity,
44 double max_angular_acceleration);
Austin Schuh10c2d112016-02-14 13:42:28 -080045
46 // Returns true if we have exceeded any hard limits.
47 bool CheckHardLimits();
48 // Resets the internal state.
49 void Reset();
50
51 // Returns the current internal estimator state for logging.
52 ::frc971::EstimatorState IntakeEstimatorState();
53
54 // Returns the requested intake voltage.
55 double intake_voltage() const { return loop_->U(0, 0); }
56
57 // Returns the current position.
58 double angle() const { return Y_(0, 0); }
59
60 // Returns the filtered goal.
61 const Eigen::Matrix<double, 3, 1> &goal() const { return loop_->R(); }
62 double goal(int row, int col) const { return loop_->R(row, col); }
63
64 // Returns the unprofiled goal.
65 const Eigen::Matrix<double, 3, 1> &unprofiled_goal() const {
66 return unprofiled_goal_;
67 }
68 double unprofiled_goal(int row, int col) const {
69 return unprofiled_goal_(row, col);
70 }
71
72 // Returns the current state estimate.
73 const Eigen::Matrix<double, 3, 1> &X_hat() const { return loop_->X_hat(); }
74 double X_hat(int row, int col) const { return loop_->X_hat(row, col); }
75
Diana Vandenberge2843c62016-02-13 17:44:20 -080076 // For testing:
77 // Triggers an estimator error.
78 void TriggerEstimatorError() { estimator_.TriggerError(); }
79
Austin Schuh10c2d112016-02-14 13:42:28 -080080 private:
81 // Limits the provided goal to the soft limits. Prints "name" when it fails
82 // to aid debugging.
83 void CapGoal(const char *name, Eigen::Matrix<double, 3, 1> *goal);
84
85 void UpdateIntakeOffset(double offset);
86
Brian Silverman2b1957a2016-02-14 20:29:57 -050087 ::std::unique_ptr<
88 ::frc971::control_loops::SimpleCappedStateFeedbackLoop<3, 1, 1>> loop_;
Austin Schuh10c2d112016-02-14 13:42:28 -080089
90 ::frc971::zeroing::ZeroingEstimator estimator_;
91 aos::util::TrapezoidProfile profile_;
92
93 // Current measurement.
94 Eigen::Matrix<double, 1, 1> Y_;
95 // Current offset. Y_ = offset_ + raw_sensor;
96 Eigen::Matrix<double, 1, 1> offset_;
97
98 // The goal that the profile tries to reach.
99 Eigen::Matrix<double, 3, 1> unprofiled_goal_;
100
101 bool initialized_ = false;
102 bool zeroed_ = false;
103};
104
Diana Vandenberge2843c62016-02-13 17:44:20 -0800105
Austin Schuh10c2d112016-02-14 13:42:28 -0800106class Arm {
107 public:
108 Arm();
109 // Returns whether the estimators have been initialized and zeroed.
110 bool initialized() const { return initialized_; }
111 bool zeroed() const { return shoulder_zeroed_ && wrist_zeroed_; }
112 bool shoulder_zeroed() const { return shoulder_zeroed_; }
113 bool wrist_zeroed() const { return wrist_zeroed_; }
Diana Vandenberge2843c62016-02-13 17:44:20 -0800114 // Returns whether an error has occured
115 bool error() const {
116 return shoulder_estimator_.error() || wrist_estimator_.error();
117 }
Austin Schuh10c2d112016-02-14 13:42:28 -0800118
119 // Updates our estimator with the latest position.
120 void Correct(::frc971::PotAndIndexPosition position_shoulder,
121 ::frc971::PotAndIndexPosition position_wrist);
122
123 // Forces the goal to be the provided goal.
124 void ForceGoal(double unprofiled_goal_shoulder, double unprofiled_goal_wrist);
125 // Sets the unprofiled goal. The profiler will generate a profile to go to
126 // this goal.
127 void set_unprofiled_goal(double unprofiled_goal_shoulder,
128 double unprofiled_goal_wrist);
129
130 // Runs the controller and profile generator for a cycle.
131 void Update(bool disabled);
132
133 // Limits our profiles to a max velocity and acceleration for proper motion.
134 void AdjustProfile(double max_angular_velocity_shoulder,
135 double max_angular_acceleration_shoulder,
136 double max_angular_velocity_wrist,
137 double max_angular_acceleration_wrist);
138 void set_max_voltage(double shoulder_max_voltage, double wrist_max_voltage);
139
140 // Returns true if we have exceeded any hard limits.
141 bool CheckHardLimits();
142 // Resets the internal state.
143 void Reset();
144
145 // Returns the current internal estimator state for logging.
146 ::frc971::EstimatorState ShoulderEstimatorState();
147 ::frc971::EstimatorState WristEstimatorState();
148
149 // Returns the requested shoulder and wrist voltages.
150 double shoulder_voltage() const { return loop_->U(0, 0); }
151 double wrist_voltage() const { return loop_->U(1, 0); }
152
153 // Returns the current positions.
154 double shoulder_angle() const { return Y_(0, 0); }
155 double wrist_angle() const { return Y_(1, 0) + Y_(0, 0); }
156
157 // Returns the unprofiled goal.
158 const Eigen::Matrix<double, 6, 1> &unprofiled_goal() const {
159 return unprofiled_goal_;
160 }
161 double unprofiled_goal(int row, int col) const {
162 return unprofiled_goal_(row, col);
163 }
164
165 // Returns the filtered goal.
166 const Eigen::Matrix<double, 6, 1> &goal() const { return loop_->R(); }
167 double goal(int row, int col) const { return loop_->R(row, col); }
168
169 // Returns the current state estimate.
170 const Eigen::Matrix<double, 6, 1> &X_hat() const { return loop_->X_hat(); }
171 double X_hat(int row, int col) const { return loop_->X_hat(row, col); }
172
Diana Vandenberge2843c62016-02-13 17:44:20 -0800173 // For testing:
174 // Triggers an estimator error.
175 void TriggerEstimatorError() { shoulder_estimator_.TriggerError(); }
176
Austin Schuh10c2d112016-02-14 13:42:28 -0800177 private:
178 // Limits the provided goal to the soft limits. Prints "name" when it fails
179 // to aid debugging.
180 void CapGoal(const char *name, Eigen::Matrix<double, 6, 1> *goal);
181
182 // Updates the offset
183 void UpdateWristOffset(double offset);
184 void UpdateShoulderOffset(double offset);
185
186 friend class testing::SuperstructureTest_DisabledGoalTest_Test;
Brian Silverman2b1957a2016-02-14 20:29:57 -0500187 ::std::unique_ptr<
188 ::frc971::control_loops::SimpleCappedStateFeedbackLoop<6, 2, 2>> loop_;
Austin Schuh10c2d112016-02-14 13:42:28 -0800189
190 aos::util::TrapezoidProfile shoulder_profile_, wrist_profile_;
191 ::frc971::zeroing::ZeroingEstimator shoulder_estimator_, wrist_estimator_;
192
193 // Current measurement.
194 Eigen::Matrix<double, 2, 1> Y_;
195 // Current offset. Y_ = offset_ + raw_sensor;
196 Eigen::Matrix<double, 2, 1> offset_;
197
198 // The goal that the profile tries to reach.
199 Eigen::Matrix<double, 6, 1> unprofiled_goal_;
200
201 bool initialized_ = false;
202 bool shoulder_zeroed_ = false;
203 bool wrist_zeroed_ = false;
204};
205
206} // namespace superstructure
207} // namespace control_loops
208} // namespace y2016
209
210#endif // Y2016_CONTROL_LOOPS_SUPERSTRUCTURE_SUPERSTRUCTURE_CONTROLS_H_