blob: e9cbaa57063521e4d6ec0d3e2f0790fb556b5536 [file] [log] [blame]
Ben Fredrickson6b5ba792015-01-25 17:14:40 -08001#ifndef FRC971_CONTROL_LOOPS_FRIDGE_H_
2#define FRC971_CONTROL_LOOPS_FRIDGE_H_
3
4#include <memory>
5
6#include "aos/common/controls/control_loop.h"
7#include "frc971/control_loops/state_feedback_loop.h"
8#include "frc971/control_loops/fridge/fridge.q.h"
Austin Schuh703b8d42015-02-01 14:56:34 -08009#include "frc971/zeroing/zeroing.h"
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080010
11namespace frc971 {
12namespace control_loops {
Austin Schuhdbd6bfa2015-02-14 21:25:16 -080013namespace testing {
14class FridgeTest_DisabledGoalTest_Test;
15class FridgeTest_ArmGoalPositiveWindupTest_Test;
16class FridgeTest_ElevatorGoalPositiveWindupTest_Test;
17class FridgeTest_ArmGoalNegativeWindupTest_Test;
18class FridgeTest_ElevatorGoalNegativeWindupTest_Test;
Daniel Pettie1bb13e2015-02-17 13:59:15 -080019class FridgeTest_SafeArmZeroing_Test;
Austin Schuh8de10c72015-02-27 23:33:40 -080020} // namespace testing
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080021
Austin Schuh8de10c72015-02-27 23:33:40 -080022template<int S>
23class CappedStateFeedbackLoop : public StateFeedbackLoop<S, 2, 2> {
Austin Schuh703b8d42015-02-01 14:56:34 -080024 public:
Austin Schuh8de10c72015-02-27 23:33:40 -080025 CappedStateFeedbackLoop(StateFeedbackLoop<S, 2, 2> &&loop)
26 : StateFeedbackLoop<S, 2, 2>(::std::move(loop)), max_voltage_(12.0) {}
Austin Schuh703b8d42015-02-01 14:56:34 -080027
28 void set_max_voltage(double max_voltage) {
Austin Schuh8de10c72015-02-27 23:33:40 -080029 max_voltage_ = ::std::max(0.0, ::std::min(12.0, max_voltage));
Austin Schuh703b8d42015-02-01 14:56:34 -080030 }
31
32 void CapU() override;
33
34 // Returns the amount to change the position goals (average and difference) in
35 // order to no longer saturate the controller.
36 Eigen::Matrix<double, 2, 1> UnsaturateOutputGoalChange();
37
38 private:
39 double max_voltage_;
40};
41
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080042class Fridge
Brian Silverman089f5812015-02-15 01:58:19 -050043 : public aos::controls::ControlLoop<control_loops::FridgeQueue> {
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080044 public:
45 explicit Fridge(
46 control_loops::FridgeQueue *fridge_queue = &control_loops::fridge_queue);
47
Austin Schuhdbd6bfa2015-02-14 21:25:16 -080048 enum State {
49 // Waiting to receive data before doing anything.
50 UNINITIALIZED = 0,
51 // Estimating the starting location.
52 INITIALIZING = 1,
53 // Moving the elevator to find an index pulse.
54 ZEROING_ELEVATOR = 2,
55 // Moving the arm to find an index pulse.
56 ZEROING_ARM = 3,
57 // All good!
58 RUNNING = 4,
59 // Internal error caused the fridge to abort.
60 ESTOP = 5,
61 };
62
63 State state() const { return state_; }
64
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080065 protected:
Austin Schuh703b8d42015-02-01 14:56:34 -080066 void RunIteration(const control_loops::FridgeQueue::Goal *goal,
67 const control_loops::FridgeQueue::Position *position,
68 control_loops::FridgeQueue::Output *output,
69 control_loops::FridgeQueue::Status *status) override;
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080070
71 private:
Austin Schuhdbd6bfa2015-02-14 21:25:16 -080072 friend class testing::FridgeTest_DisabledGoalTest_Test;
73 friend class testing::FridgeTest_ElevatorGoalPositiveWindupTest_Test;
74 friend class testing::FridgeTest_ArmGoalPositiveWindupTest_Test;
75 friend class testing::FridgeTest_ElevatorGoalNegativeWindupTest_Test;
76 friend class testing::FridgeTest_ArmGoalNegativeWindupTest_Test;
Daniel Pettie1bb13e2015-02-17 13:59:15 -080077 friend class testing::FridgeTest_SafeArmZeroing_Test;
Austin Schuhdbd6bfa2015-02-14 21:25:16 -080078
Austin Schuh703b8d42015-02-01 14:56:34 -080079 // Sets state_ to the correct state given the current state of the zeroing
80 // estimators.
81 void UpdateZeroingState();
82
83 void SetElevatorOffset(double left_offset, double right_offset);
84 void SetArmOffset(double left_offset, double right_offset);
85
86 // Getters for the current elevator positions.
87 double left_elevator();
88 double right_elevator();
89 double elevator();
90
91 // Getters for the current arm positions.
92 double left_arm();
93 double right_arm();
94 double arm();
95
96 // Our best guess at the current position of the elevator.
97 double estimated_left_elevator();
98 double estimated_right_elevator();
99 double estimated_elevator();
100
101 // Our best guess at the current position of the arm.
102 double estimated_left_arm();
103 double estimated_right_arm();
104 double estimated_arm();
105
106 // Returns the current zeroing velocity for either subsystem.
107 // If the subsystem is too far away from the center, these will switch
108 // directions.
109 double elevator_zeroing_velocity();
110 double arm_zeroing_velocity();
111
112 // Corrects the Observer with the current position.
113 void Correct();
114
Ben Fredrickson6b5ba792015-01-25 17:14:40 -0800115 // The state feedback control loop or loops to talk to.
Austin Schuh8de10c72015-02-27 23:33:40 -0800116 ::std::unique_ptr<CappedStateFeedbackLoop<5>> arm_loop_;
117 ::std::unique_ptr<CappedStateFeedbackLoop<4>> elevator_loop_;
Austin Schuh703b8d42015-02-01 14:56:34 -0800118
119 zeroing::ZeroingEstimator left_arm_estimator_;
120 zeroing::ZeroingEstimator right_arm_estimator_;
121 zeroing::ZeroingEstimator left_elevator_estimator_;
122 zeroing::ZeroingEstimator right_elevator_estimator_;
123
124 // Offsets from the encoder position to the absolute position. Add these to
125 // the encoder position to get the absolute position.
126 double left_elevator_offset_ = 0.0;
127 double right_elevator_offset_ = 0.0;
128 double left_arm_offset_ = 0.0;
129 double right_arm_offset_ = 0.0;
130
131 // Current velocity to move at while zeroing.
132 double elevator_zeroing_velocity_ = 0.0;
133 double arm_zeroing_velocity_ = 0.0;
134
135 // The goals for the elevator and arm.
136 double elevator_goal_ = 0.0;
137 double arm_goal_ = 0.0;
138
139 State state_ = UNINITIALIZED;
140 State last_state_ = UNINITIALIZED;
141
142 control_loops::FridgeQueue::Position current_position_;
Ben Fredrickson6b5ba792015-01-25 17:14:40 -0800143};
144
145} // namespace control_loops
146} // namespace frc971
147
148#endif // FRC971_CONTROL_LOOPS_FRIDGE_H_
149