blob: ee645542f1b61b9a0467d13fb6d728bcfa1ebb1d [file] [log] [blame]
Brian Silvermanb691f5e2015-08-02 11:37:55 -07001#ifndef Y2015_CONTROL_LOOPS_FRIDGE_H_
2#define Y2015_CONTROL_LOOPS_FRIDGE_H_
Ben Fredrickson6b5ba792015-01-25 17:14:40 -08003
4#include <memory>
5
6#include "aos/common/controls/control_loop.h"
Philipp Schrader3e281412015-03-01 23:48:23 +00007#include "aos/common/util/trapezoid_profile.h"
Ben Fredrickson6b5ba792015-01-25 17:14:40 -08008#include "frc971/control_loops/state_feedback_loop.h"
Brian Silvermanb691f5e2015-08-02 11:37:55 -07009#include "y2015/control_loops/fridge/fridge.q.h"
Austin Schuh703b8d42015-02-01 14:56:34 -080010#include "frc971/zeroing/zeroing.h"
Brian Silvermanb691f5e2015-08-02 11:37:55 -070011#include "y2015/util/kinematics.h"
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080012
Austin Schuh88af0852016-12-04 20:31:32 -080013namespace y2015 {
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080014namespace control_loops {
Austin Schuh88af0852016-12-04 20:31:32 -080015namespace fridge {
Austin Schuhdbd6bfa2015-02-14 21:25:16 -080016namespace testing {
17class FridgeTest_DisabledGoalTest_Test;
18class FridgeTest_ArmGoalPositiveWindupTest_Test;
19class FridgeTest_ElevatorGoalPositiveWindupTest_Test;
20class FridgeTest_ArmGoalNegativeWindupTest_Test;
21class FridgeTest_ElevatorGoalNegativeWindupTest_Test;
Daniel Pettie1bb13e2015-02-17 13:59:15 -080022class FridgeTest_SafeArmZeroing_Test;
Austin Schuh8de10c72015-02-27 23:33:40 -080023} // namespace testing
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080024
Austin Schuh8de10c72015-02-27 23:33:40 -080025template<int S>
26class CappedStateFeedbackLoop : public StateFeedbackLoop<S, 2, 2> {
Austin Schuh703b8d42015-02-01 14:56:34 -080027 public:
Austin Schuh8de10c72015-02-27 23:33:40 -080028 CappedStateFeedbackLoop(StateFeedbackLoop<S, 2, 2> &&loop)
29 : StateFeedbackLoop<S, 2, 2>(::std::move(loop)), max_voltage_(12.0) {}
Austin Schuh703b8d42015-02-01 14:56:34 -080030
31 void set_max_voltage(double max_voltage) {
Austin Schuh8de10c72015-02-27 23:33:40 -080032 max_voltage_ = ::std::max(0.0, ::std::min(12.0, max_voltage));
Austin Schuh703b8d42015-02-01 14:56:34 -080033 }
34
35 void CapU() override;
36
37 // Returns the amount to change the position goals (average and difference) in
38 // order to no longer saturate the controller.
39 Eigen::Matrix<double, 2, 1> UnsaturateOutputGoalChange();
40
41 private:
42 double max_voltage_;
43};
44
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080045class Fridge
Austin Schuh88af0852016-12-04 20:31:32 -080046 : public aos::controls::ControlLoop<FridgeQueue> {
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080047 public:
Austin Schuh88af0852016-12-04 20:31:32 -080048 explicit Fridge(FridgeQueue *fridge_queue =
49 &::y2015::control_loops::fridge::fridge_queue);
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080050
Austin Schuhdbd6bfa2015-02-14 21:25:16 -080051 enum State {
52 // Waiting to receive data before doing anything.
53 UNINITIALIZED = 0,
54 // Estimating the starting location.
55 INITIALIZING = 1,
56 // Moving the elevator to find an index pulse.
57 ZEROING_ELEVATOR = 2,
58 // Moving the arm to find an index pulse.
59 ZEROING_ARM = 3,
60 // All good!
61 RUNNING = 4,
62 // Internal error caused the fridge to abort.
63 ESTOP = 5,
64 };
65
Philipp Schrader085bf012015-03-15 01:43:11 +000066 enum class ProfilingType : int32_t {
67 // Use angle/height to specify the fridge goal.
68 ANGLE_HEIGHT_PROFILING = 0,
69 // Use x/y co-ordinates to specify the fridge goal.
70 X_Y_PROFILING = 1,
71 };
72
Austin Schuhdbd6bfa2015-02-14 21:25:16 -080073 State state() const { return state_; }
74
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080075 protected:
Austin Schuh88af0852016-12-04 20:31:32 -080076 void RunIteration(const FridgeQueue::Goal *goal,
77 const FridgeQueue::Position *position,
78 FridgeQueue::Output *output,
79 FridgeQueue::Status *status) override;
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080080
81 private:
Austin Schuhdbd6bfa2015-02-14 21:25:16 -080082 friend class testing::FridgeTest_DisabledGoalTest_Test;
83 friend class testing::FridgeTest_ElevatorGoalPositiveWindupTest_Test;
84 friend class testing::FridgeTest_ArmGoalPositiveWindupTest_Test;
85 friend class testing::FridgeTest_ElevatorGoalNegativeWindupTest_Test;
86 friend class testing::FridgeTest_ArmGoalNegativeWindupTest_Test;
Daniel Pettie1bb13e2015-02-17 13:59:15 -080087 friend class testing::FridgeTest_SafeArmZeroing_Test;
Austin Schuhdbd6bfa2015-02-14 21:25:16 -080088
Austin Schuh703b8d42015-02-01 14:56:34 -080089 // Sets state_ to the correct state given the current state of the zeroing
90 // estimators.
91 void UpdateZeroingState();
92
93 void SetElevatorOffset(double left_offset, double right_offset);
94 void SetArmOffset(double left_offset, double right_offset);
95
96 // Getters for the current elevator positions.
97 double left_elevator();
98 double right_elevator();
99 double elevator();
100
101 // Getters for the current arm positions.
102 double left_arm();
103 double right_arm();
104 double arm();
105
106 // Our best guess at the current position of the elevator.
107 double estimated_left_elevator();
108 double estimated_right_elevator();
109 double estimated_elevator();
110
111 // Our best guess at the current position of the arm.
112 double estimated_left_arm();
113 double estimated_right_arm();
114 double estimated_arm();
115
116 // Returns the current zeroing velocity for either subsystem.
117 // If the subsystem is too far away from the center, these will switch
118 // directions.
119 double elevator_zeroing_velocity();
120 double arm_zeroing_velocity();
121
122 // Corrects the Observer with the current position.
123 void Correct();
124
Philipp Schrader3e281412015-03-01 23:48:23 +0000125 double UseUnlessZero(double target_value, double default_value);
126
Ben Fredrickson6b5ba792015-01-25 17:14:40 -0800127 // The state feedback control loop or loops to talk to.
Austin Schuh8de10c72015-02-27 23:33:40 -0800128 ::std::unique_ptr<CappedStateFeedbackLoop<5>> arm_loop_;
129 ::std::unique_ptr<CappedStateFeedbackLoop<4>> elevator_loop_;
Austin Schuh703b8d42015-02-01 14:56:34 -0800130
Austin Schuh88af0852016-12-04 20:31:32 -0800131 ::frc971::zeroing::ZeroingEstimator left_arm_estimator_;
132 ::frc971::zeroing::ZeroingEstimator right_arm_estimator_;
133 ::frc971::zeroing::ZeroingEstimator left_elevator_estimator_;
134 ::frc971::zeroing::ZeroingEstimator right_elevator_estimator_;
Austin Schuh703b8d42015-02-01 14:56:34 -0800135
136 // Offsets from the encoder position to the absolute position. Add these to
137 // the encoder position to get the absolute position.
138 double left_elevator_offset_ = 0.0;
139 double right_elevator_offset_ = 0.0;
140 double left_arm_offset_ = 0.0;
141 double right_arm_offset_ = 0.0;
142
143 // Current velocity to move at while zeroing.
144 double elevator_zeroing_velocity_ = 0.0;
145 double arm_zeroing_velocity_ = 0.0;
146
147 // The goals for the elevator and arm.
148 double elevator_goal_ = 0.0;
149 double arm_goal_ = 0.0;
150
Philipp Schrader085bf012015-03-15 01:43:11 +0000151 double arm_goal_velocity_ = 0.0;
152 double elevator_goal_velocity_ = 0.0;
153
Austin Schuh703b8d42015-02-01 14:56:34 -0800154 State state_ = UNINITIALIZED;
155 State last_state_ = UNINITIALIZED;
156
Austin Schuh88af0852016-12-04 20:31:32 -0800157 FridgeQueue::Position current_position_;
Philipp Schrader3e281412015-03-01 23:48:23 +0000158
Philipp Schrader085bf012015-03-15 01:43:11 +0000159 ProfilingType last_profiling_type_;
160 aos::util::ElevatorArmKinematics kinematics_;
161
Philipp Schrader3e281412015-03-01 23:48:23 +0000162 aos::util::TrapezoidProfile arm_profile_;
163 aos::util::TrapezoidProfile elevator_profile_;
Philipp Schrader085bf012015-03-15 01:43:11 +0000164
165 aos::util::TrapezoidProfile x_profile_;
166 aos::util::TrapezoidProfile y_profile_;
Ben Fredrickson6b5ba792015-01-25 17:14:40 -0800167};
168
Austin Schuh88af0852016-12-04 20:31:32 -0800169} // namespace fridge
Ben Fredrickson6b5ba792015-01-25 17:14:40 -0800170} // namespace control_loops
Austin Schuh88af0852016-12-04 20:31:32 -0800171} // namespace y2015
Ben Fredrickson6b5ba792015-01-25 17:14:40 -0800172
Brian Silvermanb691f5e2015-08-02 11:37:55 -0700173#endif // Y2015_CONTROL_LOOPS_FRIDGE_H_
Ben Fredrickson6b5ba792015-01-25 17:14:40 -0800174