Niko Sohmers | ac4d887 | 2024-02-23 13:55:47 -0800 | [diff] [blame] | 1 | #include "y2024/control_loops/superstructure/collision_avoidance.h" |
| 2 | |
| 3 | #include <cmath> |
| 4 | |
| 5 | #include "absl/functional/bind_front.h" |
| 6 | #include "glog/logging.h" |
| 7 | |
| 8 | namespace y2024::control_loops::superstructure { |
| 9 | |
| 10 | CollisionAvoidance::CollisionAvoidance() { |
| 11 | clear_min_intake_pivot_goal(); |
| 12 | clear_max_intake_pivot_goal(); |
| 13 | clear_min_turret_goal(); |
| 14 | clear_max_turret_goal(); |
| 15 | } |
| 16 | |
| 17 | bool CollisionAvoidance::IsCollided(const CollisionAvoidance::Status &status) { |
| 18 | // Checks if intake front is collided. |
| 19 | if (TurretCollided(status.intake_pivot_position, status.turret_position, |
| 20 | kMinCollisionZoneTurret, kMaxCollisionZoneTurret)) { |
| 21 | return true; |
| 22 | } |
| 23 | |
| 24 | return false; |
| 25 | } |
| 26 | |
| 27 | bool AngleInRange(double theta, double theta_min, double theta_max) { |
| 28 | return ( |
| 29 | (theta >= theta_min && theta <= theta_max) || |
| 30 | (theta_min > theta_max && (theta >= theta_min || theta <= theta_max))); |
| 31 | } |
| 32 | |
| 33 | bool CollisionAvoidance::TurretCollided(double intake_position, |
| 34 | double turret_position, |
| 35 | double min_turret_collision_position, |
| 36 | double max_turret_collision_position) { |
| 37 | // Checks if turret is in the collision area. |
| 38 | if (AngleInRange(turret_position, min_turret_collision_position, |
| 39 | max_turret_collision_position)) { |
| 40 | // Returns true if the intake is raised. |
| 41 | if (intake_position > kCollisionZoneIntake) { |
| 42 | return true; |
| 43 | } |
| 44 | } else { |
| 45 | return false; |
| 46 | } |
| 47 | return false; |
| 48 | } |
| 49 | |
| 50 | void CollisionAvoidance::UpdateGoal(const CollisionAvoidance::Status &status, |
| 51 | const double &turret_goal_position) { |
| 52 | // Start with our constraints being wide open. |
| 53 | clear_max_turret_goal(); |
| 54 | clear_min_turret_goal(); |
| 55 | clear_max_intake_pivot_goal(); |
| 56 | clear_min_intake_pivot_goal(); |
| 57 | |
| 58 | const double intake_pivot_position = status.intake_pivot_position; |
| 59 | const double turret_position = status.turret_position; |
| 60 | |
| 61 | const double turret_goal = turret_goal_position; |
| 62 | |
| 63 | // Calculating the avoidance with the intake |
| 64 | |
| 65 | CalculateAvoidance(true, intake_pivot_position, turret_position, turret_goal, |
| 66 | kMinCollisionZoneTurret, kMaxCollisionZoneTurret); |
| 67 | } |
| 68 | |
| 69 | void CollisionAvoidance::CalculateAvoidance(bool intake_pivot, |
| 70 | double intake_position, |
| 71 | double turret_position, |
| 72 | double turret_goal, |
| 73 | double min_turret_collision_goal, |
| 74 | double max_turret_collision_goal) { |
| 75 | // If the turret goal is in a collison zone or moving through one, limit |
| 76 | // intake. |
| 77 | const bool turret_pos_unsafe = AngleInRange( |
| 78 | turret_position, min_turret_collision_goal, max_turret_collision_goal); |
| 79 | |
| 80 | const bool turret_moving_forward = (turret_goal > turret_position); |
| 81 | |
| 82 | // Check if the closest angles are going to be passed |
| 83 | const bool turret_moving_past_intake = |
| 84 | ((turret_moving_forward && |
| 85 | (turret_position <= max_turret_collision_goal && |
| 86 | turret_goal >= min_turret_collision_goal)) || |
| 87 | (!turret_moving_forward && |
| 88 | (turret_position >= min_turret_collision_goal && |
| 89 | turret_goal <= max_turret_collision_goal))); |
| 90 | |
| 91 | if (turret_pos_unsafe || turret_moving_past_intake) { |
| 92 | // If the turret is unsafe, limit the intake |
| 93 | if (intake_pivot) { |
| 94 | update_max_intake_pivot_goal(kCollisionZoneIntake - kEpsIntake); |
| 95 | } |
| 96 | |
| 97 | // If the intake is in the way, limit the turret until moved. Otherwise, |
| 98 | // let'errip! |
| 99 | if (!turret_pos_unsafe && (intake_position > kCollisionZoneIntake)) { |
| 100 | if (turret_position < |
| 101 | (min_turret_collision_goal + max_turret_collision_goal / 2)) { |
| 102 | update_max_turret_goal(min_turret_collision_goal - kEpsTurret); |
| 103 | } else { |
| 104 | update_min_turret_goal(max_turret_collision_goal + kEpsTurret); |
| 105 | } |
| 106 | } |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | } // namespace y2024::control_loops::superstructure |