blob: ac88cece3af1facfdd02a7406b84b82912304c65 [file] [log] [blame]
#ifndef Y2019_CONTROL_LOOPS_SUPERSTRUCTURE_COLLISION_AVOIDANCE_H_
#define Y2019_CONTROL_LOOPS_SUPERSTRUCTURE_COLLISION_AVOIDANCE_H_
#include <cmath>
#include "frc971/constants.h"
#include "frc971/control_loops/control_loops_generated.h"
#include "frc971/control_loops/profiled_subsystem_generated.h"
#include "y2019/control_loops/superstructure/superstructure_goal_generated.h"
#include "y2019/control_loops/superstructure/superstructure_status_generated.h"
namespace y2019 {
namespace control_loops {
namespace superstructure {
// CollisionAvoidance computes the min and max allowable ranges for various
// subsystems to avoid collisions. It also shoves the elevator up to let the
// intake go in and out, and to let the wrist switch sides.
class CollisionAvoidance {
public:
CollisionAvoidance();
// Reports if the superstructure is collided.
bool IsCollided(const Status *status);
bool IsCollided(double wrist_position, double elevator_position,
double intake_position, bool has_piece);
// Checks and alters goals to make sure they're safe.
// TODO(austin): Either we will have a unit delay because this has to happen
// after the controls, or we need to be more clever about restructuring.
void UpdateGoal(const Status *status, const Goal *unsafe_goal);
// Returns the goals to give to the respective control loops in
// superstructure.
double min_wrist_goal() const { return min_wrist_goal_; }
double max_wrist_goal() const { return max_wrist_goal_; }
double min_elevator_goal() const { return min_elevator_goal_; }
double min_intake_goal() const { return min_intake_goal_; }
double max_intake_goal() const { return max_intake_goal_; }
void update_max_wrist_goal(double max_wrist_goal) {
max_wrist_goal_ = ::std::min(max_wrist_goal, max_wrist_goal_);
}
void update_min_wrist_goal(double min_wrist_goal) {
min_wrist_goal_ = ::std::max(min_wrist_goal, min_wrist_goal_);
}
void update_max_intake_goal(double max_intake_goal) {
max_intake_goal_ = ::std::min(max_intake_goal, max_intake_goal_);
}
void update_min_intake_goal(double min_intake_goal) {
min_intake_goal_ = ::std::max(min_intake_goal, min_intake_goal_);
}
void update_min_elevator_goal(double min_elevator_goal) {
min_elevator_goal_ = ::std::max(min_elevator_goal, min_elevator_goal_);
}
// Height above which we can move the wrist freely.
static constexpr double kElevatorClearHeight = 0.35;
// Height above which we can move the wrist down.
static constexpr double kElevatorClearWristDownHeight = 0.25;
// Height the carriage needs to be above to move the intake.
static constexpr double kElevatorClearIntakeHeight = 0.4;
// Angle constraints for the wrist when below kElevatorClearDownHeight
static constexpr double kWristMaxAngle = M_PI / 2.0 + 0.15;
static constexpr double kWristMinAngle = -M_PI / 2.0 - 0.25;
// Angles outside of which the intake is fully clear of the wrist.
static constexpr double kIntakeOutAngle = 0.3;
static constexpr double kIntakeInAngle = -1.1;
// Angles within which we will crash the wrist into the elevator if the
// elevator is below kElevatorClearHeight.
static constexpr double kWristElevatorCollisionMinAngle = -M_PI / 4.0;
static constexpr double kWristElevatorCollisionMaxAngle = M_PI / 4.0;
static constexpr double kWristElevatorCollisionMaxAngleWithoutObject =
M_PI / 6.0;
// Tolerance for the elevator.
static constexpr double kEps = 0.02;
// Tolerance for the intake.
static constexpr double kEpsIntake = 0.05;
// Tolerance for the wrist.
static constexpr double kEpsWrist = 0.05;
private:
void clear_min_wrist_goal() {
min_wrist_goal_ = -::std::numeric_limits<double>::infinity();
}
void clear_max_wrist_goal() {
max_wrist_goal_ = ::std::numeric_limits<double>::infinity();
}
void clear_min_elevator_goal() {
min_elevator_goal_ = -::std::numeric_limits<double>::infinity();
}
void clear_min_intake_goal() {
min_intake_goal_ = -::std::numeric_limits<double>::infinity();
}
void clear_max_intake_goal() {
max_intake_goal_ = ::std::numeric_limits<double>::infinity();
}
double min_wrist_goal_;
double max_wrist_goal_;
double min_elevator_goal_;
double min_intake_goal_;
double max_intake_goal_;
};
} // namespace superstructure
} // namespace control_loops
} // namespace y2019
#endif // Y2019_CONTROL_LOOPS_SUPERSTRUCTURE_COLLISION_AVOIDANCE_H_