blob: 9b64282b54bcd79c8418cddefe4dd7bd0c1276e8 [file] [log] [blame]
Austin Schuhd78ab542013-03-01 22:22:19 -08001#ifndef FRC971_CONTROL_LOOPS_WRIST_H_
2#define FRC971_CONTROL_LOOPS_WRIST_H_
3
4#include <memory>
5#include <deque>
6
7#include "aos/common/control_loop/ControlLoop.h"
8#include "aos/common/time.h"
9#include "frc971/control_loops/state_feedback_loop.h"
10#include "frc971/control_loops/index_motor.q.h"
11#include "frc971/control_loops/index_motor_plant.h"
12
13namespace frc971 {
14namespace control_loops {
15
16class IndexMotor
17 : public aos::control_loops::ControlLoop<control_loops::IndexLoop> {
18 public:
19 explicit IndexMotor(
Austin Schuhf8c52252013-03-03 02:25:49 -080020 control_loops::IndexLoop *my_index = &control_loops::index_loop);
21
22 static const double kTransferStartPosition;
23 static const double kIndexStartPosition;
24 // The distance from where the disc first grabs on the indexer to where it
25 // just bairly clears the loader.
26 static const double kIndexFreeLength;
27 // The distance to where the disc just starts to enter the loader.
28 static const double kLoaderFreeStopPosition;
29
30 // Distance that the grabber pulls the disc in by.
31 static const double kGrabberLength;
32 // Distance to where the grabber takes over.
33 static const double kGrabberStartPosition;
34
35 // The distance to where the disc hits the back of the loader and is ready to
36 // lift.
37 static const double kReadyToLiftPosition;
38
39 static const double kGrabberMovementVelocity;
40 // TODO(aschuh): This depends on the shooter angle...
41 // Distance to where the shooter is up and ready to shoot.
42 static const double kLifterStopPosition;
43 static const double kLifterMovementVelocity;
44
45 // Distance to where the disc has been launched.
46 // TODO(aschuh): This depends on the shooter angle...
47 static const double kEjectorStopPosition;
48 static const double kEjectorMovementVelocity;
49
50 // Start and stop position of the bottom disc detect sensor in meters.
51 static const double kBottomDiscDetectStart;
52 static const double kBottomDiscDetectStop;
53
54 static const double kTopDiscDetectStart;
55 static const double kTopDiscDetectStop;
Austin Schuhd78ab542013-03-01 22:22:19 -080056
57 // Converts the angle of the indexer to the angle of the disc.
58 static double ConvertIndexToDiscAngle(const double angle);
59 // Converts the angle of the indexer to the position that the center of the
60 // disc has traveled.
61 static double ConvertIndexToDiscPosition(const double angle);
62
Austin Schuhf8c52252013-03-03 02:25:49 -080063 // Converts the angle of the transfer roller to the position that the center
64 // of the disc has traveled.
65 static double ConvertTransferToDiscPosition(const double angle);
66
67 // Converts the distance around the indexer to the position of
68 // the index roller.
69 static double ConvertDiscPositionToIndex(const double position);
Austin Schuhd78ab542013-03-01 22:22:19 -080070 // Converts the angle around the indexer to the position of the index roller.
71 static double ConvertDiscAngleToIndex(const double angle);
72 // Converts the angle around the indexer to the position of the disc in the
73 // indexer.
74 static double ConvertDiscAngleToDiscPosition(const double angle);
Austin Schuhf8c52252013-03-03 02:25:49 -080075 // Converts the distance around the indexer to the angle of the disc around
76 // the indexer.
77 static double ConvertDiscPositionToDiscAngle(const double position);
Austin Schuhd78ab542013-03-01 22:22:19 -080078
79 // Disc radius in meters.
Austin Schuhf8c52252013-03-03 02:25:49 -080080 static const double kDiscRadius;
Austin Schuhd78ab542013-03-01 22:22:19 -080081 // Roller radius in meters.
Austin Schuhf8c52252013-03-03 02:25:49 -080082 static const double kRollerRadius;
83 // Transfer roller radius in meters.
84 static const double kTransferRollerRadius;
Austin Schuhd78ab542013-03-01 22:22:19 -080085
Austin Schuhf8c52252013-03-03 02:25:49 -080086 // Time that it takes to grab the disc in cycles.
87 static const int kGrabbingDelay;
88 // Time that it takes to lift the loader in cycles.
89 static const int kLiftingDelay;
90 // Time that it takes to shoot the disc in cycles.
91 static const int kShootingDelay;
92 // Time that it takes to lower the loader in cycles.
93 static const int kLoweringDelay;
94
95 // Object representing a Frisbee tracked by the indexer.
Austin Schuhd78ab542013-03-01 22:22:19 -080096 class Frisbee {
97 public:
98 Frisbee()
99 : bottom_posedge_time_(0, 0),
Austin Schuhf8c52252013-03-03 02:25:49 -0800100 bottom_negedge_time_(0, 0) {
Austin Schuhd78ab542013-03-01 22:22:19 -0800101 Reset();
102 }
103
Austin Schuhf8c52252013-03-03 02:25:49 -0800104 // Resets a Frisbee so it can be reused.
Austin Schuhd78ab542013-03-01 22:22:19 -0800105 void Reset() {
106 bottom_posedge_time_ = ::aos::time::Time(0, 0);
107 bottom_negedge_time_ = ::aos::time::Time(0, 0);
Austin Schuhd78ab542013-03-01 22:22:19 -0800108 has_been_indexed_ = false;
109 index_start_position_ = 0.0;
110 }
111
Austin Schuhf8c52252013-03-03 02:25:49 -0800112 // Returns true if the position is valid.
113 bool has_position() const {
114 return has_been_indexed_;
115 }
116
117 // Returns the most up to date and accurate position that we have for the
118 // disc. This is the indexer position that the disc grabbed at.
119 double position() const {
120 return index_start_position_;
121 }
122
123 // Posedge and negedge disc times.
Austin Schuhd78ab542013-03-01 22:22:19 -0800124 ::aos::time::Time bottom_posedge_time_;
125 ::aos::time::Time bottom_negedge_time_;
Austin Schuhf8c52252013-03-03 02:25:49 -0800126
127 // True if the disc has a valid index position.
Austin Schuhd78ab542013-03-01 22:22:19 -0800128 bool has_been_indexed_;
Austin Schuhf8c52252013-03-03 02:25:49 -0800129 // Location of the index when the disc first contacted it.
Austin Schuhd78ab542013-03-01 22:22:19 -0800130 double index_start_position_;
131 };
132
133 protected:
134 virtual void RunIteration(
135 const control_loops::IndexLoop::Goal *goal,
136 const control_loops::IndexLoop::Position *position,
137 control_loops::IndexLoop::Output *output,
138 control_loops::IndexLoop::Status *status);
139
140 private:
Austin Schuhf8c52252013-03-03 02:25:49 -0800141 // Sets disc_position to the minimum or maximum disc position.
142 // Returns true if there were discs, and false if there weren't.
143 // On false, disc_position is left unmodified.
144 bool MinDiscPosition(double *disc_position);
145 bool MaxDiscPosition(double *disc_position);
Austin Schuhd78ab542013-03-01 22:22:19 -0800146
147 // The state feedback control loop to talk to for the index.
148 ::std::unique_ptr<StateFeedbackLoop<2, 1, 1>> wrist_loop_;
149
Austin Schuhd78ab542013-03-01 22:22:19 -0800150 // Count of the number of discs that we have collected.
151 uint32_t hopper_disc_count_;
152 uint32_t total_disc_count_;
153
Austin Schuhf8c52252013-03-03 02:25:49 -0800154 enum class Goal {
Austin Schuhd78ab542013-03-01 22:22:19 -0800155 // Hold position, in a low power state.
156 HOLD = 0,
157 // Get ready to load discs by shifting the discs down.
158 READY_LOWER = 1,
159 // Ready the discs, spin up the transfer roller, and accept discs.
160 INTAKE = 2,
161 // Get ready to shoot, and place a disc in the loader.
162 READY_SHOOTER = 3,
163 // Shoot at will.
164 SHOOT = 4
165 };
166
Austin Schuhf8c52252013-03-03 02:25:49 -0800167 // These two enums command and track the loader loading discs into the
168 // shooter.
169 enum class LoaderState {
170 // Open and down, ready to accept a disc.
171 READY,
172 // Closing the grabber.
173 GRABBING,
174 // Grabber closed.
175 GRABBED,
176 // Lifting the disc.
177 LIFTING,
178 // Disc lifted.
179 LIFTED,
180 // Ejecting the disc into the shooter.
181 SHOOTING,
182 // The disc has been shot.
183 SHOOT,
184 // Lowering the loader back down.
185 LOWERING,
186 // The indexer is lowered.
187 LOWERED
188 };
189
190 // TODO(aschuh): If we are grabbed and asked to be ready, now what?
191 // LOG ?
192 enum class LoaderGoal {
193 // Get the loader ready to accept another disc.
194 READY,
195 // Grab a disc now.
196 GRAB,
197 // Lift it up, shoot, and reset.
198 // Waits to shoot until the shooter is stable.
199 // Resets the goal to READY once one disc has been shot.
200 SHOOT_AND_RESET
201 };
202
Austin Schuhd78ab542013-03-01 22:22:19 -0800203 // The current goal
204 Goal safe_goal_;
205
Austin Schuhf8c52252013-03-03 02:25:49 -0800206 // Loader goal, state, and counter.
207 LoaderGoal loader_goal_;
208 LoaderState loader_state_;
209 int loader_countdown_;
210
Austin Schuhd78ab542013-03-01 22:22:19 -0800211 // Current state of the pistons.
212 bool loader_up_;
213 bool disc_clamped_;
214 bool disc_ejected_;
215
Austin Schuhd78ab542013-03-01 22:22:19 -0800216 // The frisbee that is flying through the transfer rollers.
217 Frisbee transfer_frisbee_;
218
Austin Schuhf8c52252013-03-03 02:25:49 -0800219 // Bottom disc detect from the last valid packet for detecting edges.
Austin Schuhd78ab542013-03-01 22:22:19 -0800220 bool last_bottom_disc_detect_;
221
222 // Frisbees are in order such that the newest frisbee is on the front.
223 ::std::deque<Frisbee> frisbees_;
224 // std::array ?
225
226 DISALLOW_COPY_AND_ASSIGN(IndexMotor);
227};
228
229} // namespace control_loops
230} // namespace frc971
231
232#endif // FRC971_CONTROL_LOOPS_WRIST_H_