diff --git a/README.md b/README.md index f5bc8cad..f1dfee4e 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,51 @@ ---- -layout: default -title: EZ-Template -nav_order: 1 -permalink: / ---- - -[![License: MPL 2.0](https://img.shields.io/badge/License-MPL%202.0-brightgreen.svg)](https://opensource.org/licenses/MPL-2.0) +![](https://img.shields.io/github/downloads/EZ-Robotics/EZ-Template/total.svg) +![](https://github.com/EZ-Robotics/EZ-Template/workflows/Build/badge.svg) +[![License: MPL 2.0](https://img.shields.io/badge/License-MPL%202.0-brightgreen.svg)](https://opensource.org/licenses/MPL-2.0) # EZ-Template -Simple plug-and-play PROS template that handles drive base functions for VEX robots. - - -[EZ-Template Version](https://github.com/EZ-Robotics/EZ-Template): 2.1.2-RC1 +EZ-Template is a simple plug-and-play PROS template that handles drive base functions, autonomous selector, input curves, and active brake with PTO support. [Autonomous routines that used EZ-Template](https://photos.app.goo.gl/yRwuvmq7hDoM4f6EA) +## Features +- Simple to setup +- PID for driving, turning, and swing turns +- Speed ramp-up for driving +- Asynchronous PID with blocking functions until settled and until a specific position has come +- Joystick input curves +- Live adjustment of input curves +- Basic autonomous selector +- SD card saving of autonomous selector and joystick curves +- "Tug of war" detection for autonomous +- PID exit conditions for when drive motors overheat +- Tank drive, single stick arcade, and dual stick arcade +- Loading animation during IMU calibration +- 3 wire encoder and rotation sensor support +- Add / remove motors from the drive dynamically to allow for PTO use +- Exposed PID class for use with your other subsystems + ## Download and Installation -1) Download the latest example project [here](https://github.com/EZ-Robotics/EZ-Template/releases/latest). Extract the zip, and open it in PROS. +1) Download the latest `Example-Project.zip` [here](https://github.com/EZ-Robotics/EZ-Template/releases/latest). Extract the zip, and open it in PROS. 2) In `src/main.cpp`, configure drive and IMU ports to what they are on your robot. Be sure to read the comments! -3) Configure your wheel size and cartridge. Remember that 4" omni wheels are actually 4.125! +3) Configure your wheel size and cartridge. Remember that older 4" omni wheels without mounting holes are actually 4.125! 4) In `src/main.cpp`, at the bottom in `void opcontrol()`, decide how you'd like to control your robot! Any flavor of arcade or tank! -5) Turn the robot on and use it in driver control. Make sure the ports are correct and reversed correctly! -6) To test the test autonomous modes, plug into a competition switch and select the autonomous mode on the brain screen by pressing the left and right buttons! The current page will be the autonomous that runs. For making new autonomous routines, check `src/autons.cpp` for examples on how to use the drive functions. +5) Turn the robot on and use it in driver control. Make sure the ports are correct and reversed correctly. +6) To test the test autonomous modes, plug into a competition switch and select the autonomous mode on the brain screen by pressing the left and right buttons. The current page will be the autonomous that runs. For making new autonomous routines, [click here](https://ez-robotics.github.io/EZ-Template/tutorials/example_autons) for examples on how to use the drive functions. ## Upgrading -*Note: this only works for 2.0.0 and beyond. You cannot upgrade from 1.X.X to 2.X.X.* -1) Download the most recent EZ-Template [here](https://github.com/EZ-Robotics/EZ-Template/releases/latest). +*Note: this only works for 2.x and beyond. You cannot upgrade from 1.x to 2.x, or 2.x to 3.x without changing code.* +1) Download the most recent `EZ-Template@x.x.x.zip` [here](https://github.com/EZ-Robotics/EZ-Template/releases/latest). 2) Move the file to your project. 3) Open terminal or command prompt, and `cd` into your projects directory. -4) Run this command from terminal `prosv5 c fetch EZ-Template@2.1.1.zip`. +4) Run this command from terminal `prosv5 c fetch EZ-Template@x.x.x.zip` replacing `x.x.x` with the version number of your file. 5) Apply the library to the project `prosv5 c apply EZ-Template`. 6) Put `#include "EZ-Template/api.hpp"` in your `include/main.h`. ## Tutorials -[Check out our tutorials here!](https://ez-robotics.github.io/EZ-Template/tutorials) +[Check out our tutorials here!](https://ez-robotics.github.io/EZ-Template/category/tutorials) ## Docs -[Read the docs here!](https://ez-robotics.github.io/EZ-Template/docs) - -## Additing Autonomous Routines -[Check out the tutorial on adding new autonomous routines here!](https://ez-robotics.github.io/EZ-Template/docs/Tutorials/autons.html) +[Read the docs here!](https://ez-robotics.github.io/EZ-Template/category/docs) ## License diff --git a/include/EZ-Template/PID.hpp b/include/EZ-Template/PID.hpp index 0f75b902..570729ec 100644 --- a/include/EZ-Template/PID.hpp +++ b/include/EZ-Template/PID.hpp @@ -161,6 +161,11 @@ class PID { */ void name_set(std::string name); + /** + * Returns the name of the PID that prints during exit conditions. + */ + std::string name_get(); + /** * Enables / disables i resetting when sgn of error changes. True resets, false doesn't. * diff --git a/include/EZ-Template/drive/drive.hpp b/include/EZ-Template/drive/drive.hpp index fc55f09b..9372f40a 100644 --- a/include/EZ-Template/drive/drive.hpp +++ b/include/EZ-Template/drive/drive.hpp @@ -22,7 +22,7 @@ using namespace ez; class Drive { public: /** - * Joysticks will return 0 when they are within this number. Set with opcontrol_joystick_threshold() + * Joysticks will return 0 when they are within this number. Set with opcontrol_joystick_threshold_set() */ int JOYSTICK_THRESHOLD; @@ -214,13 +214,13 @@ class Drive { /** * Sets the chassis to controller joysticks using tank control. Run is usercontrol. - * This passes the controller through the curve functions, but is disabled by default. Use toggle_controller_curve_modifier() to enable it. + * This passes the controller through the curve functions, but is disabled by default. Use opcontrol_curve_buttons_toggle() to enable it. */ void opcontrol_tank(); /** * Sets the chassis to controller joysticks using standard arcade control. Run is usercontrol. - * This passes the controller through the curve functions, but is disabled by default. Use toggle_controller_curve_modifier() to enable it. + * This passes the controller through the curve functions, but is disabled by default. Use opcontrol_curve_buttons_toggle() to enable it. * * \param stick_type * ez::SINGLE or ez::SPLIT control @@ -229,7 +229,7 @@ class Drive { /** * Sets the chassis to controller joysticks using flipped arcade control. Run is usercontrol. - * This passes the controller through the curve functions, but is disabled by default. Use toggle_controller_curve_modifier() to enable it. + * This passes the controller through the curve functions, but is disabled by default. Use opcontrol_curve_buttons_toggle() to enable it. * * \param stick_type * ez::SINGLE or ez::SPLIT control @@ -251,6 +251,11 @@ class Drive { */ void opcontrol_curve_default_set(double left, double right = 0); + /** + * Gets the default joystick curves, in {left, right} + */ + std::vector opcontrol_curve_default_get(); + /** * Runs a P loop on the drive when the joysticks are released. * @@ -259,6 +264,11 @@ class Drive { */ void opcontrol_drive_activebrake_set(double kp); + /** + * Returns kP for active brake. + */ + double opcontrol_drive_activebrake_get(); + /** * Enables/disables modifying the joystick input curves with the controller. True enables, false disables. * @@ -267,6 +277,11 @@ class Drive { */ void opcontrol_curve_buttons_toggle(bool toggle); + /** + * Gets the current state of the toggle. Enables/disables modifying the joystick input curves with the controller. True enables, false disables. + */ + bool opcontrol_curve_buttons_toggle_get(); + /** * Sets buttons for modifying the left joystick curve. * @@ -275,7 +290,12 @@ class Drive { * \param increase * a pros button enumerator */ - void opcontrol_curve_buttons_left(pros::controller_digital_e_t decrease, pros::controller_digital_e_t increase); + void opcontrol_curve_buttons_left_set(pros::controller_digital_e_t decrease, pros::controller_digital_e_t increase); + + /** + * Returns a vector of pros controller buttons user for the left joystick curve, in {decrease, increase} + */ + std::vector opcontrol_curve_buttons_left_get(); /** * Sets buttons for modifying the right joystick curve. @@ -285,7 +305,12 @@ class Drive { * \param increase * a pros button enumerator */ - void opcontrol_curve_buttons_right(pros::controller_digital_e_t decrease, pros::controller_digital_e_t increase); + void opcontrol_curve_buttons_right_set(pros::controller_digital_e_t decrease, pros::controller_digital_e_t increase); + + /** + * Returns a vector of pros controller buttons user for the right joystick curve, in {decrease, increase} + */ + std::vector opcontrol_curve_buttons_right_get(); /** * Outputs a curve from 5225A In the Zone. This gives more control over the robot at lower speeds. https://www.desmos.com/calculator/rcfjjg83zx @@ -309,7 +334,12 @@ class Drive { * \param threshold * new threshold */ - void opcontrol_joystick_threshold(int threshold); + void opcontrol_joystick_threshold_set(int threshold); + + /** + * Gets a new threshold for the joystick. The joysticks wil not return a value if they are within this. + */ + int opcontrol_joystick_threshold_get(); /** * Resets drive sensors at the start of opcontrol. @@ -390,6 +420,11 @@ class Drive { */ void drive_brake_set(pros::motor_brake_mode_e_t brake_type); + /** + * Returns the brake mode of the drive in pros_brake_mode_e_t_ + */ + pros::motor_brake_mode_e_t drive_brake_get(); + /** * Sets the limit for the current on the drive. * @@ -398,16 +433,31 @@ class Drive { */ void drive_current_limit_set(int mA); + /** + * Gets the limit for the current on the drive. + */ + int drive_current_limit_get(); + /** * Toggles set drive in autonomous. True enables, false disables. */ void pid_drive_toggle(bool toggle); + /** + * Gets the current state of the toggle. This toggles set drive in autonomous. True enables, false disables. + */ + bool pid_drive_toggle_get(); + /** * Toggles printing in autonomous. True enables, false disables. */ void pid_print_toggle(bool toggle); + /** + * Gets the current state of the toggle. This toggles printing in autonomous. True enables, false disables. + */ + bool pid_print_toggle_get(); + ///// // // Telemetry @@ -502,6 +552,11 @@ class Drive { */ void opcontrol_joystick_practicemode_toggle(bool toggle); + /** + * Gets current state of the toggle. Practice mode for driver practice that shuts off the drive if you go max speed. + */ + bool opcontrol_joystick_practicemode_toggle_get(); + ///// // // Autonomous Functions @@ -574,7 +629,7 @@ class Drive { /** * Sets heading of gyro and target of PID. */ - void set_angle(okapi::QAngle p_angle); + void drive_angle_set(okapi::QAngle p_angle); /** * Lock the code in a while loop until the robot has settled. @@ -609,6 +664,7 @@ class Drive { * ratio of the gears */ void drive_ratio_set(double ratio); + /** * Changes max speed during a drive motion. * @@ -617,6 +673,11 @@ class Drive { */ void pid_speed_max_set(int speed); + /** + * Returns max speed of drive during autonomous. + */ + int pid_speed_max_get(); + /** * @brief Set the drive pid constants object * @@ -627,6 +688,16 @@ class Drive { */ void pid_drive_constants_set(double p, double i = 0.0, double d = 0.0, double p_start_i = 0.0); + /** + * @brief returns PID constants with PID::Constants. Returns -1 if fwd and rev constants aren't the same! + * + * @param p kP + * @param i kI + * @param d kD + * @param p_start_i start_I + */ + PID::Constants pid_drive_constants_get(); + /** * @brief Set the turn pid constants object * @@ -637,6 +708,16 @@ class Drive { */ void pid_turn_constants_set(double p, double i = 0.0, double d = 0.0, double p_start_i = 0.0); + /** + * @brief returns PID constants with PID::Constants. + * + * @param p kP + * @param i kI + * @param d kD + * @param p_start_i start_I + */ + PID::Constants pid_turn_constants_get(); + /** * @brief Set the swing pid constants object * @@ -647,6 +728,16 @@ class Drive { */ void pid_swing_constants_set(double p, double i = 0.0, double d = 0.0, double p_start_i = 0.0); + /** + * @brief returns PID constants with PID::Constants. + * + * @param p kP + * @param i kI + * @param d kD + * @param p_start_i start_I + */ + PID::Constants pid_swing_constants_get(); + /** * @brief Set the heading pid constants object * @@ -657,6 +748,16 @@ class Drive { */ void pid_heading_constants_set(double p, double i = 0.0, double d = 0.0, double p_start_i = 0.0); + /** + * @brief returns PID constants with PID::Constants. + * + * @param p kP + * @param i kI + * @param d kD + * @param p_start_i start_I + */ + PID::Constants pid_heading_constants_get(); + /** * @brief Set the forward pid constants object * @@ -667,6 +768,16 @@ class Drive { */ void pid_drive_forward_constants_set(double p, double i = 0.0, double d = 0.0, double p_start_i = 0.0); + /** + * @brief returns PID constants with PID::Constants. + * + * @param p kP + * @param i kI + * @param d kD + * @param p_start_i start_I + */ + PID::Constants pid_drive_forward_constants_get(); + /** * @brief Set the backwards pid constants object * @@ -677,6 +788,16 @@ class Drive { */ void pid_drive_backward_constants_set(double p, double i = 0.0, double d = 0.0, double p_start_i = 0.0); + /** + * @brief returns PID constants with PID::Constants. + * + * @param p kP + * @param i kI + * @param d kD + * @param p_start_i start_I + */ + PID::Constants pid_drive_backward_constants_get(); + /** * Sets minimum power for swings when kI and startI are enabled. * @@ -701,7 +822,7 @@ class Drive { /** * Returns minimum power for turns when kI and startI are enabled. */ - int get_turn_min(); + int pid_turn_min_get(); /** * Sets minimum slew speed constants. diff --git a/src/EZ-Template/drive/drive.cpp b/src/EZ-Template/drive/drive.cpp index 14d953eb..0efbed6a 100644 --- a/src/EZ-Template/drive/drive.cpp +++ b/src/EZ-Template/drive/drive.cpp @@ -161,8 +161,8 @@ void Drive::drive_defaults_set() { opcontrol_curve_buttons_toggle(true); // Left / Right modify buttons - opcontrol_curve_buttons_left(pros::E_CONTROLLER_DIGITAL_LEFT, pros::E_CONTROLLER_DIGITAL_RIGHT); - opcontrol_curve_buttons_right(pros::E_CONTROLLER_DIGITAL_Y, pros::E_CONTROLLER_DIGITAL_A); + opcontrol_curve_buttons_left_set(pros::E_CONTROLLER_DIGITAL_LEFT, pros::E_CONTROLLER_DIGITAL_RIGHT); + opcontrol_curve_buttons_right_set(pros::E_CONTROLLER_DIGITAL_Y, pros::E_CONTROLLER_DIGITAL_A); // Enable auto printing and drive motors moving pid_drive_toggle(true); @@ -215,6 +215,10 @@ void Drive::drive_current_limit_set(int mA) { } } +int Drive::drive_current_limit_get() { + return CURRENT_MA; +} + // Motor telemetry void Drive::drive_sensor_reset() { left_motors.front().tare_position(); @@ -322,6 +326,11 @@ void Drive::drive_brake_set(pros::motor_brake_mode_e_t brake_type) { } } +// Get brake +pros::motor_brake_mode_e_t Drive::drive_brake_get() { + return CURRENT_BRAKE; +} + void Drive::initialize() { opcontrol_curve_sd_initialize(); drive_imu_calibrate(); @@ -329,4 +338,7 @@ void Drive::initialize() { } void Drive::pid_drive_toggle(bool toggle) { drive_toggle = toggle; } -void Drive::pid_print_toggle(bool toggle) { print_toggle = toggle; } \ No newline at end of file +void Drive::pid_print_toggle(bool toggle) { print_toggle = toggle; } + +bool Drive::pid_drive_toggle_get() {return drive_toggle;} +bool Drive::pid_print_toggle_get() {return print_toggle;} \ No newline at end of file diff --git a/src/EZ-Template/drive/pid_tasks.cpp b/src/EZ-Template/drive/pid_tasks.cpp index 2ada35b5..90ea87b7 100644 --- a/src/EZ-Template/drive/pid_tasks.cpp +++ b/src/EZ-Template/drive/pid_tasks.cpp @@ -70,8 +70,8 @@ void Drive::turn_pid_task() { // Clip the speed of the turn when the robot is within StartI, only do this when target is larger then StartI if (turnPID.constants.ki != 0 && (fabs(turnPID.target_get()) > turnPID.constants.start_i && fabs(turnPID.error) < turnPID.constants.start_i)) { - if (get_turn_min() != 0) - gyro_out = util::clamp(gyro_out, get_turn_min(), -get_turn_min()); + if (pid_turn_min_get() != 0) + gyro_out = util::clamp(gyro_out, pid_turn_min_get(), -pid_turn_min_get()); } // Set motors diff --git a/src/EZ-Template/drive/set_pid.cpp b/src/EZ-Template/drive/set_pid.cpp index e4e8f96a..4c846935 100644 --- a/src/EZ-Template/drive/set_pid.cpp +++ b/src/EZ-Template/drive/set_pid.cpp @@ -12,31 +12,65 @@ void Drive::pid_drive_constants_set(double p, double i, double d, double p_start pid_drive_backward_constants_set(p, i, d, p_start_i); } +PID::Constants Drive::pid_drive_constants_get() { + auto fwd_const = pid_drive_forward_constants_get(); + auto rev_const = pid_drive_backward_constants_get(); + if (!(fwd_const.kp == rev_const.kp && fwd_const.ki == rev_const.ki && fwd_const.kd == rev_const.kd && fwd_const.start_i == rev_const.start_i)) { + printf("\nForward and Reverse constants are not the same!"); + return {-1, -1, -1, -1}; + } + return fwd_const; +} + void Drive::pid_drive_forward_constants_set(double p, double i, double d, double p_start_i) { forward_drivePID.constants_set(p, i, d, p_start_i); } +PID::Constants Drive::pid_drive_forward_constants_get() { + return forward_drivePID.constants_get(); +} + void Drive::pid_drive_backward_constants_set(double p, double i, double d, double p_start_i) { backward_drivePID.constants_set(p, i, d, p_start_i); } +PID::Constants Drive::pid_drive_backward_constants_get() { + return backward_drivePID.constants_get(); +} + void Drive::pid_turn_constants_set(double p, double i, double d, double p_start_i) { turnPID.constants_set(p, i, d, p_start_i); } +PID::Constants Drive::pid_turn_constants_get() { + return turnPID.constants_get(); +} + void Drive::pid_swing_constants_set(double p, double i, double d, double p_start_i) { swingPID.constants_set(p, i, d, p_start_i); } +PID::Constants Drive::pid_swing_constants_get() { + return swingPID.constants_get(); +} + void Drive::pid_heading_constants_set(double p, double i, double d, double p_start_i) { headingPID.constants_set(p, i, d, p_start_i); } +PID::Constants Drive::pid_heading_constants_get() { + return headingPID.constants_get(); +} + // Updates max speed void Drive::pid_speed_max_set(int speed) { max_speed = util::clamp(abs(speed), 127, -127); } +int Drive::pid_speed_max_get() { + return max_speed; +} + void Drive::pid_targets_reset() { headingPID.target_set(0); leftPID.target_set(0); @@ -46,7 +80,7 @@ void Drive::pid_targets_reset() { turnPID.target_set(0); } -void Drive::set_angle(okapi::QAngle p_angle) { +void Drive::drive_angle_set(okapi::QAngle p_angle) { double angle = p_angle.convert(okapi::degree); // Convert okapi unit to degree headingPID.target_set(angle); @@ -54,15 +88,14 @@ void Drive::set_angle(okapi::QAngle p_angle) { } void Drive::drive_mode_set(e_mode p_mode) { mode = p_mode; } +e_mode Drive::drive_mode_get() { return mode; } void Drive::pid_turn_min_set(int min) { turn_min = abs(min); } -int Drive::get_turn_min() { return turn_min; } +int Drive::pid_turn_min_get() { return turn_min; } void Drive::pid_swing_min_set(int min) { swing_min = abs(min); } int Drive::pid_swing_min_get() { return swing_min; } -e_mode Drive::drive_mode_get() { return mode; } - // Set drive PID void Drive::pid_drive_set(okapi::QLength p_target, int speed, bool slew_on, bool toggle_heading) { double target = p_target.convert(okapi::inch); // Convert okapi unit to inches diff --git a/src/EZ-Template/drive/user_input.cpp b/src/EZ-Template/drive/user_input.cpp index 7cd18456..090c6c65 100644 --- a/src/EZ-Template/drive/user_input.cpp +++ b/src/EZ-Template/drive/user_input.cpp @@ -15,6 +15,10 @@ void Drive::opcontrol_curve_default_set(double left, double right) { save_r_curve_sd(); } +std::vector Drive::opcontrol_curve_default_get() { + return {left_curve_scale, right_curve_scale}; +} + // Initialize curve SD card void Drive::opcontrol_curve_sd_initialize() { // If no SD card, return @@ -73,15 +77,23 @@ void Drive::save_r_curve_sd() { fclose(usd_file_write); } -void Drive::opcontrol_curve_buttons_left(pros::controller_digital_e_t decrease, pros::controller_digital_e_t increase) { +void Drive::opcontrol_curve_buttons_left_set(pros::controller_digital_e_t decrease, pros::controller_digital_e_t increase) { l_increase_.button = increase; l_decrease_.button = decrease; } -void Drive::opcontrol_curve_buttons_right(pros::controller_digital_e_t decrease, pros::controller_digital_e_t increase) { +void Drive::opcontrol_curve_buttons_right_set(pros::controller_digital_e_t decrease, pros::controller_digital_e_t increase) { r_increase_.button = increase; r_decrease_.button = decrease; } +std::vector Drive::opcontrol_curve_buttons_left_get() { + return {l_decrease_.button, r_decrease_.button}; +} + +std::vector Drive::opcontrol_curve_buttons_right_get() { + return {r_decrease_.button, r_decrease_.button}; +} + // Increase / decrease left and right curves void Drive::l_increase() { left_curve_scale += 0.1; } void Drive::l_decrease() { @@ -134,6 +146,7 @@ void Drive::button_press(button_* input_name, int button, std::function // Toggle modifying curves with controller void Drive::opcontrol_curve_buttons_toggle(bool toggle) { disable_controller = toggle; } +bool Drive::opcontrol_curve_buttons_toggle_get() { return disable_controller; } // Modify curves with button presses and display them to contrller void Drive::opcontrol_curve_buttons_iterate() { @@ -182,8 +195,14 @@ void Drive::opcontrol_drive_activebrake_set(double kp) { drive_sensor_reset(); } +// Get active brake constant +double Drive::opcontrol_drive_activebrake_get() { + return active_brake_kp; +} + // Set joystick threshold -void Drive::opcontrol_joystick_threshold(int threshold) { JOYSTICK_THRESHOLD = abs(threshold); } +void Drive::opcontrol_joystick_threshold_set(int threshold) { JOYSTICK_THRESHOLD = abs(threshold); } +int Drive::opcontrol_joystick_threshold_get() { return JOYSTICK_THRESHOLD; } void Drive::opcontrol_drive_sensors_reset() { if (util::AUTON_RAN) { @@ -193,6 +212,7 @@ void Drive::opcontrol_drive_sensors_reset() { } void Drive::opcontrol_joystick_practicemode_toggle(bool toggle) { practice_mode_is_on = toggle; } +bool Drive::opcontrol_joystick_practicemode_toggle_get() { return practice_mode_is_on; } void Drive::opcontrol_joystick_threshold_iterate(int l_stick, int r_stick) { // Check the motors are being set to power diff --git a/src/main.cpp b/src/main.cpp index 10dec47b..16389823 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -63,8 +63,8 @@ void initialize() { default_constants(); // Set the drive to your own constants from autons.cpp! // These are already defaulted to these buttons, but you can change the left/right curve buttons here! - // chassis.opcontrol_curve_buttons_left (pros::E_CONTROLLER_DIGITAL_LEFT, pros::E_CONTROLLER_DIGITAL_RIGHT); // If using tank, only the left side is used. - // chassis.opcontrol_curve_buttons_right(pros::E_CONTROLLER_DIGITAL_Y, pros::E_CONTROLLER_DIGITAL_A); + // chassis.opcontrol_curve_buttons_left_set (pros::E_CONTROLLER_DIGITAL_LEFT, pros::E_CONTROLLER_DIGITAL_RIGHT); // If using tank, only the left side is used. + // chassis.opcontrol_curve_buttons_right_set(pros::E_CONTROLLER_DIGITAL_Y, pros::E_CONTROLLER_DIGITAL_A); // Autonomous Selector using LLEMU ez::as::auton_selector.autons_add({