[Tutorial] How to Code a VEX Autonomous in Less than 5 Minutes

Will see how this plays out during the season.

I do think the tutorial is good contribution to the community and encourage more of it.

2 Likes

That is not elitist enough! Uber-elite teams program their robot to write the code for them!

I love what you did Taran! Even I could see how it works! I am eager to try it out!

It may take years, before I could explain how 5225 or okapi code works. Does it mean I am not allowed to try using it in my program if I only learn how to copy from one of their examples?

It makes me feel depressed, every time I remember how we were told last year that we were not allowed to get help from our parents to get started with programming.

My team didn’t know anything and, if not for a high school girl who volunteered to help us and gave us code to move our robot, we were ready to quit mid season.

Please, don’t tell me that I am not allowed to try Taran’s code. Some boys love to ignore teacher’s advice and do everything their own way, but I learn best starting with working examples. It is already stressful with everything else not working.

9 Likes

This is actually a really good resource because it means teams with very low budgets can have a decent auton even if they don’t have a field.

4 Likes

You can use it, but first write a reply explaining how it works.

3 Likes

nope - just saying you need to be able to explain the basics. A lot of teams who copy and paste and are not able to are not really learning anything

and there is nothing that says you can get adults/teachers to teach you how to code. You just can’t have them solve the problem for you … there is a difference.

you will do fine.

2 Likes

Yes. That’s why I said if you could explain to me how it works, feel free to use it.

We should probably split this into a new topic.

So you didn’t make it easy for me by posting GitHub link. I had to search for it. Boo!

You have three files in the project: init.cpp, opcontrol.cpp, and auton.cpp

init.cpp has a list of the motors on your robot, like lf, lb, rf, rb, arm, and claw

#include "main.h"

/**
 * 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.
 */
pros::Motor lf(20);
pros::Motor lb(19);
pros::Motor rf(17);
pros::Motor rb(18);
pros::Motor arm(9);
pros::Motor claw(10);
pros::Controller controller1(CONTROLLER_MASTER);

void initialize() {
	arm.set_brake_mode(MOTOR_BRAKE_HOLD);
	claw.set_brake_mode(MOTOR_BRAKE_BRAKE);
}

/**
 * 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() {
}

opcontrol.cpp creates rerun.txt file on the sdcard and saves velocity for each motor every 10 milliseconds, while you drive your robot:

#include "main.h"

int timeOld = 0;
int timeNew = 0;
int deltaTime = 0;
int flSpeed = 0;
int blSpeed = 0;
int frSpeed = 0;
int brSpeed = 0;
int armSpeed = 0;
int clawSpeed = 0;

void opcontrol() {

	FILE* usd_file_write = fopen("/usd/rerun.txt", "w");
	fprintf(usd_file_write, "");
	fclose(usd_file_write);

	while (true) {
		int turn = controller1.get_analog(ANALOG_LEFT_Y);
		int power = controller1.get_analog(ANALOG_RIGHT_X);
		int left = power + turn;
		int right = power - turn;
		lf.move(left);
		lb.move(left);
		rf.move(right);
		rb.move(right);

		if (controller1.get_digital(DIGITAL_R1)) {
			arm.move_velocity(200);
		}
		else if (controller1.get_digital(DIGITAL_R2)) {
			arm.move_velocity(-100);
		}
		else {
			arm.move_velocity(0);
		}

		if (controller1.get_digital(DIGITAL_L1)) {
			claw.move_velocity(200);
		}
		else if (controller1.get_digital(DIGITAL_L2)) {
			claw.move_velocity(-100);
		}
		else {
			claw.move_velocity(0);
		}


		//Rerun Stuffz


		pros::delay(10);

		flSpeed = lf.get_actual_velocity();
		blSpeed = lb.get_actual_velocity();
		frSpeed = rf.get_actual_velocity();
		brSpeed = rb.get_actual_velocity();
		armSpeed = arm.get_actual_velocity();
		clawSpeed = claw.get_target_velocity();

		FILE* usd_file_write = fopen("/usd/rerun.txt", "a");
		fprintf(usd_file_write, "lf.move_velocity(%i); \n", flSpeed);
		fprintf(usd_file_write, "lb.move_velocity(%i); \n", blSpeed);
		fprintf(usd_file_write, "rf.move_velocity(%i); \n", frSpeed);
		fprintf(usd_file_write, "rb.move_velocity(%i); \n", brSpeed);
		fprintf(usd_file_write, "arm.move_velocity(%i); \n", armSpeed);
		fprintf(usd_file_write, "claw.move_velocity(%i); \n", clawSpeed);

		timeNew = pros::millis();
		deltaTime = timeNew - timeOld;
		timeOld = pros::millis();

		fprintf(usd_file_write, "delay(%d); \n", deltaTime);

		fclose(usd_file_write);
		
	}
}

Then there is an awfully long auton.cpp file with all the commands that your program saved on sdcard:

#include "main.h"

void autonomous() {
	lf.move_velocity(0);
	lb.move_velocity(0);
	rf.move_velocity(0);
	rb.move_velocity(0);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(175);
	lf.move_velocity(0);
	lb.move_velocity(4);
	rf.move_velocity(-4);
	rb.move_velocity(0);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(17);
	lf.move_velocity(0);
	lb.move_velocity(5);
	rf.move_velocity(-6);
	rb.move_velocity(-10);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(16);
	lf.move_velocity(4);
	lb.move_velocity(6);
	rf.move_velocity(-7);
	rb.move_velocity(-10);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(19);
	lf.move_velocity(9);
	lb.move_velocity(8);
	rf.move_velocity(-8);
	rb.move_velocity(-7);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(17);
	lf.move_velocity(13);
	lb.move_velocity(8);
	rf.move_velocity(-11);
	rb.move_velocity(-8);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(16);
	lf.move_velocity(18);
	lb.move_velocity(7);
	rf.move_velocity(-14);
	rb.move_velocity(-8);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(18);
	lf.move_velocity(19);
	lb.move_velocity(6);
	rf.move_velocity(-12);
	rb.move_velocity(-7);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(18);
	lf.move_velocity(17);
	lb.move_velocity(5);
	rf.move_velocity(-11);
	rb.move_velocity(-5);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(16);
	lf.move_velocity(15);
	lb.move_velocity(4);
	rf.move_velocity(-11);
	rb.move_velocity(-5);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(18);
	lf.move_velocity(10);
	lb.move_velocity(5);
	rf.move_velocity(-8);
	rb.move_velocity(-5);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(18);
	lf.move_velocity(7);
	lb.move_velocity(7);
	rf.move_velocity(-8);
	rb.move_velocity(-9);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(16);

	// gazillion of lines deleted to keep everyone sane

	delay(20);
	lf.move_velocity(0);
	lb.move_velocity(0);
	rf.move_velocity(0);
	rb.move_velocity(0);
	arm.move_velocity(0);
	claw.move_velocity(0);
	delay(18);
}

Why are the delays all different if you have delay(10) in your opcontrol?

It is not like the program is doing different things every step.

6 Likes

Y u gotta scare me like that :frowning:

2 Likes

“code takes a non-zero time to execute” - someone on discord

4 Likes

Why do I print text to the SD card in the way that I do?

Where did I create the file?

2 Likes

Also, there is a link to the code on the YT page.

2 Likes

Well, I get that it will be over 10, but why the same code executes that much longer, like 16 to 175?

You print the lines that you could ctrl-c & ctrl-v into your auton. You also use a trick to close file every time. Even if you pull the battery cable, the file should still be good.

You created it in your house while sitting on the floor filming the video. Duh.

If you asked “where did the program save the file?” I would say “microsd card that you inserted into v5 brain”.

Do you really expect people that are too lazy to learn “proper” way of doing autonomous to click on YouTube link and then click on the triangle “show more” thingy?

5 Likes

Delaying a program for a precise number of milliseconds, while executing other code during that time, is a really hard problem. So most operating system’s don’t - they merely guarantee that calling for an n millisecond delay will provide a delay of at least n milliseconds, the actual time can be longer.

Additionally, as @Sylvie said, his code takes some time to execute in addition to the 10ms delay - these sorts of things add up when timing things on the scale of milliseconds.

For this reason, when writing timing-precise code like this it’s a good idea to measure the amount of time elapsed between now and this point the last time through the loop, that’s what these lines do:

timeNew = pros::millis();
deltaTime = timeNew - timeOld;
timeOld = pros::millis();
6 Likes

Yes. I delay for the exact change in time, not a quess. Delay_until() could also work, but this does too, and I’m lazy.

2 Likes

Nope. I created it the night before. On my laptop. The code just edits the file, not creates it.

One last question, then you’re good to go:


What happens if there is already text in the file at the start of the program, and why?

Already something in the file at10 sec in?

20 Days?

3 Likes

Ri20d

1 Like

Ok, you’ve got me there! I should’ve paid more attention!

I’m glad you asked. If you haven’t watched full video five times yet, like I did, I recommend you do - the answer is right there at 7:20 and 10:10.

The first time it opens the file with “w” command to wipe it clean. Then in the loop it opens the file with “a” append command and adds more lines to what’s already there.

6 Likes

Answer the other two questions.

*The code could create the file, but it’s not ATM