blob: a9fbd8c62573d405fe35072a04cf28151656eff4 [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
Stephan Pleinesf63bde82024-01-13 15:59:33 -080010namespace y2019::control_loops::superstructure {
Theo Bafrali3274a182019-02-17 20:01:38 -080011
Austin Schuh54629412019-04-14 19:53:59 -070012namespace chrono = ::std::chrono;
13
Theo Bafrali3274a182019-02-17 20:01:38 -080014constexpr double Vacuum::kPumpVoltage;
15constexpr double Vacuum::kPumpHasPieceVoltage;
16constexpr aos::monotonic_clock::duration Vacuum::kTimeAtHigherVoltage;
Tyler Chatow7db827f2019-02-24 00:10:13 -080017constexpr aos::monotonic_clock::duration Vacuum::kReleaseTime;
Theo Bafrali3274a182019-02-17 20:01:38 -080018
19void Vacuum::Iterate(const SuctionGoal *unsafe_goal, float suction_pressure,
Alex Perrycb7da4b2019-08-28 19:35:56 -070020 OutputT *output, bool *has_piece,
Theo Bafrali3274a182019-02-17 20:01:38 -080021 aos::EventLoop *event_loop) {
22 auto monotonic_now = event_loop->monotonic_now();
23 bool low_pump_voltage = false;
Theo Bafrali3274a182019-02-17 20:01:38 -080024
25 // implement a simple low-pass filter on the pressure
26 filtered_pressure_ = kSuctionAlpha * suction_pressure +
27 (1 - kSuctionAlpha) * filtered_pressure_;
28
Austin Schuh54629412019-04-14 19:53:59 -070029 const bool new_has_piece =
30 filtered_pressure_ < (filtered_had_piece_near_disabled_
31 ? kVacuumOffThreshold
32 : kVacuumOnThreshold);
Theo Bafrali3274a182019-02-17 20:01:38 -080033
Austin Schuh830fc862019-02-22 20:46:56 -080034 if (new_has_piece && !had_piece_) {
Theo Bafrali3274a182019-02-17 20:01:38 -080035 time_at_last_acquisition_ = monotonic_now;
36 }
Austin Schuh830fc862019-02-22 20:46:56 -080037 *has_piece =
38 monotonic_now > time_at_last_acquisition_ + kTimeAtHigherVoltage &&
39 new_has_piece;
Theo Bafrali3274a182019-02-17 20:01:38 -080040
Austin Schuh54629412019-04-14 19:53:59 -070041 if (!output && *has_piece) {
42 last_disable_has_piece_time_ = monotonic_now;
43 }
44
Tyler Chatow7db827f2019-02-24 00:10:13 -080045 // If we've had the piece for enough time, go to lower pump_voltage
Austin Schuh54629412019-04-14 19:53:59 -070046 low_pump_voltage = *has_piece && filtered_pressure_ < kVacuumOnThreshold;
Theo Bafrali3274a182019-02-17 20:01:38 -080047
48 if (unsafe_goal && output) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070049 const bool release = !unsafe_goal->grab_piece();
Tyler Chatow7db827f2019-02-24 00:10:13 -080050
51 if (release) {
52 last_release_time_ = monotonic_now;
Theo Bafrali3274a182019-02-17 20:01:38 -080053 }
54
55 // Once the vacuum evacuates, the pump speeds up because there is no
56 // resistance. So, we want to turn it down to save the pump from
57 // overheating.
58 output->pump_voltage =
Tyler Chatow7db827f2019-02-24 00:10:13 -080059 release ? 0 : (low_pump_voltage ? kPumpHasPieceVoltage : kPumpVoltage);
Theo Bafrali3274a182019-02-17 20:01:38 -080060
Alex Perrycb7da4b2019-08-28 19:35:56 -070061 if (unsafe_goal->grab_piece() && unsafe_goal->gamepiece_mode() == 0) {
Sabina Davisc6329342019-03-01 20:44:42 -080062 output->intake_suction_top = false;
63 output->intake_suction_bottom = true;
Philipp Schrader790cb542023-07-05 21:06:52 -070064 } else if (unsafe_goal->grab_piece() &&
65 unsafe_goal->gamepiece_mode() == 1) {
Sabina Davisc6329342019-03-01 20:44:42 -080066 output->intake_suction_top = true;
67 output->intake_suction_bottom = true;
68 } else {
69 output->intake_suction_top = false;
70 output->intake_suction_bottom = false;
71 }
Tyler Chatow7db827f2019-02-24 00:10:13 -080072
73 // If we intend to release, or recently released, set has_piece to false so
74 // that we give the part of the vacuum circuit with the pressure sensor time
75 // to equilibrate with the rest of the suction cup.
76 if (release || monotonic_now < last_release_time_ + kReleaseTime) {
77 *has_piece = false;
78 }
Theo Bafrali3274a182019-02-17 20:01:38 -080079 }
Austin Schuh830fc862019-02-22 20:46:56 -080080 had_piece_ = new_has_piece;
Austin Schuh54629412019-04-14 19:53:59 -070081
82 filtered_had_piece_near_disabled_ =
83 *has_piece &&
84 monotonic_now < last_disable_has_piece_time_ + chrono::milliseconds(250);
Theo Bafrali3274a182019-02-17 20:01:38 -080085}
86
Stephan Pleinesf63bde82024-01-13 15:59:33 -080087} // namespace y2019::control_loops::superstructure