blob: 5ee6ed0e71ad8729802b2e5576a99bc2d31e8ffd [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"
9#include "frc971/control_loops/fridge/arm_motor_plant.h"
10#include "frc971/control_loops/fridge/elevator_motor_plant.h"
Austin Schuh703b8d42015-02-01 14:56:34 -080011#include "frc971/zeroing/zeroing.h"
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080012
13namespace frc971 {
14namespace control_loops {
15
Austin Schuh703b8d42015-02-01 14:56:34 -080016class CappedStateFeedbackLoop : public StateFeedbackLoop<4, 2, 2> {
17 public:
18 CappedStateFeedbackLoop(StateFeedbackLoop<4, 2, 2> &&loop)
19 : StateFeedbackLoop<4, 2, 2>(::std::move(loop)), max_voltage_(12.0) {}
20
21 void set_max_voltage(double max_voltage) {
22 max_voltage_ = ::std::max(-12.0, ::std::min(12.0, max_voltage));
23 }
24
25 void CapU() override;
26
27 // Returns the amount to change the position goals (average and difference) in
28 // order to no longer saturate the controller.
29 Eigen::Matrix<double, 2, 1> UnsaturateOutputGoalChange();
30
31 private:
32 double max_voltage_;
33};
34
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080035class Fridge
36 : public aos::controls::ControlLoop<control_loops::FridgeQueue> {
37 public:
38 explicit Fridge(
39 control_loops::FridgeQueue *fridge_queue = &control_loops::fridge_queue);
40
41 // Control loop time step.
42 // Please figure out how to set dt from a common location
43 // Please decide the correct value
44 // Please use dt in your implementation so we can change looptimnig
45 // and be consistent with legacy
46 // And Brian please approve my code review as people are wait on
47 // these files to exist and they will be rewritten anyway
48 //static constexpr double dt;
49
50 protected:
Austin Schuh703b8d42015-02-01 14:56:34 -080051 void RunIteration(const control_loops::FridgeQueue::Goal *goal,
52 const control_loops::FridgeQueue::Position *position,
53 control_loops::FridgeQueue::Output *output,
54 control_loops::FridgeQueue::Status *status) override;
Ben Fredrickson6b5ba792015-01-25 17:14:40 -080055
56 private:
Austin Schuh703b8d42015-02-01 14:56:34 -080057 // Sets state_ to the correct state given the current state of the zeroing
58 // estimators.
59 void UpdateZeroingState();
60
61 void SetElevatorOffset(double left_offset, double right_offset);
62 void SetArmOffset(double left_offset, double right_offset);
63
64 // Getters for the current elevator positions.
65 double left_elevator();
66 double right_elevator();
67 double elevator();
68
69 // Getters for the current arm positions.
70 double left_arm();
71 double right_arm();
72 double arm();
73
74 // Our best guess at the current position of the elevator.
75 double estimated_left_elevator();
76 double estimated_right_elevator();
77 double estimated_elevator();
78
79 // Our best guess at the current position of the arm.
80 double estimated_left_arm();
81 double estimated_right_arm();
82 double estimated_arm();
83
84 // Returns the current zeroing velocity for either subsystem.
85 // If the subsystem is too far away from the center, these will switch
86 // directions.
87 double elevator_zeroing_velocity();
88 double arm_zeroing_velocity();
89
90 // Corrects the Observer with the current position.
91 void Correct();
92
93 enum State {
94 // Waiting to receive data before doing anything.
95 UNINITIALIZED = 0,
96 // Estimating the starting location.
97 INITIALIZING = 1,
98 // Moving the elevator to find an index pulse.
99 ZEROING_ELEVATOR = 2,
100 // Moving the arm to find an index pulse.
101 ZEROING_ARM = 3,
102 // All good!
103 RUNNING = 4,
104 // Internal error caused the fridge to abort.
105 ESTOP = 5,
106 };
107
Ben Fredrickson6b5ba792015-01-25 17:14:40 -0800108 // The state feedback control loop or loops to talk to.
Austin Schuh703b8d42015-02-01 14:56:34 -0800109 ::std::unique_ptr<CappedStateFeedbackLoop> arm_loop_;
110 ::std::unique_ptr<CappedStateFeedbackLoop> elevator_loop_;
111
112 zeroing::ZeroingEstimator left_arm_estimator_;
113 zeroing::ZeroingEstimator right_arm_estimator_;
114 zeroing::ZeroingEstimator left_elevator_estimator_;
115 zeroing::ZeroingEstimator right_elevator_estimator_;
116
117 // Offsets from the encoder position to the absolute position. Add these to
118 // the encoder position to get the absolute position.
119 double left_elevator_offset_ = 0.0;
120 double right_elevator_offset_ = 0.0;
121 double left_arm_offset_ = 0.0;
122 double right_arm_offset_ = 0.0;
123
124 // Current velocity to move at while zeroing.
125 double elevator_zeroing_velocity_ = 0.0;
126 double arm_zeroing_velocity_ = 0.0;
127
128 // The goals for the elevator and arm.
129 double elevator_goal_ = 0.0;
130 double arm_goal_ = 0.0;
131
132 State state_ = UNINITIALIZED;
133 State last_state_ = UNINITIALIZED;
134
135 control_loops::FridgeQueue::Position current_position_;
136 static constexpr double dt = 0.005;
Ben Fredrickson6b5ba792015-01-25 17:14:40 -0800137};
138
139} // namespace control_loops
140} // namespace frc971
141
142#endif // FRC971_CONTROL_LOOPS_FRIDGE_H_
143