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