blob: a5b4da679f76046385a3dc45d779d6329dfbbdc2 [file] [log] [blame]
Adam Snaider18f44172016-10-22 15:30:21 -07001#ifndef Y2016_BOT3_CONTROL_LOOPS_INTAKE_INTAKE_H_
2#define Y2016_BOT3_CONTROL_LOOPS_INTAKE_INTAKE_H_
3
4#include <memory>
5
6#include "aos/common/controls/control_loop.h"
7#include "aos/common/util/trapezoid_profile.h"
8#include "frc971/control_loops/state_feedback_loop.h"
9
10#include "frc971/zeroing/zeroing.h"
11#include "y2016_bot3/control_loops/intake/intake.q.h"
12#include "y2016_bot3/control_loops/intake/intake_controls.h"
13
14namespace y2016_bot3 {
15namespace constants {
16static const int kZeroingSampleSize = 200;
17
18// Ratios for our subsystems.
19// TODO(constants): Update these.
20static constexpr double kIntakeEncoderRatio = 18.0 / 72.0 * 15.0 / 48.0;
21
22static constexpr double kIntakePotRatio = 15.0 / 48.0;
23
24// Difference in radians between index pulses.
25static constexpr double kIntakeEncoderIndexDifference =
26 2.0 * M_PI * kIntakeEncoderRatio;
27
28// Subsystem motion ranges, in whatever units that their respective queues say
29// the use.
30// TODO(constants): Update these.
31static constexpr ::frc971::constants::Range kIntakeRange{// Lower hard stop
32 -0.5,
33 // Upper hard stop
34 2.90,
35 // Lower soft stop
36 -0.300,
37 // Uppper soft stop
38 2.725};
39
40struct IntakeZero {
41 double pot_offset = 0.0;
42 ::frc971::constants::ZeroingConstants zeroing{
43 kZeroingSampleSize, kIntakeEncoderIndexDifference, 0.0, 0.3};
44};
45} // namespace constants
46namespace control_loops {
47namespace intake {
48namespace testing {
49class IntakeTest_RespectsRange_Test;
50class IntakeTest_DisabledGoalTest_Test;
51class IntakeTest_IntakeZeroingErrorTest_Test;
52class IntakeTest_UpperHardstopStartup_Test;
53class IntakeTest_DisabledWhileZeroingHigh_Test;
54class IntakeTest_DisabledWhileZeroingLow_Test;
55}
56
Adam Snaidera3271fe2016-10-26 21:03:38 -070057// TODO(Adam): Implement this class and delete it from here.
Adam Snaider18f44172016-10-22 15:30:21 -070058class LimitChecker {
59 public:
60 LimitChecker(IntakeArm *intake) : intake_(intake) {}
61 void UpdateGoal(double intake_angle_goal);
62 private:
63 IntakeArm *intake_;
64};
65
66class Intake : public ::aos::controls::ControlLoop<control_loops::IntakeQueue> {
67 public:
68 explicit Intake(
69 control_loops::IntakeQueue *my_intake = &control_loops::intake_queue);
70
71 static constexpr double kZeroingVoltage = 6.0;
72 static constexpr double kOperatingVoltage = 12.0;
73
74 // This is the large scale movement tolerance.
75 static constexpr double kLooseTolerance = 0.05;
76
77 // This is the small scale movement tolerance.
78 static constexpr double kTightTolerance = 0.03;
79
80 static constexpr double kIntakeUpAngle = M_PI / 2;
81
82 static constexpr double kIntakeDownAngle = 0.0;
83
84 static constexpr double kIntakeMiddleAngle =
85 (kIntakeUpAngle + kIntakeDownAngle) / 2;
86
87 enum State {
88 // Wait for all the filters to be ready before starting the initialization
89 // process.
90 UNINITIALIZED = 0,
91
92 // We now are ready to decide how to zero. Decide what to do once we are
93 // enabled.
94 DISABLED_INITIALIZED = 1,
95
96 ZERO_LOWER_INTAKE = 2,
97
98 ZERO_LIFT_INTAKE = 3,
99 // Run, but limit power to zeroing voltages.
100 SLOW_RUNNING = 12,
101 // Run with full power.
102 RUNNING = 13,
103 // Internal error caused the intake to abort.
104 ESTOP = 16,
105 };
106
107 bool IsRunning() const {
108 return (state_ == SLOW_RUNNING || state_ == RUNNING);
109 }
110
111 State state() const { return state_; }
112
Adam Snaider18f44172016-10-22 15:30:21 -0700113 protected:
114 void RunIteration(const control_loops::IntakeQueue::Goal *unsafe_goal,
115 const control_loops::IntakeQueue::Position *position,
116 control_loops::IntakeQueue::Output *output,
117 control_loops::IntakeQueue::Status *status) override;
118
119 private:
120 friend class testing::IntakeTest_DisabledGoalTest_Test;
121 friend class testing::IntakeTest_IntakeZeroingErrorTest_Test;
122 friend class testing::IntakeTest_RespectsRange_Test;
123 friend class testing::IntakeTest_UpperHardstopStartup_Test;
124 friend class testing::IntakeTest_DisabledWhileZeroingHigh_Test;
125 friend class testing::IntakeTest_DisabledWhileZeroingLow_Test;
126 IntakeArm intake_;
127
128 State state_ = UNINITIALIZED;
129 State last_state_ = UNINITIALIZED;
130
131 float last_intake_angle_ = 0.0;
132 LimitChecker limit_checker_;
133 // Returns true if the profile has finished, and the joint is within the
134 // specified tolerance.
135 bool IsIntakeNear(double tolerance);
136
137 DISALLOW_COPY_AND_ASSIGN(Intake);
138};
139
140
141} // namespace intake
142} // namespace control_loops
143} // namespace y2016_bot3
144
145#endif // Y2016_BOT3_CONTROL_LOOPS_SUPERSTRUCTURE_SUPERSTRUCTURE_H_