blob: fda123eb39d7dc1e37413d50b8531851698a2cbd [file] [log] [blame]
Theo Bafrali3274a182019-02-17 20:01:38 -08001#include "y2019/control_loops/superstructure/vacuum.h"
2
Austin Schuh54629412019-04-14 19:53:59 -07003#include <chrono>
4
Alex Perrycb7da4b2019-08-28 19:35:56 -07005#include "frc971/control_loops/control_loops_generated.h"
6#include "frc971/control_loops/profiled_subsystem_generated.h"
7#include "y2019/control_loops/superstructure/superstructure_goal_generated.h"
8#include "y2019/control_loops/superstructure/superstructure_output_generated.h"
Austin Schuh54629412019-04-14 19:53:59 -07009
Theo Bafrali3274a182019-02-17 20:01:38 -080010namespace y2019 {
11namespace control_loops {
12namespace superstructure {
13
Austin Schuh54629412019-04-14 19:53:59 -070014namespace chrono = ::std::chrono;
15
Theo Bafrali3274a182019-02-17 20:01:38 -080016constexpr double Vacuum::kPumpVoltage;
17constexpr double Vacuum::kPumpHasPieceVoltage;
18constexpr aos::monotonic_clock::duration Vacuum::kTimeAtHigherVoltage;
Tyler Chatow7db827f2019-02-24 00:10:13 -080019constexpr aos::monotonic_clock::duration Vacuum::kReleaseTime;
Theo Bafrali3274a182019-02-17 20:01:38 -080020
21void Vacuum::Iterate(const SuctionGoal *unsafe_goal, float suction_pressure,
Alex Perrycb7da4b2019-08-28 19:35:56 -070022 OutputT *output, bool *has_piece,
Theo Bafrali3274a182019-02-17 20:01:38 -080023 aos::EventLoop *event_loop) {
24 auto monotonic_now = event_loop->monotonic_now();
25 bool low_pump_voltage = false;
Theo Bafrali3274a182019-02-17 20:01:38 -080026
27 // implement a simple low-pass filter on the pressure
28 filtered_pressure_ = kSuctionAlpha * suction_pressure +
29 (1 - kSuctionAlpha) * filtered_pressure_;
30
Austin Schuh54629412019-04-14 19:53:59 -070031 const bool new_has_piece =
32 filtered_pressure_ < (filtered_had_piece_near_disabled_
33 ? kVacuumOffThreshold
34 : kVacuumOnThreshold);
Theo Bafrali3274a182019-02-17 20:01:38 -080035
Austin Schuh830fc862019-02-22 20:46:56 -080036 if (new_has_piece && !had_piece_) {
Theo Bafrali3274a182019-02-17 20:01:38 -080037 time_at_last_acquisition_ = monotonic_now;
38 }
Austin Schuh830fc862019-02-22 20:46:56 -080039 *has_piece =
40 monotonic_now > time_at_last_acquisition_ + kTimeAtHigherVoltage &&
41 new_has_piece;
Theo Bafrali3274a182019-02-17 20:01:38 -080042
Austin Schuh54629412019-04-14 19:53:59 -070043 if (!output && *has_piece) {
44 last_disable_has_piece_time_ = monotonic_now;
45 }
46
Tyler Chatow7db827f2019-02-24 00:10:13 -080047 // If we've had the piece for enough time, go to lower pump_voltage
Austin Schuh54629412019-04-14 19:53:59 -070048 low_pump_voltage = *has_piece && filtered_pressure_ < kVacuumOnThreshold;
Theo Bafrali3274a182019-02-17 20:01:38 -080049
50 if (unsafe_goal && output) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070051 const bool release = !unsafe_goal->grab_piece();
Tyler Chatow7db827f2019-02-24 00:10:13 -080052
53 if (release) {
54 last_release_time_ = monotonic_now;
Theo Bafrali3274a182019-02-17 20:01:38 -080055 }
56
57 // Once the vacuum evacuates, the pump speeds up because there is no
58 // resistance. So, we want to turn it down to save the pump from
59 // overheating.
60 output->pump_voltage =
Tyler Chatow7db827f2019-02-24 00:10:13 -080061 release ? 0 : (low_pump_voltage ? kPumpHasPieceVoltage : kPumpVoltage);
Theo Bafrali3274a182019-02-17 20:01:38 -080062
Alex Perrycb7da4b2019-08-28 19:35:56 -070063 if (unsafe_goal->grab_piece() && unsafe_goal->gamepiece_mode() == 0) {
Sabina Davisc6329342019-03-01 20:44:42 -080064 output->intake_suction_top = false;
65 output->intake_suction_bottom = true;
Philipp Schrader790cb542023-07-05 21:06:52 -070066 } else if (unsafe_goal->grab_piece() &&
67 unsafe_goal->gamepiece_mode() == 1) {
Sabina Davisc6329342019-03-01 20:44:42 -080068 output->intake_suction_top = true;
69 output->intake_suction_bottom = true;
70 } else {
71 output->intake_suction_top = false;
72 output->intake_suction_bottom = false;
73 }
Tyler Chatow7db827f2019-02-24 00:10:13 -080074
75 // If we intend to release, or recently released, set has_piece to false so
76 // that we give the part of the vacuum circuit with the pressure sensor time
77 // to equilibrate with the rest of the suction cup.
78 if (release || monotonic_now < last_release_time_ + kReleaseTime) {
79 *has_piece = false;
80 }
Theo Bafrali3274a182019-02-17 20:01:38 -080081 }
Austin Schuh830fc862019-02-22 20:46:56 -080082 had_piece_ = new_has_piece;
Austin Schuh54629412019-04-14 19:53:59 -070083
84 filtered_had_piece_near_disabled_ =
85 *has_piece &&
86 monotonic_now < last_disable_has_piece_time_ + chrono::milliseconds(250);
Theo Bafrali3274a182019-02-17 20:01:38 -080087}
88
89} // namespace superstructure
90} // namespace control_loops
91} // namespace y2019