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