ary-over-under/CLOUDS/src/superstructure.cpp
2024-01-03 17:47:18 -05:00

290 lines
7.9 KiB
C++

#include "superstructure.hpp"
using namespace ary;
using namespace globals;
bool ptoEnabled = false;
bool wingsOpen = false;
/*
SCALE SPEEDS: Determines what percentage speeds of autonomous movements should move at
speedScale -> The scale of how fast the drivetrain goes forward and backwards
turnScale -> The scale of how fast the drivetrain turns
swingScale -> The scale of fast one side of the chassis moves
*/
double speedScale = 1.0;
double turnScale = 1.0;
double swingScale = 1.0;
double intakeSpeed = 0;
namespace superstruct
{
void chassisInit()
{
/*
When the robot first starts up we want to do a couple things:
- Adjust the drivetrain curve bottons so it does not interfere with any of the driver controls.
- Enable the joystick curve
- Enable active break on the drive
- Active break is a P controller applied to the drivetrain in order to help it maintain it's position, resisting external forces.
-
*/
chassis.set_curve_buttons(pros::E_CONTROLLER_DIGITAL_LEFT, pros::E_CONTROLLER_DIGITAL_RIGHT);
chassis.toggle_modify_curve_with_controller(true);
chassis.set_active_brake(0.1);
chassis.set_curve_default(1.075, 1.075);
/* Adjust the adjust the factor by which the drive velocity is adjusted */
chassis.set_joystick_drivescale(1.0);
chassis.set_joystick_turnscale(1.0);
}
void opControlInit()
{
motorsCoast();
disableActiveBrake();
}
// Adjust exit conditions to allow for quick movements
void configureExitConditions()
{
chassis.set_exit_condition(chassis.turn_exit, 45, 2, 150, 3, 435, 435);
chassis.set_exit_condition(chassis.swing_exit, 100, 3, 400, 7, 435, 435);
chassis.set_exit_condition(chassis.drive_exit, 35, 80, 200, 150, 435, 435);
}
// Adjust PID constants for accurate movements
void configureConstants()
{
chassis.set_slew_min_power(80, 80);
chassis.set_slew_distance(7, 7);
chassis.set_pid_constants(&chassis.headingPID, 16, 0, 52, 0);
chassis.set_pid_constants(&chassis.forward_drivePID, 3, 0, 18, 0);
chassis.set_pid_constants(&chassis.backward_drivePID, 3, 0, 18, 0);
chassis.set_pid_constants(&chassis.turnPID, 8, 0.001, 80, 15);
chassis.set_pid_constants(&chassis.swingPID, 8.5, 0, 50, 0);
}
// Prepare the bot for the autonomous period of a match
void autonomousResets()
{
chassis.reset_pid_targets();
chassis.reset_gyro();
chassis.reset_drive_sensor();
configureConstants();
configureExitConditions();
motorsBrake();
}
void motorsCoast()
{
chassis.set_drive_brake(MOTOR_BRAKE_COAST);
}
void motorsHold()
{
chassis.set_drive_brake(MOTOR_BRAKE_HOLD);
}
void motorsBrake()
{
chassis.set_drive_brake(MOTOR_BRAKE_BRAKE);
}
// The chassis will not apply a constant voltage to prevent it from being moved
void disableActiveBrake()
{
chassis.set_active_brake(0.0);
}
void handleIntake() {
while (true) {
intake_mtr.move_voltage(intakeSpeed);
pros::delay(ary::util::DELAY_TIME);
}
}
pros::Task intakeManager(handleIntake);
// Drives forward, runs next commands WITHOUT waiting for the drive to complete
void driveAsync(double dist, bool useHeadingCorrection)
{
chassis.set_drive(dist, DRIVE_SPEED * speedScale, (dist > 14.0) ? true : false, useHeadingCorrection);
}
// Drives forward, runs next commands AFTER waiting for the drive to complete
void driveSync(double dist, bool useHeadingCorrection)
{
chassis.set_drive(dist, DRIVE_SPEED * speedScale, (dist > 14.0) ? true : false, useHeadingCorrection);
chassis.wait_drive();
}
// Drives forward, runs next commands AFTER reaching a certain measurement/error along the path
void driveWithMD(double dist, bool useHeadingCorrection, double waitUntilDist)
{
chassis.set_drive(dist, DRIVE_SPEED * speedScale, (dist > 14.0) ? true : false, useHeadingCorrection);
chassis.wait_until(waitUntilDist);
}
// Turns the chassis, runs other commands after it has run.
void turnSync(double theta)
{
chassis.set_turn(theta, TURN_SPEED * turnScale);
chassis.wait_drive();
}
// Turns the chassis, runs other commands immediately after call
void turnAsync(double theta)
{
chassis.set_turn(theta, TURN_SPEED * turnScale);
}
// Moves only the right side of the chassis so it can make a left turn
void leftSwing(double theta)
{
chassis.set_swing(LEFT_SWING, theta, SWING_SPEED * swingScale);
}
// Moves only the left side of the chassis so it can make a right turn
void rightSwing(double theta)
{
chassis.set_swing(RIGHT_SWING, theta, SWING_SPEED * swingScale);
}
/*
Each of the scale values must be clamed between 0.1 - 1 (10% to 100%) to avoid saturation of motors.
*/
void setDriveScale(double val)
{
speedScale = std::clamp(val, 0.1, 1.0);
}
void setTurnScale(double val)
{
turnScale = std::clamp(val, 0.1, 1.0);
}
void setSwingScale(double val)
{
swingScale = std::clamp(val, 0.1, 1.0); //
}
// Structure methods
void togglePto(bool toggle)
{
ptoEnabled = toggle;
chassis.pto_toggle({intake_mtr, cata_mtr}, toggle); // Configure the listed PTO motors to whatever value toggle is.
pto_piston.set_value(toggle);
if (toggle)
{
intake_mtr.set_brake_mode(MOTOR_BRAKE_COAST);
cata_mtr.set_brake_mode(MOTOR_BRAKE_COAST);
}
}
void runCata(double inpt)
{
if (!ptoEnabled)
return;
cata_mtr.move_voltage(inpt);
}
void setIntakeSpeed(double inpt)
{
if (!ptoEnabled) {
intakeSpeed = 0;
} else {
intakeSpeed = inpt;
}
}
int lock = 0;
void subsysControl(pros::controller_digital_e_t ptoToggleButton, pros::controller_digital_e_t cataRunButton, pros::controller_digital_e_t intakeButton, pros::controller_digital_e_t outtakeButton)
{
if (globals::master.get_digital(ptoToggleButton) && lock == 0)
{ // If the PTO button has been pressed and the PTO is not engaged
togglePto(!ptoEnabled); // Toggle the PTO so that cataput is useable
lock = 1;
}
else if (!globals::master.get_digital(ptoToggleButton))
{
lock = 0;
}
if (globals::master.get_digital(cataRunButton))
{
runCata(-12000);
}
else
{
runCata(0);
}
if (globals::master.get_digital(intakeButton))
{
setIntakeSpeed(-12000);
}
else if (globals::master.get_digital(outtakeButton))
{
setIntakeSpeed(12000);
}
else
{
setIntakeSpeed(0);
}
}
void wingsControl(pros::controller_digital_e_t wingControlButton)
{
if (globals::master.get_digital_new_press(wingControlButton))
{
if (wings.getState() == 0) // A value of 0 indicates that both wings are closed
wings.open();
else if (wings.getState() == 3) // A value of 3 indicates that both wings are open
wings.close();
}
}
void actuateClimb()
{
climb_piston_one.set_value(1);
climb_piston_two.set_value(1);
}
void climbControl(pros::controller_digital_e_t but1, pros::controller_digital_e_t but2)
{
if (globals::master.get_digital(but1) && globals::master.get_digital(but2))
{
actuateClimb();
}
}
/*
Controls -> For whoever is controlling the robot
*/
void renu_control()
{
subsysControl(RENU_PTO_TOGGLE, RENU_CATA_CONTROL, RENU_INTAKE_CONTROL_INTAKE, RENU_INTAKE_CONTROL_OUTTAKE);
wingsControl(RENU_WING_CONTROL);
climbControl(RENU_CLIMB_CONTROL_ONE, RENU_CLIMB_CONTROL_TWO);
}
void ria_control()
{
subsysControl(RENU_PTO_TOGGLE, RENU_CATA_CONTROL, RENU_INTAKE_CONTROL_INTAKE, RENU_INTAKE_CONTROL_OUTTAKE);
wingsControl(RENU_WING_CONTROL);
climbControl(RENU_CLIMB_CONTROL_ONE, RENU_CLIMB_CONTROL_TWO);
}
void chris_control()
{
subsysControl(RENU_PTO_TOGGLE, RENU_CATA_CONTROL, RENU_INTAKE_CONTROL_INTAKE, RENU_INTAKE_CONTROL_OUTTAKE);
wingsControl(RENU_WING_CONTROL);
climbControl(RENU_CLIMB_CONTROL_ONE, RENU_CLIMB_CONTROL_TWO);
}
}