Hi!
Grouping code together can be done in VEXcode v5 text by using something called a function. Functions are basically sections of code that execute together, and the function can be reused as many times as you want. They’re extremely versatile and make coding a lot easier!
Here is an example of a function. In this post, I’m going to show you how to create this function through a step-by-step approach.
void moveBase(float revs) {
// start motors 1, 2, and 3 but don't wait for them to finish before moving on
motor1.startRotateFor(revs, rotationUnits::rev);
motor2.startRotateFor(revs, rotationUnits::rev);
motor3.startRotateFor(revs, rotationUnits::rev);
// start motor 4 but wait for it to finish before moving on
motor4.rotateFor(revs, rotationUnits::rev);
}
1. Data Types
To make a function, start out by typing the data type. A data type is basically the type of information the function is going to output when given a certain set of inputs, called parameters.
void: this data type means that the function won’t return anything, it’ll just execute some set of commands.
int: this data type means that the function will return an integer number (a whole number). This data type is also used in making tasks for multithreading, but that’s an advanced concept and you don’t need to worry about that right now.
bool: this data type returns a boolean (true or false) value.
float: this data type returns a floating point number (a decimal number).
This is seen in the first part of the function, the first word of the first line of the function, often referred to as the function header.
void moveBase(float revs) {
^ that ‘void’ means that the function won’t return anything. This means that it doesn’t have to have a return statement.
Other functions that use the other data types need a return statement. This is modeled in the below example:
int integerFunction() {
// do functiony stuff
// return a 0 back to the caller
return 0;
}
In this example, we are using a function named integerFunction. Because it is an integer function, it has to return an integer number. Likewise, if we are dealing with a boolean function, it will have to return a boolean value.
2. Function Naming Conventions
The next thing we need to make a function is the function name and the function’s parameters. Functions have a few naming conventions-- the 1st character of the name can’t be a number, it can’t have spaces, it can’t have any weird characters like @ or %, and it can’t be named something that means something else in the programming language, like bool or int. It can have underscores, though. Here are some examples of illegally named functions.
// these are some illegally named functions.
void 1stMove() {
}
void %turned() {
}
void turn left() {
}
void bool() {
}
It’s also a programmer’s rule of thumb to make the function names clear so you can understand them. If you have multiple words in your name, you can also use camelCase, where you capitalize the first letter of every word after the first word. Here are some examples of legally named functions (some using camelCase). You can also use an underscore to separate the words.
// these are some legally named functions
void move() {
}
void moveBase() {
}
void move_right() {
}
3. Parameters
Parameters are the values you pass into a function. They are in the header, in the parentheses after the name. These are extremely helpful to use, because they allow you to not hard-code anything-- just like variables!
What's a variable?
A variable is essentially a box that you can put a value in.
int number = 5;
This example means that the integer variable ‘number’ has a value that is equal to 5. (Yes, data types are needed in variable declaration statements!)
You can change the value of a variable at any time by changing the value in the declaration statement
int number = 6;
or just changing it later on in the program.
number = 7;
Remember that you only need to declare a variable once. After you’ve done that, you don’t need to restate the variable declaration, because the program already has a spot in memory named ‘number’ or whatever you named your variable, and it doesn’t need to create a new variable of the same name.
Here is an example of turn_left, a function that takes degrees as a parameter.
void turn_left(float degreesToTurn) {
}
If you use degreesToTurn as a parameter, this means that you can use the variable degreesToTurn in your function! This is seen in the first function example I gave, with moveBase.
void moveBase(float revs) {
// start motors 1, 2, and 3 but don't wait for them to finish before moving on
motor1.startRotateFor(revs, rotationUnits::rev);
motor2.startRotateFor(revs, rotationUnits::rev);
motor3.startRotateFor(revs, rotationUnits::rev);
// start motor 4 but wait for it to finish before moving on
motor4.rotateFor(revs, rotationUnits::rev);
}
As you can see, this function takes revs (revolutions) as a parameter. This variable, revs, is used later in the function multiple times, in the motor commands. This means that you can use the same function multiple times even when you want to move the base different amounts.
Parameters give reusability to functions, allowing the same function (moveBase) to be used multiple times even when the amount of motion needed isn’t the same every time.
4. What Goes Inside The Function?
Anything you want! This is why functions are so widely used. They offer a way to reuse code multiple times, with enough versatility that they can be adapted to almost any purpose.
In my example, I used code to move my base motors all at the same time. The motor commands can be accessed here, and if you want the specific motor commands I used, you can go here for the startRotateFor command and here for the rotateFor command.
5. Comments
Make sure to comment your code! This can be done by typing 2 slashes next to each other for a line comment (that only takes up that one line), and a /*
then */
for a block comment that spans multiple lines.
Here are some examples of how to use them:
// line comment!
/*
block comment!
this is still part of the block comment
*/
Comments are used to annotate your code so you know what is happening on which lines of code. They should be clear and relevant, so you and/or others can understand your code. In my example, I commented the 2 sections of code I had included: the startRotateFor section for 3 of the motors, and the rotateFor section for the last motor.
void moveBase(float revs) {
// start motors 1, 2, and 3 but don't wait for them to finish before moving on
motor1.startRotateFor(revs, rotationUnits::rev);
motor2.startRotateFor(revs, rotationUnits::rev);
motor3.startRotateFor(revs, rotationUnits::rev);
// start motor 4 but wait for it to finish before moving on
motor4.rotateFor(revs, rotationUnits::rev);
}
In those comments, I explain exactly what’s going on in each section of code.
Commenting your code is a super important practice that will help you waaaaay more than you might think. It is really worth investing the time to properly annotate your code, and you’ll thank yourself later for doing it.
6. Calling The Functions
To call a function, just type the function name, then a set of parentheses, and then the values you want to pass in to the function, called arguments. Here is an example of how to call the function moveBase and have it go 5 revs.
moveBase(5);
This line of code would then be put into the autonomous calling function.
I hope that helped, and feel free to ask any questions you might have! Good luck with your autonomous program! 