blob: d20b345a97c3ce2076d32c08e88c426c788a1ae5 [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_; }
27
28 // Updates our estimator with the latest position.
29 void Correct(::frc971::PotAndIndexPosition position);
Adam Snaider06779722016-02-14 15:26:22 -080030 // Runs the controller and profile generator for a cycle.
31 void Update(bool disabled);
32 // Sets the maximum voltage that will be commanded by the loop.
33 void set_max_voltage(double voltage);
Austin Schuh10c2d112016-02-14 13:42:28 -080034
35 // Forces the current goal to the provided goal, bypassing the profiler.
36 void ForceGoal(double goal);
37 // Sets the unprofiled goal. The profiler will generate a profile to go to
38 // this goal.
39 void set_unprofiled_goal(double unprofiled_goal);
Austin Schuh10c2d112016-02-14 13:42:28 -080040 // Limits our profiles to a max velocity and acceleration for proper motion.
41 void AdjustProfile(double max_angular_velocity,
42 double max_angular_acceleration);
Austin Schuh10c2d112016-02-14 13:42:28 -080043
44 // Returns true if we have exceeded any hard limits.
45 bool CheckHardLimits();
46 // Resets the internal state.
47 void Reset();
48
49 // Returns the current internal estimator state for logging.
50 ::frc971::EstimatorState IntakeEstimatorState();
51
52 // Returns the requested intake voltage.
53 double intake_voltage() const { return loop_->U(0, 0); }
54
55 // Returns the current position.
56 double angle() const { return Y_(0, 0); }
57
58 // Returns the filtered goal.
59 const Eigen::Matrix<double, 3, 1> &goal() const { return loop_->R(); }
60 double goal(int row, int col) const { return loop_->R(row, col); }
61
62 // Returns the unprofiled goal.
63 const Eigen::Matrix<double, 3, 1> &unprofiled_goal() const {
64 return unprofiled_goal_;
65 }
66 double unprofiled_goal(int row, int col) const {
67 return unprofiled_goal_(row, col);
68 }
69
70 // Returns the current state estimate.
71 const Eigen::Matrix<double, 3, 1> &X_hat() const { return loop_->X_hat(); }
72 double X_hat(int row, int col) const { return loop_->X_hat(row, col); }
73
74 private:
75 // Limits the provided goal to the soft limits. Prints "name" when it fails
76 // to aid debugging.
77 void CapGoal(const char *name, Eigen::Matrix<double, 3, 1> *goal);
78
79 void UpdateIntakeOffset(double offset);
80
Brian Silverman2b1957a2016-02-14 20:29:57 -050081 ::std::unique_ptr<
82 ::frc971::control_loops::SimpleCappedStateFeedbackLoop<3, 1, 1>> loop_;
Austin Schuh10c2d112016-02-14 13:42:28 -080083
84 ::frc971::zeroing::ZeroingEstimator estimator_;
85 aos::util::TrapezoidProfile profile_;
86
87 // Current measurement.
88 Eigen::Matrix<double, 1, 1> Y_;
89 // Current offset. Y_ = offset_ + raw_sensor;
90 Eigen::Matrix<double, 1, 1> offset_;
91
92 // The goal that the profile tries to reach.
93 Eigen::Matrix<double, 3, 1> unprofiled_goal_;
94
95 bool initialized_ = false;
96 bool zeroed_ = false;
97};
98
99class Arm {
100 public:
101 Arm();
102 // Returns whether the estimators have been initialized and zeroed.
103 bool initialized() const { return initialized_; }
104 bool zeroed() const { return shoulder_zeroed_ && wrist_zeroed_; }
105 bool shoulder_zeroed() const { return shoulder_zeroed_; }
106 bool wrist_zeroed() const { return wrist_zeroed_; }
107
108 // Updates our estimator with the latest position.
109 void Correct(::frc971::PotAndIndexPosition position_shoulder,
110 ::frc971::PotAndIndexPosition position_wrist);
111
112 // Forces the goal to be the provided goal.
113 void ForceGoal(double unprofiled_goal_shoulder, double unprofiled_goal_wrist);
114 // Sets the unprofiled goal. The profiler will generate a profile to go to
115 // this goal.
116 void set_unprofiled_goal(double unprofiled_goal_shoulder,
117 double unprofiled_goal_wrist);
118
119 // Runs the controller and profile generator for a cycle.
120 void Update(bool disabled);
121
122 // Limits our profiles to a max velocity and acceleration for proper motion.
123 void AdjustProfile(double max_angular_velocity_shoulder,
124 double max_angular_acceleration_shoulder,
125 double max_angular_velocity_wrist,
126 double max_angular_acceleration_wrist);
127 void set_max_voltage(double shoulder_max_voltage, double wrist_max_voltage);
128
129 // Returns true if we have exceeded any hard limits.
130 bool CheckHardLimits();
131 // Resets the internal state.
132 void Reset();
133
134 // Returns the current internal estimator state for logging.
135 ::frc971::EstimatorState ShoulderEstimatorState();
136 ::frc971::EstimatorState WristEstimatorState();
137
138 // Returns the requested shoulder and wrist voltages.
139 double shoulder_voltage() const { return loop_->U(0, 0); }
140 double wrist_voltage() const { return loop_->U(1, 0); }
141
142 // Returns the current positions.
143 double shoulder_angle() const { return Y_(0, 0); }
144 double wrist_angle() const { return Y_(1, 0) + Y_(0, 0); }
145
146 // Returns the unprofiled goal.
147 const Eigen::Matrix<double, 6, 1> &unprofiled_goal() const {
148 return unprofiled_goal_;
149 }
150 double unprofiled_goal(int row, int col) const {
151 return unprofiled_goal_(row, col);
152 }
153
154 // Returns the filtered goal.
155 const Eigen::Matrix<double, 6, 1> &goal() const { return loop_->R(); }
156 double goal(int row, int col) const { return loop_->R(row, col); }
157
158 // Returns the current state estimate.
159 const Eigen::Matrix<double, 6, 1> &X_hat() const { return loop_->X_hat(); }
160 double X_hat(int row, int col) const { return loop_->X_hat(row, col); }
161
162 private:
163 // Limits the provided goal to the soft limits. Prints "name" when it fails
164 // to aid debugging.
165 void CapGoal(const char *name, Eigen::Matrix<double, 6, 1> *goal);
166
167 // Updates the offset
168 void UpdateWristOffset(double offset);
169 void UpdateShoulderOffset(double offset);
170
171 friend class testing::SuperstructureTest_DisabledGoalTest_Test;
Brian Silverman2b1957a2016-02-14 20:29:57 -0500172 ::std::unique_ptr<
173 ::frc971::control_loops::SimpleCappedStateFeedbackLoop<6, 2, 2>> loop_;
Austin Schuh10c2d112016-02-14 13:42:28 -0800174
175 aos::util::TrapezoidProfile shoulder_profile_, wrist_profile_;
176 ::frc971::zeroing::ZeroingEstimator shoulder_estimator_, wrist_estimator_;
177
178 // Current measurement.
179 Eigen::Matrix<double, 2, 1> Y_;
180 // Current offset. Y_ = offset_ + raw_sensor;
181 Eigen::Matrix<double, 2, 1> offset_;
182
183 // The goal that the profile tries to reach.
184 Eigen::Matrix<double, 6, 1> unprofiled_goal_;
185
186 bool initialized_ = false;
187 bool shoulder_zeroed_ = false;
188 bool wrist_zeroed_ = false;
189};
190
191} // namespace superstructure
192} // namespace control_loops
193} // namespace y2016
194
195#endif // Y2016_CONTROL_LOOPS_SUPERSTRUCTURE_SUPERSTRUCTURE_CONTROLS_H_