blob: b4074091791557ba39b14da2e3f783b4793f4287 [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
Milind Upadhyay8e2582b2022-03-06 15:14:15 -080022// Checks if theta is between theta_min and theta_max. Expects all angles to be
23// wrapped from 0 to 2pi
24bool AngleInRange(double theta, double theta_min, double theta_max);
25
Milind Upadhyay225156b2022-02-25 22:42:12 -080026// 1. Prevent the turret from moving if the intake is up
27// 2. If the intake is up, drop it so it is not in the way
28// 3. Move the turret to the desired position.
29// 4. When the turret moves away, if the intake is down, move it back up.
30class CollisionAvoidance {
31 public:
32 struct Status {
33 double intake_front_position;
34 double intake_back_position;
35 double turret_position;
36
37 bool operator==(const Status &s) const {
38 return (intake_front_position == s.intake_front_position &&
39 intake_back_position == s.intake_back_position &&
40 turret_position == s.turret_position);
41 }
42 bool operator!=(const Status &s) const { return !(*this == s); }
43 };
44
45 // TODO(henry): put actual constants here.
46
47 // Reference angles between which the turret will be careful
48 static constexpr double kCollisionZoneTurret = M_PI * 5.0 / 18.0;
49
50 // For the turret, 0 rad is pointing straight forwards
51 static constexpr double kMinCollisionZoneFrontTurret =
52 M_PI - kCollisionZoneTurret;
53 static constexpr double kMaxCollisionZoneFrontTurret =
54 M_PI + kCollisionZoneTurret;
55
Milind Upadhyay8e2582b2022-03-06 15:14:15 -080056 static constexpr double kMinCollisionZoneBackTurret =
57 (2.0 * M_PI) - kCollisionZoneTurret;
Milind Upadhyay225156b2022-02-25 22:42:12 -080058 static constexpr double kMaxCollisionZoneBackTurret = kCollisionZoneTurret;
59
milind-u3e297d32022-03-05 10:31:12 -080060 // Maximum position of the intake to avoid collisions
Austin Schuh465a2882022-03-05 15:39:04 -080061 static constexpr double kCollisionZoneIntake = 1.4;
Milind Upadhyay225156b2022-02-25 22:42:12 -080062
63 // Tolerance for the turret.
64 static constexpr double kEpsTurret = 0.05;
65 // Tolerance for the intake.
66 static constexpr double kEpsIntake = 0.05;
67
68 CollisionAvoidance();
69
70 // Reports if the superstructure is collided.
71 bool IsCollided(const Status &status);
72 // Checks if there is a collision on either intake.
73 bool TurretCollided(double intake_position, double turret_position,
74 double min_turret_collision_position,
75 double max_turret_collision_position);
76 // Checks and alters goals to make sure they're safe.
Ravago Jones5da06352022-03-04 20:26:24 -080077 void UpdateGoal(
78 const Status &status,
79 const frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal
80 *unsafe_turret_goal);
Milind Upadhyay225156b2022-02-25 22:42:12 -080081 // Limits if goal is in collision spots.
82 void CalculateAvoidance(bool intake_front, double intake_position,
83 double turret_goal, double mix_turret_collision_goal,
84 double max_turret_collision_goal,
85 double turret_position);
86
87 // Returns the goals to give to the respective control loops in
88 // superstructure.
89 double min_turret_goal() const { return min_turret_goal_; }
90 double max_turret_goal() const { return max_turret_goal_; }
91 double min_intake_front_goal() const { return min_intake_front_goal_; }
92 double max_intake_front_goal() const { return max_intake_front_goal_; }
93 double min_intake_back_goal() const { return min_intake_back_goal_; }
94 double max_intake_back_goal() const { return max_intake_back_goal_; }
95
96 void update_max_turret_goal(double max_turret_goal) {
97 max_turret_goal_ = ::std::min(max_turret_goal, max_turret_goal_);
98 }
99 void update_min_turret_goal(double min_turret_goal) {
100 min_turret_goal_ = ::std::max(min_turret_goal, min_turret_goal_);
101 }
102 void update_max_intake_front_goal(double max_intake_front_goal) {
103 max_intake_front_goal_ =
104 ::std::min(max_intake_front_goal, max_intake_front_goal_);
105 }
106 void update_min_intake_front_goal(double min_intake_front_goal) {
107 min_intake_front_goal_ =
108 ::std::max(min_intake_front_goal, min_intake_front_goal_);
109 }
110 void update_max_intake_back_goal(double max_intake_back_goal) {
111 max_intake_back_goal_ =
112 ::std::min(max_intake_back_goal, max_intake_back_goal_);
113 }
114 void update_min_intake_back_goal(double min_intake_back_goal) {
115 min_intake_back_goal_ =
116 ::std::max(min_intake_back_goal, min_intake_back_goal_);
117 }
118
119 private:
120 void clear_min_intake_front_goal() {
121 min_intake_front_goal_ = -::std::numeric_limits<double>::infinity();
122 }
123 void clear_max_intake_front_goal() {
124 max_intake_front_goal_ = ::std::numeric_limits<double>::infinity();
125 }
126 void clear_min_intake_back_goal() {
127 min_intake_back_goal_ = -::std::numeric_limits<double>::infinity();
128 }
129 void clear_max_intake_back_goal() {
130 max_intake_back_goal_ = ::std::numeric_limits<double>::infinity();
131 }
132 void clear_min_turret_goal() {
133 min_turret_goal_ = -::std::numeric_limits<double>::infinity();
134 }
135 void clear_max_turret_goal() {
136 max_turret_goal_ = ::std::numeric_limits<double>::infinity();
137 }
138
139 double min_intake_front_goal_;
140 double max_intake_front_goal_;
141 double min_intake_back_goal_;
142 double max_intake_back_goal_;
143 double min_turret_goal_;
144 double max_turret_goal_;
145};
146
147} // namespace superstructure
148} // namespace control_loops
149} // namespace y2022
150
151#endif