I should probably add some comments be here it is.
It ain’t the best or the tidiest code out there but this is my first go with the pros.
#include "main.h"
#include <cstdint>
#include <vector>
// Ports
#define Pimu 5
#define Pdrive_left_1 10
#define Pdrive_left_2 9
#define Pdrive_right_1 4
#define Pdrive_right_2 3
#define Pcatta_left 2
#define Pcatta_right 8
#define Pintake 1
#define Pwings 1 // A = 1 H = 8
// Light Strip Left
#define PexpandR 22 // 22 for built in
#define PlightR 7 // A = 1 H = 8
int length = 58; // Must be int to compaire with. Length of both strips because symetrical
// Light Strip Right
#define PexpandL 22 // 22 for built in
#define PlightL 8 // A = 1 H = 8
void PID(int target, bool left) // true if you want to go left
{
pros::Imu imu(Pimu);
pros::Motor drive_left1(Pdrive_left_1);
pros::Motor drive_left2(Pdrive_left_2);
pros::Motor drive_right1(Pdrive_right_1, true);
pros::Motor drive_right2(Pdrive_right_2, true);
imu.tare_rotation();
int kp = 2;
int ki = 8;
int kd = 27;
int max = 70;
int exit_ = 1;
int exit_time = 5; // times by time step
int travled = 0;
int output = 0;
int cycles = 0;
int error = 0;
int p = 0;
int i = 0;
int d = 0;
int error_ = 0; // Last error
while (true)
{
travled = abs(imu.get_rotation());
// Exit if exit condititons met
if (travled > (target - exit_) && travled < (target + exit_))
{
cycles++;
if (cycles == exit_time)
{
drive_left1 = 0;
drive_left2 = 0;
drive_right1 = 0;
drive_right2 = 0;
return; // exit pid
}
}
else
{
cycles = 0;
}
error = target - travled;
p = kp * error;
i = i + (ki * (error + error_));
// Intergral anti windup
if (i > max)
{
i = max;
}
else if (i < -max)
{
i = -max;
}
d = kd * (error - error_);
output = p + (i / 4) + d;
// limit max speed
if (output > max)
{
output = max;
}
else if (output < -max)
{
output = -max;
}
error_ = error; // store last error
if (left)
{
drive_left1 = -output;
drive_left2 = -output;
drive_right1 = output;
drive_right2 = output;
}
else
{
drive_left1 = output;
drive_left2 = output;
drive_right1 = -output;
drive_right2 = -output;
}
// printf("T:%d O:%d\n", travled, output); //Debug code
pros::delay(10);
}
}
void move(int distace, int speed)
{
pros::Motor drive_left1(Pdrive_left_1);
pros::Motor drive_left2(Pdrive_left_2);
pros::Motor drive_right1(Pdrive_right_1, true);
pros::Motor drive_right2(Pdrive_right_2, true);
drive_left1.move_relative(distace, speed);
drive_left2.move_relative(distace, speed);
drive_right1.move_relative(distace, speed);
drive_right2.move_relative(distace, speed);
pros::delay(100);
while (drive_left1.get_actual_velocity() != 0)
{
pros::delay(10);
}
drive_left1 = 0;
drive_left2 = 0;
drive_right1 = 0;
drive_right2 = 0;
}
/**
* Runs initialization code. This occurs as soon as the program is started.
*
* All other competition modes are blocked by initialize; it is recommended
* to keep execution time for this mode under a few seconds.
*/
void initialize()
{
// Reset IMU.
pros::Imu imu(Pimu);
imu.reset();
// Initialize sylib background processes
sylib::initialize();
}
/**
* Runs while the robot is in the disabled state of Field Management System or
* the VEX Competition Switch, following either autonomous or opcontrol. When
* the robot is enabled, this task will exit.
*/
void disabled() {}
/**
* Runs after initialize(), and before autonomous when connected to the Field
* Management System or the VEX Competition Switch. This is intended for
* competition-specific initialization routines, such as an autonomous selector
* on the LCD.
*
* This task will exit when the robot is enabled and autonomous or opcontrol
* starts.
*/
void competition_initialize() {}
/**
* Runs the user autonomous code. This function will be started in its own task
* with the default priority and stack size whenever the robot is enabled via
* the Field Management System or the VEX Competition Switch in the autonomous
* mode. Alternatively, this function may be called in initialize or opcontrol
* for non-competition testing purposes.
*
* If the robot is disabled or communications is lost, the autonomous task
* will be stopped. Re-enabling the robot will restart the task, not re-start it
* from where it left off.
*/
void autonomous()
{
pros::Motor drive_left1(Pdrive_left_1);
pros::Motor drive_left2(Pdrive_left_2);
pros::Motor drive_right1(Pdrive_right_1, true);
pros::Motor drive_right2(Pdrive_right_2, true);
pros::Motor intake(Pintake, true);
int speed = 170;
move(-3100, speed);
PID(90, true);
intake = -100;
pros::delay(900);
intake = 0;
drive_left1 = 100;
drive_left2 = 100;
drive_right1 = 100;
drive_right2 = 100;
pros::delay(700);
drive_left1 = 0;
drive_left2 = 0;
drive_right1 = 0;
drive_right2 = 0;
move(-800, speed);
PID(90, false);
move(1100, speed);
PID(90, false);
move(1500, speed);
intake = 100;
pros::delay(500);
intake = 0;
move(-300, 70);
PID(100, false);
move(1000, speed);
PID(70, false);
move(1100, speed);
intake = -100;
pros::delay(900);
intake = 0;
drive_left1 = 100;
drive_left2 = 100;
drive_right1 = 100;
drive_right2 = 100;
pros::delay(700);
drive_left1 = 0;
drive_left2 = 0;
drive_right1 = 0;
drive_right2 = 0;
move(-800, speed);
}
/**
* Runs the operator control code. This function will be started in its own task
* with the default priority and stack size whenever the robot is enabled via
* the Field Management System or the VEX Competition Switch in the operator
* control mode.
*
* If no competition control is connected, this function will run immediately
* following initialize().
*
* If the robot is disabled or communications is lost, the
* operator control task will be stopped. Re-enabling the robot will restart the
* task, not resume it from where it left off.
*/
void opcontrol()
{
// Set up devices
pros::Imu imu(Pimu);
pros::Motor drive_left1(Pdrive_left_1);
pros::Motor drive_left2(Pdrive_left_2);
pros::Motor drive_right1(Pdrive_right_1, true);
pros::Motor drive_right2(Pdrive_right_2, true);
pros::Controller master(CONTROLLER_MASTER);
pros::Motor catta_left(Pcatta_left);
pros::Motor catta_right(Pcatta_right, true);
pros::Motor intake(Pintake, true);
pros::ADIDigitalOut wings(Pwings);
catta_left.set_brake_mode(MOTOR_BRAKE_COAST);
catta_right.set_brake_mode(MOTOR_BRAKE_COAST);
// Create addrled objects for light strips
auto right_strip = sylib::Addrled(PexpandR, PlightR, length);
auto left_strip = sylib::Addrled(PexpandL, PlightL, length);
// Set strips to green to signal forward Drive and ready
right_strip.set_all(0x008000);
left_strip.set_all(0x008000);
// Caliber colour #f47a20 || Version that works on strip #ff6a00
// Store the time at the start of the loop
std::uint32_t clock = pros::millis();
// Vars to keep tract of differnt states
bool reverse = false;
bool shoot = false;
bool wing = false;
bool rotate = false;
int rot = 0;
int left = 0;
int right = 0;
while (true)
{
if (reverse)
{
left = -master.get_analog(ANALOG_RIGHT_Y);
right = -master.get_analog(ANALOG_LEFT_Y);
}
else
{
left = master.get_analog(ANALOG_LEFT_Y);
right = master.get_analog(ANALOG_RIGHT_Y);
}
if (left > 100)
{
left = round((2.85185185 * left) - 235);
}
else if (left < -100)
{
left = round((2.85185185 * left) + 235);
}
else
{
left = round(0.5 * left);
}
if (right > 100)
{
right = round((2.85185185 * right) - 235);
}
else if (right < -100)
{
right = round((2.85185185 * right) + 235);
}
else
{
right = round(0.5 * right);
}
drive_left1 = left;
drive_left2 = left;
drive_right1 = right;
drive_right2 = right;
if (master.get_digital(DIGITAL_R1))
{
intake = 100;
}
else if (master.get_digital(DIGITAL_R2))
{
intake = -100;
}
else
{
intake = 0;
}
if (master.get_digital_new_press(DIGITAL_A))
{
wing = !wing;
wings.set_value(wing);
}
if (master.get_digital_new_press(DIGITAL_L1))
{
catta_left.move_relative(255, 120);
catta_right.move_relative(255, 200);
shoot = true;
}
else if (master.get_digital_new_press(DIGITAL_L2))
{
catta_left.move_relative(255, 100);
catta_right.move_relative(255, 100);
shoot = true;
}
else if (master.get_digital_new_press(DIGITAL_DOWN))
{
catta_left.brake();
catta_right.brake();
catta_left = -40;
catta_right = -40;
pros::delay(200);
catta_left.brake();
catta_right.brake();
}
if (shoot)
{
if (catta_left.get_position() > (catta_left.get_target_position() - 10))
{
catta_left.brake();
catta_right.brake();
catta_left = -50;
catta_right = -50;
pros::delay(200);
catta_left.brake();
catta_right.brake();
shoot = false;
}
}
if (master.get_digital_new_press(DIGITAL_B))
{
reverse = !reverse;
if (reverse)
{
master.rumble("...");
right_strip.set_all(0xff6a00); // 0x800000);
left_strip.set_all(0xff6a00); // 0x800000);
}
else
{
master.rumble("-");
right_strip.set_all(0x008000);
left_strip.set_all(0x008000);
}
}
if (master.get_digital_new_press(DIGITAL_X))
{
right_strip.gradient(0xFF0000, 0xFF0005, 0, 0, false, true);
left_strip.gradient(0xFF0000, 0xFF0005, 0, 0, false, true);
rot = 0;
rotate = true;
/*catta_left = 100;
catta_right = 100;
pros::delay(40);
catta_left = 0;
catta_right = 0;
catta_left.brake();
catta_right.brake();*/
// Catta jugle celebration code
}
if (rotate)
{
if (rot < (2 * length))
{
right_strip.rotate(1, false);
left_strip.rotate(1, false);
rot++;
}
else
{
rotate = false;
if (reverse)
{
right_strip.set_all(0xff6a00); // 0x800000);
left_strip.set_all(0xff6a00); // 0x800000);
}
else
{
right_strip.set_all(0x008000);
left_strip.set_all(0x008000);
}
}
}
// 10ms delay to allow other tasks to run
sylib::delay_until(&clock, 10);
}
}
Thanks for the help