blob: 30112e1b923e9995eb9c847b4b97ebf68984351f [file] [log] [blame]
joe93778a62014-02-15 13:22:14 -08001#ifndef FRC971_CONTROL_LOOPS_shooter_shooter_H_
2#define FRC971_CONTROL_LOOPS_shooter_shooter_H_
3
4#include <memory>
5
6#include "aos/common/control_loop/ControlLoop.h"
7#include "frc971/control_loops/state_feedback_loop.h"
8
9#include "frc971/control_loops/shooter/shooter_motor_plant.h"
10#include "frc971/control_loops/shooter/shooter.q.h"
11
12#include "frc971/control_loops/zeroed_joint.h"
13
14namespace frc971 {
15namespace control_loops {
16namespace testing {
17class ShooterTest_NoWindupPositive_Test;
18class ShooterTest_NoWindupNegative_Test;
19};
20
Ben Fredrickson1f633ef2014-02-16 05:35:45 +000021// Note: Everything in this file assumes that there is a 1 cycle delay between
22// power being requested and it showing up at the motor. It assumes that
23// X_hat(2, 1) is the voltage being applied as well. It will go unstable if
24// that isn't true.
25
26// This class implements the CapU function correctly given all the extra
27// information that we know about from the wrist motor.
28// It does not have any zeroing logic in it, only logic to deal with a delta U
29// controller.
30class ZeroedStateFeedbackLoop : public StateFeedbackLoop<3, 1, 1> {
31 public:
32 ZeroedStateFeedbackLoop(StateFeedbackLoop<3, 1, 1> loop)
33 : StateFeedbackLoop<3, 1, 1>(loop),
34 voltage_(0.0),
35 last_voltage_(0.0),
36 uncapped_voltage_(0.0),
37 offset_(0.0),
38 encoder_(0.0),
39 last_encoder_(0.0){}
40
41 const static int kZeroingMaxVoltage = 5;
42
43 // Caps U, but this time respects the state of the wrist as well.
44 virtual void CapU();
45
46 // Returns the accumulated voltage.
47 double voltage() const { return voltage_; }
48
49 // Returns the uncapped voltage.
50 double uncapped_voltage() const { return uncapped_voltage_; }
51
52 // Zeros the accumulator.
53 void ZeroPower() { voltage_ = 0.0; }
54
55 enum JointZeroingState {
56 // We don't know where the joint is at all.
57 UNKNOWN_POSITION,
58 // Ready for use during teleop.
59 CALIBRATED
60 };
61
62
63 void set_zeroing_state(JointZeroingState zeroing_state) {
64 zeroing_state_ = zeroing_state;
65 }
66
67
68 JointZeroingState zeroing_state() const { return zeroing_state_; }
69
70
71 // Sets the calibration offset given the absolute angle and the corrisponding
72 // encoder value.
73 void SetCalibration(double encoder_val, double known_position) {
74 offset_ = known_position - encoder_val;
75 }
76
77
78 bool SetCalibrationOnEdge(const constants::Values::Claw &claw_values,
79 JointZeroingState zeroing_state) {
80 double edge_encoder;
81 double known_position;
82 if (GetPositionOfEdge(claw_values, &edge_encoder, &known_position)) {
83 LOG(INFO, "Calibration edge.\n");
84 SetCalibration(edge_encoder, known_position);
85 set_zeroing_state(zeroing_state);
86 return true;
87 }
88 return false;
89 }
90
91
92 void SetPositionValues(double poistion) {
93 Eigen::Matrix<double, 1, 1> Y;
94 Y << position;
95 Correct(Y);
96 }
97
98
99 void SetGoalPositionVelocity(double desired_position,
100 double desired_velocity) {
101 // austin said something about which matrix to set, but I didn't under
102 // very much of it
103 //some_matrix = {desired_position, desired_velocity};
104 printf("%s:%d : seg fault?\n", __FILE__, __LINE__);
105 *(const char **)(NULL) = "seg fault";
106 }
107
108 double position() const { return X_hat(0, 0); }
109 double encoder() const { return encoder_; }
110 double last_encoder() const { return last_encoder_; }
111
112 // Returns true if an edge was detected in the last cycle and then sets the
113 // edge_position to the absolute position of the edge.
114 bool GetPositionOfEdge(const constants::Values::Shooter &shooter,
115 double *edge_encoder, double *known_position);
116
117#undef COUNT_SETTER_GETTER
118
119 private:
120 // The accumulated voltage to apply to the motor.
121 double voltage_;
122 double last_voltage_;
123 double uncapped_voltage_;
124 double offset_;
125
126 double previous_position_;
127
128 JointZeroingState zeroing_state_;
129 double encoder_;
130 double last_encoder_;
131};
132
133
joe93778a62014-02-15 13:22:14 -0800134class ShooterMotor
135 : public aos::control_loops::ControlLoop<control_loops::ShooterLoop> {
136 public:
137 explicit ShooterMotor(
joe3779d0c2014-02-15 19:41:22 -0800138 control_loops::ShooterLoop *my_shooter = &control_loops::shooter_queue_group);
joe93778a62014-02-15 13:22:14 -0800139
140 // True if the goal was moved to avoid goal windup.
141 bool capped_goal() const { return zeroed_joint_.capped_goal(); }
142
143 // True if the shooter is zeroing.
144 bool is_zeroing() const { return zeroed_joint_.is_zeroing(); }
145
146 // True if the shooter is zeroing.
147 bool is_moving_off() const { return zeroed_joint_.is_moving_off(); }
148
149 // True if the state machine is uninitialized.
150 bool is_uninitialized() const { return zeroed_joint_.is_uninitialized(); }
151
152 // True if the state machine is ready.
153 bool is_ready() const { return zeroed_joint_.is_ready(); }
154
Ben Fredrickson1f633ef2014-02-16 05:35:45 +0000155enum {
156 STATE_INITIALIZE,
157 STATE_REQUEST_LOAD,
158 STATE_LOAD_BACKTRACK,
159 STATE_LOAD,
160 STATE_LOADING_PROBLEM,
161 STATE_PREPARE_SHOT,
162 STATE_BRAKE_SET,
163 STATE_READY,
164 STATE_REQUEST_FIRE,
165 STATE_PREPARE_FIRE,
166 STATE_FIRE,
167 STATE_UNLOAD,
168 STATE_UNLOAD_MOVE,
169 STATE_READY_UNLOAD
170} State;
171
joe93778a62014-02-15 13:22:14 -0800172 protected:
173 virtual void RunIteration(
174 const ShooterLoop::Goal *goal,
175 const control_loops::ShooterLoop::Position *position,
176 ShooterLoop::Output *output,
177 ShooterLoop::Status *status);
178
179 private:
180 // Friend the test classes for acces to the internal state.
181 friend class testing::ShooterTest_NoWindupPositive_Test;
182 friend class testing::ShooterTest_NoWindupNegative_Test;
183
184 // The zeroed joint to use.
185 ZeroedJoint<1> zeroed_joint_;
Ben Fredrickson1f633ef2014-02-16 05:35:45 +0000186 ZeroedStateFeedbackLoop shooter_;
joe93778a62014-02-15 13:22:14 -0800187
188 DISALLOW_COPY_AND_ASSIGN(ShooterMotor);
189};
190
191} // namespace control_loops
192} // namespace frc971
193
194#endif // FRC971_CONTROL_LOOPS_shooter_shooter_H_