blob: 7c259648d64c6e5d7871d120e915d976e756e112 [file] [log] [blame]
Milind Upadhyay225156b2022-02-25 22:42:12 -08001#ifndef Y2022_CONTROL_LOOPS_SUPERSTRUCTURE_COLLISION_AVOIDENCE_H_
2#define Y2022_CONTROL_LOOPS_SUPERSTRUCTURE_COLLISION_AVOIDENCE_H_
3
4#include <cmath>
5
6#include "frc971/control_loops/control_loops_generated.h"
7#include "frc971/control_loops/profiled_subsystem_generated.h"
8#include "y2022/control_loops/superstructure/superstructure_goal_generated.h"
9#include "y2022/control_loops/superstructure/superstructure_status_generated.h"
10
11namespace y2022 {
12namespace control_loops {
13namespace superstructure {
14
15// Returns the wrapped angle as well as number of wraps (positive or negative).
16// The returned angle will be inside [0.0, 2 * M_PI).
17std::pair<double, int> WrapTurretAngle(double turret_angle);
18
19// Returns the absolute angle given the wrapped angle and number of wraps.
20double UnwrapTurretAngle(double wrapped, int wraps);
21
22// 1. Prevent the turret from moving if the intake is up
23// 2. If the intake is up, drop it so it is not in the way
24// 3. Move the turret to the desired position.
25// 4. When the turret moves away, if the intake is down, move it back up.
26class CollisionAvoidance {
27 public:
28 struct Status {
29 double intake_front_position;
30 double intake_back_position;
31 double turret_position;
32
33 bool operator==(const Status &s) const {
34 return (intake_front_position == s.intake_front_position &&
35 intake_back_position == s.intake_back_position &&
36 turret_position == s.turret_position);
37 }
38 bool operator!=(const Status &s) const { return !(*this == s); }
39 };
40
41 // TODO(henry): put actual constants here.
42
43 // Reference angles between which the turret will be careful
44 static constexpr double kCollisionZoneTurret = M_PI * 5.0 / 18.0;
45
46 // For the turret, 0 rad is pointing straight forwards
47 static constexpr double kMinCollisionZoneFrontTurret =
48 M_PI - kCollisionZoneTurret;
49 static constexpr double kMaxCollisionZoneFrontTurret =
50 M_PI + kCollisionZoneTurret;
51
52 static constexpr double kMinCollisionZoneBackTurret = -kCollisionZoneTurret;
53 static constexpr double kMaxCollisionZoneBackTurret = kCollisionZoneTurret;
54
55 // Minimum (highest in reality) of the intake, in order to avoid collisions
56 static constexpr double kCollisionZoneIntake = M_PI / 6.0;
57
58 // Tolerance for the turret.
59 static constexpr double kEpsTurret = 0.05;
60 // Tolerance for the intake.
61 static constexpr double kEpsIntake = 0.05;
62
63 CollisionAvoidance();
64
65 // Reports if the superstructure is collided.
66 bool IsCollided(const Status &status);
67 // Checks if there is a collision on either intake.
68 bool TurretCollided(double intake_position, double turret_position,
69 double min_turret_collision_position,
70 double max_turret_collision_position);
71 // Checks and alters goals to make sure they're safe.
Ravago Jones5da06352022-03-04 20:26:24 -080072 void UpdateGoal(
73 const Status &status,
74 const frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal
75 *unsafe_turret_goal);
Milind Upadhyay225156b2022-02-25 22:42:12 -080076 // Limits if goal is in collision spots.
77 void CalculateAvoidance(bool intake_front, double intake_position,
78 double turret_goal, double mix_turret_collision_goal,
79 double max_turret_collision_goal,
80 double turret_position);
81
82 // Returns the goals to give to the respective control loops in
83 // superstructure.
84 double min_turret_goal() const { return min_turret_goal_; }
85 double max_turret_goal() const { return max_turret_goal_; }
86 double min_intake_front_goal() const { return min_intake_front_goal_; }
87 double max_intake_front_goal() const { return max_intake_front_goal_; }
88 double min_intake_back_goal() const { return min_intake_back_goal_; }
89 double max_intake_back_goal() const { return max_intake_back_goal_; }
90
91 void update_max_turret_goal(double max_turret_goal) {
92 max_turret_goal_ = ::std::min(max_turret_goal, max_turret_goal_);
93 }
94 void update_min_turret_goal(double min_turret_goal) {
95 min_turret_goal_ = ::std::max(min_turret_goal, min_turret_goal_);
96 }
97 void update_max_intake_front_goal(double max_intake_front_goal) {
98 max_intake_front_goal_ =
99 ::std::min(max_intake_front_goal, max_intake_front_goal_);
100 }
101 void update_min_intake_front_goal(double min_intake_front_goal) {
102 min_intake_front_goal_ =
103 ::std::max(min_intake_front_goal, min_intake_front_goal_);
104 }
105 void update_max_intake_back_goal(double max_intake_back_goal) {
106 max_intake_back_goal_ =
107 ::std::min(max_intake_back_goal, max_intake_back_goal_);
108 }
109 void update_min_intake_back_goal(double min_intake_back_goal) {
110 min_intake_back_goal_ =
111 ::std::max(min_intake_back_goal, min_intake_back_goal_);
112 }
113
114 private:
115 void clear_min_intake_front_goal() {
116 min_intake_front_goal_ = -::std::numeric_limits<double>::infinity();
117 }
118 void clear_max_intake_front_goal() {
119 max_intake_front_goal_ = ::std::numeric_limits<double>::infinity();
120 }
121 void clear_min_intake_back_goal() {
122 min_intake_back_goal_ = -::std::numeric_limits<double>::infinity();
123 }
124 void clear_max_intake_back_goal() {
125 max_intake_back_goal_ = ::std::numeric_limits<double>::infinity();
126 }
127 void clear_min_turret_goal() {
128 min_turret_goal_ = -::std::numeric_limits<double>::infinity();
129 }
130 void clear_max_turret_goal() {
131 max_turret_goal_ = ::std::numeric_limits<double>::infinity();
132 }
133
134 double min_intake_front_goal_;
135 double max_intake_front_goal_;
136 double min_intake_back_goal_;
137 double max_intake_back_goal_;
138 double min_turret_goal_;
139 double max_turret_goal_;
140};
141
142} // namespace superstructure
143} // namespace control_loops
144} // namespace y2022
145
146#endif