*Click to expand*
#include "vex.h"
#include "libraries/include.h"
using namespace vex;
using signature = vision::signature;
using code = vision::code;
brain Brain;
//? Other stuff
inertial Inertial(PORT1);
rotation AutonSelector(PORT12);
digital_out Claw(Brain.ThreeWirePort.A);
//? -----------
/* #region Controller Stuff */
controller ControllerPrimary(primary);
controller ControllerPartner(partner);
bool clawToggling = false;
bool hookToggling = false;
/* #endregion */
/* #region Drivetrain */
bool disableBrake = false;
motor RM1(PORT15, ratio6_1, false); // A
motor RM2(PORT16, ratio6_1, false); // B
motor RM3(PORT17, ratio6_1, false); // C
motor LM1(PORT18, ratio6_1, true); // D
motor LM2(PORT19, ratio6_1, true); // E
motor LM3(PORT20, ratio6_1, true); // F
motor_group RMG(RM1, RM2, RM3); // Right motor group
motor_group LMG(LM1, LM2, LM3); // Left motor group
smartdrive Drivetrain(LMG, RMG, Inertial, 12.59, 12.5, 10, distanceUnits::in, -0.4375);
/* #endregion */
/* #region Drive Controllers */
controller* DriveController = &ControllerPrimary;
controller* NonDriveController = &ControllerPartner;
double driveMultiplier = 50;
double driveMultiplierDecimal = driveMultiplier/100;
double driveAxis3 = 0; // Forward and backward
double driveAxis1 = 0; // Left and right
/* #endregion */
/* #region Intake */
motor Intake(PORT11, ratio18_1, true);
// For switching intake prority
controller* MainIntakeController = &ControllerPartner;
controller* SecondaryIntakeController = &ControllerPrimary;
double mainIntakeAxis2 = 0;
double secondaryIntakeAxis2 = 0;
/* #endregion */
/* #region Hook */
motor Hook(PORT2, ratio36_1, false);
PIDController hookPID(0.6, 0, 0);
double hookPID_dt = 0.1;
double hookDown = 136;
double hookUp = 30;
double hookMid = 70;
double hookTarget = hookUp;
bool doResetHook = false;
bool resetStarted = false;
/* #endregion */
void vexcodeInit( void ) {
Inertial.startCalibration(3000);
while (Inertial.isCalibrating())
{
wait(10, msec);
}
}
*Click to expand*
#include "vex.h"
#include "include.h"
#include <iostream>
#include <map>
using namespace vex;
competition Competition;
int autonMode = 0;
void pre_auton(void) {
double autonPosition = AutonSelector.angle(deg);
autonPosition = 360 - autonPosition;
autonMode = ceil(autonPosition / 60 - 0.5) + 1;
autonMode = autonMode == 7 ? 1 : autonMode;
std::cout << "Auton Mode Selected: " <<to_string(autonMode) << std::endl;
}
void autonomous(void) {
pre_auton();
disableBrake = true;
switch (autonMode) {
case 1:
auton1();
break;
case 2:
auton2();
break;
case 3:
auton3();
break;
case 4:
auton4();
break;
case 5:
auton5();
break;
case 6:
auton6();
break;
}
disableBrake = false;
}
void usercontrol(void) {
disableBrake = false;
task controllerHandlerTask(controllerHandlerFunction);
while (1) {
this_thread::sleep_for(10);
}
}
int main() {
vexcodeInit();
Competition.autonomous(autonomous);
Competition.drivercontrol(usercontrol);
pre_auton();
while (true) {
this_thread::sleep_for(20);
}
}
*Click to expand*
#include "vex.h"
#include "robot-config.h"
#include "include.h"
int controllerHandlerFunction( void ) {
doResetHook = true;
while(1) {
controllerDriveControlCheck();
controllerDrive();
intakeControl();
hookControl();
if (MainIntakeController->ButtonX.pressing() ||
SecondaryIntakeController->ButtonX.pressing()) {
if (!clawToggling) {
clawToggling = true;
Claw.set(!Claw.value());
}
} else clawToggling = false;
if (ControllerPrimary.ButtonDown.pressing() ||
ControllerPartner.ButtonDown.pressing()) {
if (!hookToggling) {
hookToggling = true;
hookTarget = hookUp;
}
} else hookToggling = false;
if (ControllerPrimary.ButtonUp.pressing() ||
ControllerPartner.ButtonUp.pressing()) {
if (!hookToggling) {
hookToggling = true;
hookTarget = hookDown;
}
} else hookToggling = false;
if (ControllerPrimary.ButtonRight.pressing() ||
ControllerPartner.ButtonRight.pressing()) {
if (!hookToggling) {
hookToggling = true;
hookTarget = hookMid;
}
} else hookToggling = false;
if (ControllerPrimary.ButtonY.pressing() ||
ControllerPartner.ButtonY.pressing()) {
alignToMogo();
}
this_thread::sleep_for(10);
}
}
void controllerDriveControlCheck( void ) {
if (ControllerPrimary.ButtonA.pressing() && DriveController != &ControllerPrimary) {
DriveController->rumble("-");
DriveController = &ControllerPrimary;
NonDriveController = &ControllerPartner;
}
else if (ControllerPartner.ButtonA.pressing() && DriveController != &ControllerPartner) {
DriveController->rumble("-");
DriveController = &ControllerPartner;
NonDriveController = &ControllerPrimary;
}
}
void controllerDrive( void ) {
// If the L1 button is pressed, set the drive multiplier to 100 otherwise set it to 50
DriveController->ButtonL1.pressing() ? driveMultiplier = 100 : driveMultiplier = 50;
// Convert the drive mutliplier decimal
driveMultiplierDecimal = driveMultiplier/100;
// Get the position for driving from the drive controller
driveAxis3 = DriveController->Axis3.position(pct);
driveAxis1 = DriveController->Axis1.position(pct);
// Deadband (Small values are ignored to prevent stick drift)
if (abs(driveAxis3) < 5) driveAxis3 = 0;
if (abs(driveAxis1) < 5) driveAxis1 = 0;
// Calculate the power for each side of the drivetrain
double leftPower = (driveAxis3 + driveAxis1);
double rightPower = (driveAxis3 - driveAxis1);
// Multiply the power by the drive mutliplier decimal
leftPower *= driveMultiplierDecimal;
rightPower *= driveMultiplierDecimal;
// Set the power for each side of the drivetrain
if (leftPower != 0 || rightPower != 0) {
RMG.spin(directionType::fwd, rightPower, velocityUnits::pct);
LMG.spin(directionType::fwd, leftPower, velocityUnits::pct);
} else {
if (!disableBrake) {
RMG.stop(brake);
LMG.stop(brake);
}
}
}
*Click to expand*
#include "vex.h"
#include "robot-config.h"
bool intakeControl_checkValues( controller* targetController ) {
bool targetControllerButtonL2Pressing = targetController->ButtonL2.pressing();
bool targetControllerButtonR2Pressing = targetController->ButtonR2.pressing();
bool targetControllerButtonR1Pressing = targetController->ButtonR1.pressing();
double intakeAxis2 = targetController->Axis2.position(pct);
if (abs(intakeAxis2) < 5) intakeAxis2 = 0;
if (targetControllerButtonL2Pressing) {
Intake.spin(directionType::rev, -intakeAxis2, velocityUnits::pct);
} else {
if (targetControllerButtonR1Pressing || targetControllerButtonR2Pressing) {
directionType intakeDirection = directionType::fwd;
if (targetControllerButtonR1Pressing) intakeDirection = directionType::fwd;
if (targetControllerButtonR2Pressing) intakeDirection = directionType::rev;
Intake.spin(intakeDirection, 100, velocityUnits::pct);
} else {
Intake.stop();
}
}
if (targetControllerButtonR1Pressing ||
targetControllerButtonR2Pressing ||
intakeAxis2 != 0) {
return false;
} else {
return true;
}
}
void intakeControl( void ) {
bool allowSecondary = intakeControl_checkValues(MainIntakeController);
if (allowSecondary) {
intakeControl_checkValues(SecondaryIntakeController);
}
}
*Click to expand*
#include "vex.h"
#include "robot-config.h"
void resetHook( void ) {
if (doResetHook) {
Hook.spin(directionType::fwd, 60, velocityUnits::pct);
if (Hook.torque(torqueUnits::Nm) >= 0.5) {
resetStarted = true;
}
if (abs(Hook.velocity(velocityUnits::rpm)) <= 0 && resetStarted) {
Hook.setPosition(0, rotationUnits::deg);
Hook.stop(brake);
doResetHook = false;
resetStarted = false;
}
}
}
void hookControl( void ) {
resetHook();
if (doResetHook) return;
double control = hookPID.calculate(hookTarget, -Hook.position(deg), hookPID_dt);
control = abs(control) < 1 ? 0 : control;
Hook.spin(directionType::rev, control, velocityUnits::pct);
}
*Click to expand*
#include "vex.h"
#include "robot-config.h"
#include "libraries/pid.h"
using namespace vex;
using signature = vision::signature;
using code = vision::code;
/* #region Vision Sensor */
signature VisionSensor__BLUE_DONUT(1, -3699, -3339, -3518, 8013, 8787, 8400, 3.9, 0);
signature VisionSensor__RED_DONUT(2, 10309, 11361, 10836, -1321, -767, -1044, 2, 0);
signature VisionSensor__MOBILE_GOAL(3, -49, 49, 0, -4033, -3635, -3834, 7.5, 0);
vision VisionSensor(PORT3, 50, VisionSensor__BLUE_DONUT, VisionSensor__RED_DONUT, VisionSensor__MOBILE_GOAL);
PIDController alignPID(0.2, 0, 0);
double alignPID_dt = 0.1;
/* #endregion */
void alignToMogo( void ) {
VisionSensor.takeSnapshot(3);
if (VisionSensor.largestObject.exists) {
double measuredValue = 157.5 - VisionSensor.largestObject.centerX;
double control = alignPID.calculate(157.5, measuredValue, alignPID_dt);
LMG.spin(directionType::fwd, control, velocityUnits::pct);
RMG.spin(directionType::rev, control, velocityUnits::pct);
}
}
*Click to expand*
#include "vex.h"
#include "robot-config.h"
#include "controllers/include.h"
#include "libraries/include.h"
void auton1( void ) {
Drivetrain.driveFor( directionType::rev, 18, distanceUnits::in );
toggleAlignToMogo();
Drivetrain.driveFor( directionType::rev, 17, distanceUnits::in );
toggleClaw(true);
Drivetrain.driveFor( directionType::fwd, 17, distanceUnits::in );
Drivetrain.turnToHeading( 245, rotationUnits::deg );
Intake.spin( directionType::fwd, 100, velocityUnits::pct );
Drivetrain.driveFor( directionType::fwd, 28, distanceUnits::in, 50, velocityUnits::pct );
Drivetrain.turnToHeading( 115, rotationUnits::deg );
Intake.spin( directionType::rev, 100, velocityUnits::pct );
Drivetrain.driveFor( directionType::fwd, 28, distanceUnits::in, 30, velocityUnits::pct );
Drivetrain.turnFor(turnType::right, 30, rotationUnits::deg);
Drivetrain.driveFor( directionType::fwd, 3, distanceUnits::in );
}
*Click to expand*
#pragma once
#include "lemlib/chassis/chassis.hpp"
#include "lemlib/pose.hpp"
namespace lemlib {
/**
* @brief Set the sensors to be used for odometry
*
* @param sensors the sensors to be used
* @param drivetrain drivetrain to be used
*/
void setSensors(lemlib::OdomSensors sensors, lemlib::Drivetrain drivetrain);
/**
* @brief Get the pose of the robot
*
* @param radians true for theta in radians, false for degrees. False by default
* @return Pose
*/
Pose getPose(bool radians = false);
/**
* @brief Set the Pose of the robot
*
* @param pose the new pose
* @param radians true if theta is in radians, false if in degrees. False by default
*/
void setPose(Pose pose, bool radians = false);
/**
* @brief Get the speed of the robot
*
* @param radians true for theta in radians, false for degrees. False by default
* @return lemlib::Pose
*/
Pose getSpeed(bool radians = false);
/**
* @brief Get the local speed of the robot
*
* @param radians true for theta in radians, false for degrees. False by default
* @return lemlib::Pose
*/
Pose getLocalSpeed(bool radians = false);
/**
* @brief Estimate the pose of the robot after a certain amount of time
*
* @param time time in seconds
* @param radians False for degrees, true for radians. False by default
* @return lemlib::Pose
*/
Pose estimatePose(float time, bool radians = false);
/**
* @brief Update the pose of the robot
*
*/
void update();
/**
* @brief Initialize the odometry system
*
*/
void init();
} // namespace lemlib
*Click to expand*
#include "classes/clamp.h"
Clamp::Clamp(ControllerPair* pair)
: piston(CLAMP_PORT, E_ADI_DIGITAL_OUT),
distanceSensor(CLAMP_DISTANCE_PORT),
pair(pair)
{
}
void Clamp::toggle( bool override )
{
bool clampState = piston.get_value();
double mogoDistance = distanceSensor.get();
if (!clampState && (mogoDistance < 70 || override)) {
piston.set_value(true);
} else {
piston.set_value(false);
}
}
void Clamp::set(bool state)
{
piston.set_value(state);
}
void Clamp::loop() {
if (pair->driver->btnX.isPressed_new()) {
toggle();
} else if (pair->support->btnX.isPressed_new()) {
toggle();
}
if (autoClampEnabled) {
if (distanceSensor.get() < 70) {
set(true);
autoClampEnabled = false;
}
}
}
Clamp::~Clamp()
{
}
*Click to expand*
#pragma once
#include "classes/controllerSolo.h"
#include "main.h"
class ControllerPair {
public:
ControllerSolo* master;
ControllerSolo* partner;
ControllerSolo* driver;
ControllerSolo* support;
ControllerPair(ControllerSolo* masterController, ControllerSolo* partnerController)
: master(masterController),
partner(partnerController),
driver(masterController),
support(partnerController) {
}
void setDriver(ControllerSolo* newDriver) {
if (newDriver == driver) return;
ControllerSolo* temp = driver;
driver = newDriver;
support = temp;
}
void checkForSwitch() {
if (master->btnA.isPressed()) {
setDriver(master);
} else if (partner->btnA.isPressed()) {
setDriver(partner);
}
}
void loop() {
master->buttonLoop();
partner->buttonLoop();
checkForSwitch();
}
};
*Click to expand*
#include "classes/intake.h"
Intake::Intake(ControllerPair* pair)
: motor(INTAKE_MOTOR_PORT, v5::MotorGear::blue),
piston(INTAKE_RISER_PORT, E_ADI_DIGITAL_OUT),
pair(pair) {
}
bool Intake::checkForInput(ControllerSolo* controller) {
if (controller->btnR1.isPressed()) {
motor.move(127);
return true;
} else if (controller->btnR2.isPressed()) {
motor.move(-127);
return true;
}
return false;
}
void Intake::handleMotor() {
if (checkForInput(pair->driver)) return;
if (checkForInput(pair->support)) return;
if (motor.get_voltage() != 0) motor.move(0);
}
void Intake::toggleRiser() {
piston.set_value(!piston.get_value());
}
void Intake::handleRiser() {
if (pair->master->btnLeft.isPressed_new()) toggleRiser();
else if (pair->partner->btnLeft.isPressed_new()) toggleRiser();
}
void Intake::loop() {
handleMotor();
handleRiser();
}
*Click to expand*
#pragma once
// #include "main.h"
#include "liblvgl/lvgl.h"
#include "other/fieldImg.h"
#include <string>
#include "classes/screen/tabs.h"
#include "classes/autonomous/main.h"
class Autonomous {
public:
Autonomous(lv_obj_t *parent, AutonomousRoutines* autonRoutines);
lv_obj_t *optionsLabel;
// 0 is no auton, 1 is blue negative, 2 is blue positive, 3 is red positive, 4
// is red negative
int8_t auton_selection = 0;
const char* routine_selection = "No Auton";
private:
AutonomousRoutines* autonRoutines;
lv_obj_t *btn_matrix;
static void staticSelectAuton(lv_event_t *e) {
Autonomous *instance = (Autonomous *)lv_event_get_user_data(e);
instance->selectAuton(e);
};
static void staticSelectAutonRoutine(lv_event_t *e) {
Autonomous *instance = (Autonomous *)lv_event_get_user_data(e);
instance->selectAutonRoutine();
};
void selectAuton(lv_event_t *e);
void selectAutonRoutine(int16_t check_id = -1);
void setBtnMatrix(const char **map, size_t size);
};
void Autonomous::selectAuton(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
if (code == LV_EVENT_CLICKED) {
lv_obj_t *obj = lv_event_get_target(e);
lv_obj_t *label = lv_obj_get_child(obj, 0);
bool is_positive = std::string(lv_label_get_text(label)) == "+";
lv_color32_t color = lv_obj_get_style_bg_color(obj, 0);
uint32_t raw_color = color.full;
if (raw_color == lv_color_make(255, 0, 0).full) {
if (is_positive) {
// Red Positive
auton_selection = 3;
setBtnMatrix((const char **)autonRoutines->redplus.routines,
autonRoutines->redplus.routinesSize);
lv_label_set_text(optionsLabel, "Red Positive (3)");
} else {
// Red Negative
auton_selection = 4;
setBtnMatrix((const char **)autonRoutines->redminus.routines,
autonRoutines->redminus.routinesSize);
lv_label_set_text(optionsLabel, "Red Negative (4)");
}
} else if (raw_color == lv_color_make(0, 119, 200).full) {
if (is_positive) {
// Blue Positive
auton_selection = 2;
setBtnMatrix((const char **)autonRoutines->blueplus.routines,
autonRoutines->blueplus.routinesSize);
lv_label_set_text(optionsLabel, "Blue Positive (2)");
} else {
// Blue Negative
auton_selection = 1;
setBtnMatrix((const char **)autonRoutines->blueminus.routines,
autonRoutines->blueminus.routinesSize);
lv_label_set_text(optionsLabel, "Blue Negative (1)");
}
} else if (raw_color == lv_color_make(100, 100, 100).full) {
// No Auton
auton_selection = 0;
static constexpr const char* noAutonMap[] = {"No Auton", ""};
setBtnMatrix((const char **)noAutonMap, sizeof(noAutonMap) / sizeof(noAutonMap[0]));
lv_label_set_text(optionsLabel, "No Auton (0)");
}
}
}
Autonomous::Autonomous(lv_obj_t *parent, AutonomousRoutines* autonRoutines)
: autonRoutines(autonRoutines) {
lv_obj_t *fieldContainer = lv_obj_create(parent);
lv_obj_set_size(fieldContainer, 240, 240);
lv_obj_set_style_pad_all(fieldContainer, 0, 0);
lv_obj_clear_flag(fieldContainer, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t *fieldImg = lv_img_create(fieldContainer);
lv_img_set_src(fieldImg, &field_image);
lv_obj_align(fieldImg, LV_ALIGN_TOP_LEFT, 0, 0);
/* #region Auton Buttons */
lv_obj_t *redPlus = lv_btn_create(fieldContainer);
lv_obj_set_size(redPlus, 25, 25);
lv_obj_align(redPlus, LV_ALIGN_TOP_LEFT, 20, 20);
lv_obj_set_style_bg_color(redPlus, lv_color_make(255, 0, 0), 0);
lv_obj_add_event_cb(redPlus, staticSelectAuton, LV_EVENT_CLICKED, this);
lv_obj_t *redPlusLabel = lv_label_create(redPlus);
lv_obj_set_style_text_font(redPlusLabel, &lv_font_montserrat_24, 0);
lv_label_set_text(redPlusLabel, "+");
lv_obj_center(redPlusLabel);
lv_obj_t *redMinus = lv_btn_create(fieldContainer);
lv_obj_set_size(redMinus, 25, 25);
lv_obj_align(redMinus, LV_ALIGN_TOP_RIGHT, -20, 20);
lv_obj_set_style_bg_color(redMinus, lv_color_make(255, 0, 0), 0);
lv_obj_add_event_cb(redMinus, staticSelectAuton, LV_EVENT_CLICKED, this);
lv_obj_t *redMinusLabel = lv_label_create(redMinus);
lv_obj_set_style_text_font(redMinusLabel, &lv_font_montserrat_24, 0);
lv_label_set_text(redMinusLabel, "-");
lv_obj_center(redMinusLabel);
lv_obj_t *bluePlus = lv_btn_create(fieldContainer);
lv_obj_set_size(bluePlus, 25, 25);
lv_obj_align(bluePlus, LV_ALIGN_BOTTOM_LEFT, 20, -20);
lv_obj_set_style_bg_color(bluePlus, lv_color_make(0, 119, 200), 0);
lv_obj_add_event_cb(bluePlus, staticSelectAuton, LV_EVENT_CLICKED, this);
lv_obj_t *bluePlusLabel = lv_label_create(bluePlus);
lv_obj_set_style_text_font(bluePlusLabel, &lv_font_montserrat_24, 0);
lv_label_set_text(bluePlusLabel, "+");
lv_obj_center(bluePlusLabel);
lv_obj_t *blueMinus = lv_btn_create(fieldContainer);
lv_obj_set_size(blueMinus, 25, 25);
lv_obj_align(blueMinus, LV_ALIGN_BOTTOM_RIGHT, -20, -20);
lv_obj_set_style_bg_color(blueMinus, lv_color_make(0, 119, 200), 0);
lv_obj_add_event_cb(blueMinus, staticSelectAuton, LV_EVENT_CLICKED, this);
lv_obj_t *blueMinusLabel = lv_label_create(blueMinus);
lv_obj_set_style_text_font(blueMinusLabel, &lv_font_montserrat_24, 0);
lv_label_set_text(blueMinusLabel, "-");
lv_obj_center(blueMinusLabel);
lv_obj_t *noAuton = lv_btn_create(fieldContainer);
lv_obj_set_size(noAuton, 25, 25);
lv_obj_align(noAuton, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_style_bg_color(noAuton, lv_color_make(100, 100, 100), 0);
lv_obj_add_event_cb(noAuton, staticSelectAuton, LV_EVENT_CLICKED, this);
lv_obj_t *noAutonLabel = lv_label_create(noAuton);
lv_obj_set_style_text_font(noAutonLabel, &lv_font_montserrat_24, 0);
lv_label_set_text(noAutonLabel, "X");
lv_obj_center(noAutonLabel);
/* #endregion */
lv_obj_t *optionsContainer = lv_obj_create(parent);
lv_obj_set_size(optionsContainer, 240 - 35, 240);
lv_obj_align(optionsContainer, LV_ALIGN_TOP_RIGHT, 0, 0);
optionsLabel = lv_label_create(optionsContainer);
lv_obj_set_style_text_font(optionsLabel, &lv_font_montserrat_16, 0);
lv_label_set_text(optionsLabel, "No Auton (0)");
lv_obj_set_style_border_side(optionsLabel, LV_BORDER_SIDE_BOTTOM, 0);
lv_obj_set_style_border_width(optionsLabel, 3, 0);
lv_obj_set_style_border_color(optionsLabel,
lv_palette_main(LV_PALETTE_GREEN), 0);
lv_obj_align(optionsLabel, LV_ALIGN_TOP_MID, 0, 0);
/* #region Options Btn Matrix */
static lv_style_t style_bg;
lv_style_init(&style_bg);
lv_style_set_pad_all(&style_bg, 0);
lv_style_set_pad_gap(&style_bg, 5);
lv_style_set_clip_corner(&style_bg, true);
lv_style_set_radius(&style_bg, 0);
lv_style_set_border_width(&style_bg, 0);
static lv_style_t style_btn;
lv_style_init(&style_btn);
lv_style_set_radius(&style_btn, 0);
lv_style_set_border_width(&style_btn, 3);
lv_style_set_border_opa(&style_btn, LV_OPA_50);
lv_style_set_border_color(&style_btn, lv_palette_main(LV_PALETTE_GREY));
lv_style_set_radius(&style_btn, LV_RADIUS_CIRCLE);
static constexpr const char* map[] = {"No Autons", ""};
btn_matrix = lv_btnmatrix_create(optionsContainer);
lv_obj_add_style(btn_matrix, &style_bg, 0);
lv_obj_add_style(btn_matrix, &style_btn, LV_PART_ITEMS);
lv_obj_add_event_cb(btn_matrix, staticSelectAutonRoutine, LV_EVENT_VALUE_CHANGED, this);
lv_obj_align(btn_matrix, LV_ALIGN_TOP_MID, 0, 35);
setBtnMatrix((const char **)map, sizeof(map) / sizeof(map[0]));
/* #endregion */
}
void Autonomous::setBtnMatrix(const char **map, size_t size) {
lv_btnmatrix_set_map(btn_matrix, map);
lv_obj_set_size(btn_matrix, 240 - 35 - 40, size * 20);
lv_btnmatrix_set_btn_ctrl_all(btn_matrix, LV_BTNMATRIX_CTRL_CHECKABLE);
lv_btnmatrix_set_one_checked(btn_matrix, true);
lv_btnmatrix_set_btn_ctrl(btn_matrix, 0, LV_BTNMATRIX_CTRL_CHECKED);
selectAutonRoutine(0);
}
void Autonomous::selectAutonRoutine(int16_t check_id) {
if (check_id == -1) {
check_id = lv_btnmatrix_get_selected_btn(btn_matrix);
}
const char* routineName = lv_btnmatrix_get_btn_text(btn_matrix, check_id);
routine_selection = routineName;
autonRoutines->autonSelection = auton_selection;
autonRoutines->subAuton = routineName;
}
*Click to expand*
#include "classes/doinker.h"
Doinker::Doinker(ControllerPair* pair)
: motor(DOINKER_MOTOR_PORT, v5::MotorGear::red),
pair(pair),
pid(HOOK_KP, HOOK_KI, HOOK_KD) {
motor.set_encoder_units(v5::MotorEncoderUnits::degrees);
}
void Doinker::resetLoop() {
if (isResetting) {
motor.move_velocity(40);
if (motor.get_torque() >= 0.05) {
resetStarted = true;
}
if (std::fabs(motor.get_actual_velocity()) <= 0 && resetStarted) {
motor.tare_position();
motor.move(0);
isResetting = false;
resetStarted = false;
}
}
}
void Doinker::reset() {
isResetting = true;
}
void Doinker::controlCheck(ControllerSolo* controller) {
if (controller->btnUp.isPressed_new()) {
target = HOOK_DOWN;
} else if (controller->btnRight.isReleased_new()) {
target = HOOK_MID;
} else if (controller->btnDown.isPressed_new()) {
target = HOOK_UP;
}
}
void Doinker::loop() {
resetLoop();
if (!isResetting) {
double control = pid.calculate(target, -motor.get_position(), HOOK_DT);
control = std::fabs(control) < 1 ? 0 : control;
motor.move_velocity(-control);
}
controlCheck(pair->driver);
controlCheck(pair->partner);
}
*Click to expand*
#include "main.h"
#include "lemlib/api.hpp"
#include "liblvgl/lvgl.h"
#include "pros/apix.h"
#include "fieldUtils.h"
// #include "logo.h"
#include "classes/include.h"
ControllerSolo master(E_CONTROLLER_MASTER);
ControllerSolo partner(E_CONTROLLER_PARTNER);
ControllerPair pair(&master, &partner);
DriveBase drivebase;
Clamp clamp(&pair);
Intake intake(&pair);
Doinker doinker(&pair);
BumperSwitch odomReset('H');
// ASSET(test_txt);
AutonomousRoutines autonomousRoutines(
&drivebase,
&intake,
&clamp,
&doinker
);
Screen screenClass(&autonomousRoutines, &drivebase);
static bool isAuton = false;
void initialize() {
lv_init();
lv_theme_default_init(
NULL,
lv_palette_main(LV_PALETTE_GREEN),
lv_palette_main(LV_PALETTE_GREY),
true,
LV_FONT_DEFAULT
);
drivebase.chassis.calibrate();
doinker.reset();
// Create a task for updating sensor data
Task screen_task([&]() {
static lv_obj_t* text_x = lv_label_create(screenClass.tabs.odometryTab);
static lv_obj_t* text_y = lv_label_create(screenClass.tabs.odometryTab);
static lv_obj_t* text_theta = lv_label_create(screenClass.tabs.odometryTab);
// Position them once
lv_obj_align(text_x, LV_ALIGN_TOP_LEFT, 10, 10);
lv_obj_align(text_y, LV_ALIGN_TOP_LEFT, 10, 30);
lv_obj_align(text_theta, LV_ALIGN_TOP_LEFT, 10, 50);
while (true) {
//TODO: Disable some of this during autonomous
pair.loop();
clamp.loop();
if (!isAuton) intake.loop();
doinker.loop();
screenClass.motors.loop();
if (odomReset.pressed()) {
printf("Resetting Odom to Auton Start\n");
autonomousRoutines.runAuton(true);
}
// lv_task_handler();
// Only update text content
char buf[32];
sprintf(buf, "X: %.2f", drivebase.chassis.getPose().x);
lv_label_set_text(text_x, buf);
sprintf(buf, "Y: %.2f", drivebase.chassis.getPose().y);
lv_label_set_text(text_y, buf);
sprintf(buf, "Theta: %.2f", drivebase.chassis.getPose().theta);
lv_label_set_text(text_theta, buf);
delay(20);
}
// Create text objects once
// static lv_obj_t* text_x = lv_label_create(lv_scr_act());
// static lv_obj_t* text_y = lv_label_create(lv_scr_act());
// static lv_obj_t* text_theta = lv_label_create(lv_scr_act());
// // Position them once
// lv_obj_align(text_x, LV_ALIGN_TOP_LEFT, 10, 10);
// lv_obj_align(text_y, LV_ALIGN_TOP_LEFT, 10, 30);
// lv_obj_align(text_theta, LV_ALIGN_TOP_LEFT, 10, 50);
// while (true) {
// lv_task_handler();
// // Only update text content
// char buf[32];
// sprintf(buf, "X: %.2f", drivebase.chassis.getPose().x);
// lv_label_set_text(text_x, buf);
// sprintf(buf, "Y: %.2f", drivebase.chassis.getPose().y);
// lv_label_set_text(text_y, buf);
// sprintf(buf, "Theta: %.2f", drivebase.chassis.getPose().theta);
// lv_label_set_text(text_theta, buf);
// delay(50);
// }
});
}
void disabled() {}
void competition_initialize() {}
void autonomous() {
isAuton = true;
lv_tabview_set_act(screenClass.tabs.tabview, 4, LV_ANIM_OFF);
autonomousRoutines.runAuton();
// drivebase.chassis.setPose(-23, 47, 90);
// drivebase.chassis.follow(test_txt, 15, 200*1000);
}
void opcontrol() {
isAuton = false;
while (true) {
int dir = pair.driver->get_analog(ANALOG_LEFT_Y);
int turn = pair.driver->get_analog(ANALOG_RIGHT_X);
drivebase.chassis.arcade(dir, turn);
if (pair.driver->btnY.isPressed_new()) clamp.autoClampEnabled = true;
if (pair.support->btnY.isPressed_new()) clamp.autoClampEnabled = true;
// pair.driver->print(0, 0, "Quad: %i", getQuadrant(drivebase.chassis.getPose()));
delay(20);
}
}
*Click to expand*
horizontal_tracking_wheel(&horizontal_encoder, lemlib::Omniwheel::NEW_275, 3.25),
vertical_tracking_wheel(&vertical_encoder, lemlib::Omniwheel::NEW_275, 1.5),
lateral_controller(10, 0, 3, 3, 1, 100, 3, 500, 20),
angular_controller(2, 0, 10, 3, 1, 100, 3, 500, 0),
*Click to expand*
horizontal_tracking_wheel(&horizontal_encoder,
lemlib::Omniwheel::NEW_275, 3.25),
vertical_tracking_wheel(&vertical_encoder,
lemlib::Omniwheel::NEW_275, -1.5),
lateral_controller(10, 0, 3, 6,
0.7, 100,
1.5, 500, 0),
angular_controller(2, 0, 10, 0.5,
1, 100,
3, 500, 0),
*Click to expand*
#include "classes/driveBase.h"
DriveBase::DriveBase() :
left_mg({-18, -19, -20}, v5::MotorGear::blue),
right_mg({15, 16, 17}, v5::MotorGear::blue),
drivetrain(&left_mg, &right_mg, 12.5,
lemlib::Omniwheel::OLD_4, 262.5, 0),
imu(1),
horizontal_encoder(-10),
vertical_encoder(13),
horizontal_tracking_wheel(&horizontal_encoder,
lemlib::Omniwheel::NEW_275, 3.25),
vertical_tracking_wheel(&vertical_encoder,
lemlib::Omniwheel::NEW_275, -1.5),
lateral_controller(10, 0, 1, 0,
0.7, 100,
1.3, 400, 20),
angular_controller(10, 0, 5, 0,
0.7, 100,
1.3, 500, 0),
chassis(drivetrain, lateral_controller, angular_controller,
lemlib::OdomSensors(&vertical_tracking_wheel, nullptr,
&horizontal_tracking_wheel, nullptr, &imu))
{
left_mg.set_brake_mode(v5::MotorBrake::brake);
right_mg.set_brake_mode(v5::MotorBrake::brake);
}
void DriveBase::loop() {
}
*Click to expand*
#include "classes/ladybrown.h"
#include "pros/abstract_motor.hpp"
#include <cstdio>
LadyBrown::LadyBrown(ControllerPair* pair)
: motor(LADYBROWN_MOTOR_PORT, v5::MotorGear::green),
rotation(LADYBROWN_ROTATION_PORT),
pair(pair),
pid(HOOK_KP, HOOK_KI, HOOK_KD) {
motor.set_encoder_units(v5::MotorEncoderUnits::degrees);
}
// void LadyBrown::resetLoop() {
// if (isResetting) {
// motor.move_velocity(40);
// if (motor.get_torque() >= 0.05) {
// resetStarted = true;
// }
// if (std::fabs(motor.get_actual_velocity()) <= 0 && resetStarted) {
// motor.tare_position();
// motor.move(0);
// isResetting = false;
// resetStarted = false;
// }
// }
// }
// void LadyBrown::reset() {
// isResetting = true;
// }
void LadyBrown::controlCheck(ControllerSolo* controller) {
if (controller->btnUp.isPressed_new()) {
target = HOOK_UP;
} else if (controller->btnRight.isReleased_new()) {
target = HOOK_MID;
} else if (controller->btnDown.isPressed_new()) {
target = HOOK_DOWN;
}
}
void LadyBrown::loop() {
// resetLoop();
if (!isResetting) {
double control = pid.calculate(target, rotation.get_angle(), HOOK_DT);
control = std::fabs(control) < 1 ? 0 : control;
motor.move_velocity(-control);
}
controlCheck(pair->driver);
// controlCheck(pair->support);
}
*Click to expand*
#include "classes/intake.h"
#include "pros/abstract_motor.hpp"
#include "pros/rtos.h"
#include <cstdint>
#include <cstdio>
#include <ratio>
Intake::Intake(ControllerPair* pair)
: motor(INTAKE_MOTOR_PORT, v5::MotorGear::green),
// piston(INTAKE_RISER_PORT, E_ADI_DIGITAL_OUT),
optical(INTAKE_OPTICAL_PORT),
state(MANUAL),
colorSort(NONE),
sortState(IDLE),
pair(pair) {
motor.set_encoder_units_all(MotorEncoderUnits::degrees);
}
bool Intake::checkForInput(ControllerSolo* controller) {
if (controller->btnR1.isDoublePress()) {state = AUTO_IN; return true;}
if (controller->btnR2.isDoublePress()) {state = AUTO_OUT; return true;}
if (state != MANUAL) {
if (controller->btnR1.isPressed_new() || controller->btnR2.isPressed_new()) {state = MANUAL; return true;}
} else {
if (controller->btnR1.isPressed()) {
motor.move(127);
return true;
} else if (controller->btnR2.isPressed()) {
motor.move(-127);
return true;
}
}
return false;
}
void Intake::handleMotor() {
bool input = checkForInput(pair->driver);
input = checkForInput(pair->support) ? true : input;
bool colorSorted = handleColorSort();
uint32_t current_time = pros::millis();
if (state == AUTO_IN) {
if (current_time > sortTime+330
&& current_time < sortTime+600) {
motor.move(-127);
sortState = SORTED;
} else {
if (sortState == SORTED
|| current_time > sortTime+2000) sortState = IDLE;
motor.move(127);
}
} else if (state == AUTO_OUT) {
motor.move(-127);
} else if (state == MANUAL && !input) {
motor.move(0);
}
// if (checkForInput(pair->support)) return;
// if (checkForInput(pair->driver)) return;
// if (motor.get_voltage() != 0) motor.move(0);
}
void Intake::checkForSortInput(ControllerSolo* controller) {
if (controller->btnUp.isPressed_new()) colorSort = RED;
else if (controller->btnRight.isPressed_new()) colorSort = NONE;
else if (controller->btnDown.isPressed_new()) colorSort = BLUE;
};
// void Intake::toggleRiser() {
// piston.set_value(!piston.get_value());
// }
// void Intake::handleRiser() {
// if (pair->master->btnLeft.isPressed_new()) toggleRiser();
// else if (pair->partner->btnLeft.isPressed_new()) toggleRiser();
// }
bool Intake::handleColorSort() {
if (state != MANUAL) {
optical.set_led_pwm(100);
uint32_t current_time = pros::millis();
double hue = optical.get_hue();
ColorSort found = NONE;
if (hue >= INTAKE_OPTICAL_RED_HUES[0]
&& hue <= INTAKE_OPTICAL_RED_HUES[1]) {
found = RED;
} else if (hue >= INTAKE_OPTICAL_RED_HUES[0]
&& hue <= INTAKE_OPTICAL_BLUE_HUES[1]) {
found = BLUE;
}
if ((colorSort == RED && found == RED)
|| (colorSort == BLUE && found == BLUE)
&& optical.get_proximity() > 150) {
if (sortState == IDLE) {
sortTime = current_time;
}
sortState = PRIMED;
return true;
}
else if (found == NONE) {
sortState = IDLE;
return false;
}
} else {
optical.set_led_pwm(0);
}
return false;
};
void Intake::loop() {
handleMotor();
checkForSortInput(pair->partner);
// handleRiser();
}
*Click to expand*
void myblockfunction_Set_right_side_vel_vel(double myblockfunction_Set_right_side_vel_vel__vel);
void myblockfunction_Set_left_side_vel_vel(double myblockfunction_Set_left_side_vel_vel__vel);
int AIVision_objectIndex = 0;
float myVariable, vel;
void myblockfunction_Set_right_side_vel_vel(double myblockfunction_Set_right_side_vel_vel__vel) {
Motor4.setVelocity(myblockfunction_Set_right_side_vel_vel__vel, percent);
Motor12.setVelocity(myblockfunction_Set_right_side_vel_vel__vel, percent);
Motor13.setVelocity(myblockfunction_Set_right_side_vel_vel__vel, percent);
if (myblockfunction_Set_right_side_vel_vel__vel == 0.0) {
Motor4.stop();
Motor12.stop();
Motor13.stop();
}
else {
Motor4.spin(forward);
Motor12.spin(forward);
Motor13.spin(forward);
}
}
void myblockfunction_Set_left_side_vel_vel(double myblockfunction_Set_left_side_vel_vel__vel) {
Motor16.setVelocity(myblockfunction_Set_left_side_vel_vel__vel, percent);
Motor17.setVelocity(myblockfunction_Set_left_side_vel_vel__vel, percent);
Motor18.setVelocity(myblockfunction_Set_left_side_vel_vel__vel, percent);
if (myblockfunction_Set_left_side_vel_vel__vel == 0.0) {
Motor16.stop();
Motor17.stop();
Motor18.stop();
}
else {
Motor16.spin(forward);
Motor17.spin(forward);
Motor18.spin(forward);
}
}
int whenStarted1() {
AIVision_objectIndex = static_cast<int>(1.0) - 1;
while (true) {
AIVision.takeSnapshot(AIVision__Mogo);
vel = (AIVision.objects[AIVision_objectIndex].centerX - 200.0) / 9.0;
if (vel > 10.0) {
vel = 10.0;
}
if (vel < -10.0) {
vel = -10.0;
}
if (AIVision.objects[AIVision_objectIndex].centerX - 200.0 < -40.0 && AIVision.objects[AIVision_objectIndex].centerX - 200.0 > 40.0) {
myblockfunction_Set_left_side_vel_vel(0.0);
myblockfunction_Set_right_side_vel_vel(0.0);
}
else {
if (AIVision.objects[AIVision_objectIndex].centerX - 200.0 < -100.0 && AIVision.objects[AIVision_objectIndex].centerX - 200.0 > 100.0) {
myblockfunction_Set_left_side_vel_vel(vel / 4.0);
myblockfunction_Set_right_side_vel_vel((vel * -1.0) / 4.0);
}
else {
myblockfunction_Set_left_side_vel_vel(vel);
myblockfunction_Set_right_side_vel_vel(vel * -1.0);
}
}
wait(5, msec);
}
return 0;
}
int main() {
vexcodeInit();
whenStarted1();
}