blob: dcc26d45ec12fce44cc6231d619669e3ebd9658f [file] [log] [blame]
#ifndef Y2024_CONTROL_LOOPS_SUPERSTRUCTURE_COLLISION_AVOIDENCE_H_
#define Y2024_CONTROL_LOOPS_SUPERSTRUCTURE_COLLISION_AVOIDENCE_H_
#include <cmath>
#include "frc971/control_loops/control_loops_generated.h"
#include "frc971/control_loops/profiled_subsystem_generated.h"
namespace y2024::control_loops::superstructure {
// Checks if theta is between theta_min and theta_max. Expects all angles to be
// wrapped from 0 to 2pi
bool AngleInRange(double theta, double theta_min, double theta_max);
// 1. Prevent the turret from moving if the intake is up
// and prevent the back of the turret from colliding with the intake when it's
// up.
// 2. If the intake is up, drop it so it is not in the way
// 3. Move the turret to the desired position.
// 4. When the turret moves away, if the intake is down, move it back up.
class CollisionAvoidance {
public:
struct Status {
double intake_pivot_position;
double turret_position;
double extend_position;
bool operator==(const Status &s) const {
return (intake_pivot_position == s.intake_pivot_position &&
turret_position == s.turret_position &&
extend_position == s.extend_position);
}
bool operator!=(const Status &s) const { return !(*this == s); }
};
// For the turret, 0 rad is pointing straight forwards
static constexpr double kMinCollisionZoneTurret = 0.15;
static constexpr double kMaxCollisionZoneTurret = 1.15;
static constexpr double kSafeTurretExtendedPosition = 0.0;
// Maximum position of the intake to avoid collisions
static constexpr double kCollisionZoneIntake = 1.6;
static constexpr double kMinCollisionZoneExtend = 0.03;
// Tolerances for the subsystems
static constexpr double kEpsTurret = 0.05;
static constexpr double kEpsIntake = 0.05;
static constexpr double kEpsExtend = 0.005;
CollisionAvoidance();
// Reports if the superstructure is collided.
bool IsCollided(const Status &status);
// Checks if there is a collision with the intake.
bool TurretCollided(double intake_position, double turret_position,
double extend_position);
// Checks if there is a collision with the extend.
bool ExtendCollided(double intake_position, double turret_position,
double extend_position);
// Checks and alters goals to make sure they're safe.
void UpdateGoal(const CollisionAvoidance::Status &status,
double turret_goal_position, double extend_goal_position);
// Limits if goal is in collision spots.
void CalculateAvoidance(double intake_position, double turret_position,
double extend_position, double turret_goal,
double extend_goal);
// Returns the goals to give to the respective control loops in
// superstructure.
double min_extend_goal() const { return min_extend_goal_; }
double max_extend_goal() const { return max_extend_goal_; }
double min_turret_goal() const { return min_turret_goal_; }
double max_turret_goal() const { return max_turret_goal_; }
double min_intake_pivot_goal() const { return min_intake_pivot_goal_; }
double max_intake_pivot_goal() const { return max_intake_pivot_goal_; }
void update_max_turret_goal(double max_turret_goal) {
max_turret_goal_ = ::std::min(max_turret_goal, max_turret_goal_);
}
void update_min_turret_goal(double min_turret_goal) {
min_turret_goal_ = ::std::max(min_turret_goal, min_turret_goal_);
}
void update_max_intake_pivot_goal(double max_intake_pivot_goal) {
max_intake_pivot_goal_ =
::std::min(max_intake_pivot_goal, max_intake_pivot_goal_);
}
void update_min_intake_pivot_goal(double min_intake_pivot_goal) {
min_intake_pivot_goal_ =
::std::max(min_intake_pivot_goal, min_intake_pivot_goal_);
}
void update_min_extend_goal(double min_extend_goal) {
min_extend_goal_ = ::std::max(min_extend_goal, min_extend_goal_);
}
void update_max_extend_goal(double max_extend_goal) {
max_extend_goal_ = ::std::min(max_extend_goal, max_extend_goal_);
}
private:
void clear_min_intake_pivot_goal() {
min_intake_pivot_goal_ = -::std::numeric_limits<double>::infinity();
}
void clear_max_intake_pivot_goal() {
max_intake_pivot_goal_ = ::std::numeric_limits<double>::infinity();
}
void clear_min_turret_goal() {
min_turret_goal_ = -::std::numeric_limits<double>::infinity();
}
void clear_max_turret_goal() {
max_turret_goal_ = ::std::numeric_limits<double>::infinity();
}
void clear_min_extend_goal() {
min_extend_goal_ = -::std::numeric_limits<double>::infinity();
}
void clear_max_extend_goal() {
max_extend_goal_ = ::std::numeric_limits<double>::infinity();
}
double min_intake_pivot_goal_;
double max_intake_pivot_goal_;
double min_turret_goal_;
double max_turret_goal_;
double min_extend_goal_;
double max_extend_goal_;
};
} // namespace y2024::control_loops::superstructure
#endif