blob: 2cddf834a62d2bff1969ef14bd89d4e4f9ba1c89 [file] [log] [blame]
Sabina Davis8d20ca82018-02-19 13:17:45 -08001#include "y2018/control_loops/superstructure/superstructure.h"
2
3#include "aos/common/controls/control_loops.q.h"
4#include "aos/common/logging/logging.h"
5#include "frc971/control_loops/control_loops.q.h"
6#include "y2018/constants.h"
7#include "y2018/control_loops/superstructure/intake/intake.h"
8
9namespace y2018 {
10namespace control_loops {
11namespace superstructure {
12
13namespace {
14// The maximum voltage the intake roller will be allowed to use.
15constexpr double kMaxIntakeRollerVoltage = 12.0;
16} // namespace
17
18Superstructure::Superstructure(
19 control_loops::SuperstructureQueue *superstructure_queue)
20 : aos::controls::ControlLoop<control_loops::SuperstructureQueue>(
21 superstructure_queue),
22 intake_left_(constants::GetValues().left_intake.zeroing),
23 intake_right_(constants::GetValues().right_intake.zeroing) {}
24
25void Superstructure::RunIteration(
26 const control_loops::SuperstructureQueue::Goal *unsafe_goal,
27 const control_loops::SuperstructureQueue::Position *position,
28 control_loops::SuperstructureQueue::Output *output,
29 control_loops::SuperstructureQueue::Status *status) {
30 if (WasReset()) {
31 LOG(ERROR, "WPILib reset, restarting\n");
32 intake_left_.Reset();
33 intake_right_.Reset();
Austin Schuhcb091712018-02-21 20:01:55 -080034 arm_.Reset();
Sabina Davis8d20ca82018-02-19 13:17:45 -080035 }
36
37 intake_left_.Iterate(unsafe_goal != nullptr
38 ? &(unsafe_goal->intake.left_intake_angle)
39 : nullptr,
Sabina Daviscfb872f2018-02-25 16:28:20 -080040 &(position->left_intake),
41 output != nullptr ? &(output->left_intake) : nullptr,
Sabina Davis8d20ca82018-02-19 13:17:45 -080042 &(status->left_intake));
43
44 intake_right_.Iterate(unsafe_goal != nullptr
45 ? &(unsafe_goal->intake.right_intake_angle)
46 : nullptr,
Sabina Daviscfb872f2018-02-25 16:28:20 -080047 &(position->right_intake),
48 output != nullptr ? &(output->right_intake) : nullptr,
Sabina Davis8d20ca82018-02-19 13:17:45 -080049 &(status->right_intake));
50
Austin Schuhcb091712018-02-21 20:01:55 -080051 arm_.Iterate(
52 unsafe_goal != nullptr ? &(unsafe_goal->arm_goal_position) : nullptr,
53 &(position->arm),
54 output != nullptr ? &(output->voltage_proximal) : nullptr,
55 output != nullptr ? &(output->voltage_distal) : nullptr,
56 output != nullptr ? &(output->release_arm_brake) : nullptr,
57 &(status->arm));
58
59 status->estopped = status->left_intake.estopped ||
60 status->right_intake.estopped || status->arm.estopped;
61
62 status->zeroed = status->left_intake.zeroed && status->right_intake.zeroed &&
63 status->arm.zeroed;
Sabina Davis8d20ca82018-02-19 13:17:45 -080064
65 if (output && unsafe_goal) {
Austin Schuh17dd0892018-03-02 20:06:31 -080066 const double roller_voltage = ::std::max(
Sabina Davis8d20ca82018-02-19 13:17:45 -080067 -kMaxIntakeRollerVoltage, ::std::min(unsafe_goal->intake.roller_voltage,
68 kMaxIntakeRollerVoltage));
Austin Schuh17dd0892018-03-02 20:06:31 -080069 constexpr int kReverseTime = 15;
70 if (unsafe_goal->intake.roller_voltage < 0.0) {
Sabina Daviscfb872f2018-02-25 16:28:20 -080071 output->left_intake.voltage_rollers = roller_voltage;
72 output->right_intake.voltage_rollers = roller_voltage;
Austin Schuh17dd0892018-03-02 20:06:31 -080073 rotation_state_ = RotationState::NOT_ROTATING;
74 rotation_count_ = 0;
75 } else {
76 switch (rotation_state_) {
77 case RotationState::NOT_ROTATING:
Sabina Daviscfb872f2018-02-25 16:28:20 -080078 if (position->left_intake.beam_break) {
Austin Schuh17dd0892018-03-02 20:06:31 -080079 rotation_state_ = RotationState::ROTATING_RIGHT;
80 rotation_count_ = kReverseTime;
81 break;
Sabina Daviscfb872f2018-02-25 16:28:20 -080082 } else if (position->right_intake.beam_break) {
Austin Schuh17dd0892018-03-02 20:06:31 -080083 rotation_state_ = RotationState::ROTATING_LEFT;
84 rotation_count_ = kReverseTime;
85 break;
86 } else {
87 break;
88 }
89 case RotationState::ROTATING_LEFT:
Sabina Daviscfb872f2018-02-25 16:28:20 -080090 if (position->right_intake.beam_break) {
Austin Schuh17dd0892018-03-02 20:06:31 -080091 rotation_count_ = kReverseTime;
92 } else {
93 --rotation_count_;
94 }
95 if (rotation_count_ == 0) {
96 rotation_state_ = RotationState::NOT_ROTATING;
97 }
98 break;
99 case RotationState::ROTATING_RIGHT:
Sabina Daviscfb872f2018-02-25 16:28:20 -0800100 if (position->left_intake.beam_break) {
Austin Schuh17dd0892018-03-02 20:06:31 -0800101 rotation_count_ = kReverseTime;
102 } else {
103 --rotation_count_;
104 }
105 if (rotation_count_ == 0) {
106 rotation_state_ = RotationState::NOT_ROTATING;
107 }
108 break;
109 }
110
111 switch (rotation_state_) {
112 case RotationState::NOT_ROTATING:
Sabina Daviscfb872f2018-02-25 16:28:20 -0800113 output->left_intake.voltage_rollers = roller_voltage;
114 output->right_intake.voltage_rollers = roller_voltage;
Austin Schuh17dd0892018-03-02 20:06:31 -0800115 break;
116 case RotationState::ROTATING_LEFT:
Sabina Daviscfb872f2018-02-25 16:28:20 -0800117 output->left_intake.voltage_rollers = roller_voltage;
118 output->right_intake.voltage_rollers = -roller_voltage;
Austin Schuh17dd0892018-03-02 20:06:31 -0800119 break;
120 case RotationState::ROTATING_RIGHT:
Sabina Daviscfb872f2018-02-25 16:28:20 -0800121 output->left_intake.voltage_rollers = -roller_voltage;
122 output->right_intake.voltage_rollers = roller_voltage;
Austin Schuh17dd0892018-03-02 20:06:31 -0800123 break;
124 }
125 }
Sabina Davis8d20ca82018-02-19 13:17:45 -0800126 }
127}
128
129} // namespace superstructure
130} // namespace control_loops
131} // namespace y2018