blob: 3bc41cb743681c7bb604b5c0751a734dc83df286 [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
Austin Schuh9f4e8a72016-02-16 15:28:47 -0800140 void set_shoulder_asymetric_limits(double shoulder_min_voltage,
141 double shoulder_max_voltage) {
142 loop_->set_asymetric_voltage(0, shoulder_min_voltage, shoulder_max_voltage);
143 }
144
Austin Schuh10c2d112016-02-14 13:42:28 -0800145 // Returns true if we have exceeded any hard limits.
146 bool CheckHardLimits();
147 // Resets the internal state.
148 void Reset();
149
150 // Returns the current internal estimator state for logging.
151 ::frc971::EstimatorState ShoulderEstimatorState();
152 ::frc971::EstimatorState WristEstimatorState();
153
154 // Returns the requested shoulder and wrist voltages.
155 double shoulder_voltage() const { return loop_->U(0, 0); }
156 double wrist_voltage() const { return loop_->U(1, 0); }
157
158 // Returns the current positions.
159 double shoulder_angle() const { return Y_(0, 0); }
160 double wrist_angle() const { return Y_(1, 0) + Y_(0, 0); }
161
162 // Returns the unprofiled goal.
163 const Eigen::Matrix<double, 6, 1> &unprofiled_goal() const {
164 return unprofiled_goal_;
165 }
166 double unprofiled_goal(int row, int col) const {
167 return unprofiled_goal_(row, col);
168 }
169
170 // Returns the filtered goal.
171 const Eigen::Matrix<double, 6, 1> &goal() const { return loop_->R(); }
172 double goal(int row, int col) const { return loop_->R(row, col); }
173
174 // Returns the current state estimate.
175 const Eigen::Matrix<double, 6, 1> &X_hat() const { return loop_->X_hat(); }
176 double X_hat(int row, int col) const { return loop_->X_hat(row, col); }
177
Diana Vandenberge2843c62016-02-13 17:44:20 -0800178 // For testing:
179 // Triggers an estimator error.
180 void TriggerEstimatorError() { shoulder_estimator_.TriggerError(); }
181
Austin Schuh10c2d112016-02-14 13:42:28 -0800182 private:
183 // Limits the provided goal to the soft limits. Prints "name" when it fails
184 // to aid debugging.
185 void CapGoal(const char *name, Eigen::Matrix<double, 6, 1> *goal);
186
187 // Updates the offset
188 void UpdateWristOffset(double offset);
189 void UpdateShoulderOffset(double offset);
190
191 friend class testing::SuperstructureTest_DisabledGoalTest_Test;
Brian Silverman2b1957a2016-02-14 20:29:57 -0500192 ::std::unique_ptr<
193 ::frc971::control_loops::SimpleCappedStateFeedbackLoop<6, 2, 2>> loop_;
Austin Schuh10c2d112016-02-14 13:42:28 -0800194
195 aos::util::TrapezoidProfile shoulder_profile_, wrist_profile_;
196 ::frc971::zeroing::ZeroingEstimator shoulder_estimator_, wrist_estimator_;
197
198 // Current measurement.
199 Eigen::Matrix<double, 2, 1> Y_;
200 // Current offset. Y_ = offset_ + raw_sensor;
201 Eigen::Matrix<double, 2, 1> offset_;
202
203 // The goal that the profile tries to reach.
204 Eigen::Matrix<double, 6, 1> unprofiled_goal_;
205
206 bool initialized_ = false;
207 bool shoulder_zeroed_ = false;
208 bool wrist_zeroed_ = false;
209};
210
211} // namespace superstructure
212} // namespace control_loops
213} // namespace y2016
214
215#endif // Y2016_CONTROL_LOOPS_SUPERSTRUCTURE_SUPERSTRUCTURE_CONTROLS_H_