blob: b8c674fed5f232418b722a99267abd32d361ae66 [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
Austin Schuhbe041152016-02-28 22:01:52 -080060 // Returns the controller error.
61 const StateFeedbackLoop<3, 1, 1> &controller() const { return *loop_; }
62
Austin Schuh10c2d112016-02-14 13:42:28 -080063 // Returns the filtered goal.
64 const Eigen::Matrix<double, 3, 1> &goal() const { return loop_->R(); }
65 double goal(int row, int col) const { return loop_->R(row, col); }
66
67 // Returns the unprofiled goal.
68 const Eigen::Matrix<double, 3, 1> &unprofiled_goal() const {
69 return unprofiled_goal_;
70 }
71 double unprofiled_goal(int row, int col) const {
72 return unprofiled_goal_(row, col);
73 }
74
75 // Returns the current state estimate.
76 const Eigen::Matrix<double, 3, 1> &X_hat() const { return loop_->X_hat(); }
77 double X_hat(int row, int col) const { return loop_->X_hat(row, col); }
78
Diana Vandenberge2843c62016-02-13 17:44:20 -080079 // For testing:
80 // Triggers an estimator error.
81 void TriggerEstimatorError() { estimator_.TriggerError(); }
82
Austin Schuh10c2d112016-02-14 13:42:28 -080083 private:
84 // Limits the provided goal to the soft limits. Prints "name" when it fails
85 // to aid debugging.
86 void CapGoal(const char *name, Eigen::Matrix<double, 3, 1> *goal);
87
88 void UpdateIntakeOffset(double offset);
89
Brian Silverman2b1957a2016-02-14 20:29:57 -050090 ::std::unique_ptr<
91 ::frc971::control_loops::SimpleCappedStateFeedbackLoop<3, 1, 1>> loop_;
Austin Schuh10c2d112016-02-14 13:42:28 -080092
93 ::frc971::zeroing::ZeroingEstimator estimator_;
94 aos::util::TrapezoidProfile profile_;
95
96 // Current measurement.
97 Eigen::Matrix<double, 1, 1> Y_;
98 // Current offset. Y_ = offset_ + raw_sensor;
99 Eigen::Matrix<double, 1, 1> offset_;
100
101 // The goal that the profile tries to reach.
102 Eigen::Matrix<double, 3, 1> unprofiled_goal_;
103
104 bool initialized_ = false;
105 bool zeroed_ = false;
106};
107
Diana Vandenberge2843c62016-02-13 17:44:20 -0800108
Austin Schuh10c2d112016-02-14 13:42:28 -0800109class Arm {
110 public:
111 Arm();
112 // Returns whether the estimators have been initialized and zeroed.
113 bool initialized() const { return initialized_; }
114 bool zeroed() const { return shoulder_zeroed_ && wrist_zeroed_; }
115 bool shoulder_zeroed() const { return shoulder_zeroed_; }
116 bool wrist_zeroed() const { return wrist_zeroed_; }
Diana Vandenberge2843c62016-02-13 17:44:20 -0800117 // Returns whether an error has occured
118 bool error() const {
119 return shoulder_estimator_.error() || wrist_estimator_.error();
120 }
Austin Schuh10c2d112016-02-14 13:42:28 -0800121
122 // Updates our estimator with the latest position.
123 void Correct(::frc971::PotAndIndexPosition position_shoulder,
124 ::frc971::PotAndIndexPosition position_wrist);
125
126 // Forces the goal to be the provided goal.
127 void ForceGoal(double unprofiled_goal_shoulder, double unprofiled_goal_wrist);
128 // Sets the unprofiled goal. The profiler will generate a profile to go to
129 // this goal.
130 void set_unprofiled_goal(double unprofiled_goal_shoulder,
131 double unprofiled_goal_wrist);
132
133 // Runs the controller and profile generator for a cycle.
134 void Update(bool disabled);
135
136 // Limits our profiles to a max velocity and acceleration for proper motion.
137 void AdjustProfile(double max_angular_velocity_shoulder,
138 double max_angular_acceleration_shoulder,
139 double max_angular_velocity_wrist,
140 double max_angular_acceleration_wrist);
141 void set_max_voltage(double shoulder_max_voltage, double wrist_max_voltage);
142
Austin Schuh9f4e8a72016-02-16 15:28:47 -0800143 void set_shoulder_asymetric_limits(double shoulder_min_voltage,
144 double shoulder_max_voltage) {
145 loop_->set_asymetric_voltage(0, shoulder_min_voltage, shoulder_max_voltage);
146 }
147
Austin Schuh10c2d112016-02-14 13:42:28 -0800148 // Returns true if we have exceeded any hard limits.
149 bool CheckHardLimits();
150 // Resets the internal state.
151 void Reset();
152
153 // Returns the current internal estimator state for logging.
154 ::frc971::EstimatorState ShoulderEstimatorState();
155 ::frc971::EstimatorState WristEstimatorState();
156
157 // Returns the requested shoulder and wrist voltages.
158 double shoulder_voltage() const { return loop_->U(0, 0); }
159 double wrist_voltage() const { return loop_->U(1, 0); }
160
161 // Returns the current positions.
162 double shoulder_angle() const { return Y_(0, 0); }
163 double wrist_angle() const { return Y_(1, 0) + Y_(0, 0); }
164
Austin Schuhbe041152016-02-28 22:01:52 -0800165 // Returns the controller error.
166 const StateFeedbackLoop<6, 2, 2> &controller() const { return *loop_; }
167
Austin Schuh10c2d112016-02-14 13:42:28 -0800168 // Returns the unprofiled goal.
169 const Eigen::Matrix<double, 6, 1> &unprofiled_goal() const {
170 return unprofiled_goal_;
171 }
172 double unprofiled_goal(int row, int col) const {
173 return unprofiled_goal_(row, col);
174 }
175
176 // Returns the filtered goal.
177 const Eigen::Matrix<double, 6, 1> &goal() const { return loop_->R(); }
178 double goal(int row, int col) const { return loop_->R(row, col); }
179
180 // Returns the current state estimate.
181 const Eigen::Matrix<double, 6, 1> &X_hat() const { return loop_->X_hat(); }
182 double X_hat(int row, int col) const { return loop_->X_hat(row, col); }
183
Diana Vandenberge2843c62016-02-13 17:44:20 -0800184 // For testing:
185 // Triggers an estimator error.
186 void TriggerEstimatorError() { shoulder_estimator_.TriggerError(); }
187
Austin Schuh10c2d112016-02-14 13:42:28 -0800188 private:
189 // Limits the provided goal to the soft limits. Prints "name" when it fails
190 // to aid debugging.
191 void CapGoal(const char *name, Eigen::Matrix<double, 6, 1> *goal);
192
193 // Updates the offset
194 void UpdateWristOffset(double offset);
195 void UpdateShoulderOffset(double offset);
196
197 friend class testing::SuperstructureTest_DisabledGoalTest_Test;
Brian Silverman2b1957a2016-02-14 20:29:57 -0500198 ::std::unique_ptr<
199 ::frc971::control_loops::SimpleCappedStateFeedbackLoop<6, 2, 2>> loop_;
Austin Schuh10c2d112016-02-14 13:42:28 -0800200
201 aos::util::TrapezoidProfile shoulder_profile_, wrist_profile_;
202 ::frc971::zeroing::ZeroingEstimator shoulder_estimator_, wrist_estimator_;
203
204 // Current measurement.
205 Eigen::Matrix<double, 2, 1> Y_;
206 // Current offset. Y_ = offset_ + raw_sensor;
207 Eigen::Matrix<double, 2, 1> offset_;
208
209 // The goal that the profile tries to reach.
210 Eigen::Matrix<double, 6, 1> unprofiled_goal_;
211
212 bool initialized_ = false;
213 bool shoulder_zeroed_ = false;
214 bool wrist_zeroed_ = false;
215};
216
217} // namespace superstructure
218} // namespace control_loops
219} // namespace y2016
220
221#endif // Y2016_CONTROL_LOOPS_SUPERSTRUCTURE_SUPERSTRUCTURE_CONTROLS_H_