Functions work similarly to variables in representing something else, but serve a different purpose. While variables typically replace short items like numbers, functions can substitute for multiple lines of code. This proves valuable when code sections will repeat or when organizing code into manageable sections.
To establish a new function in a Blocks program, retrieve a block from the Functions menu. Replace "do something" with an appropriate name (the example uses a climbing function). Once named, the function appears in the "Functions" menu for use throughout the code. Add desired code within the function. Deleting the function block removes it from the "Functions" menu.
This example connects to the 2024-25 FTC Starter Bot program but applies to other robots. After configuration, create a new OpMode (named FunctionsDemo) to begin.
The documentation presents an autonomous code scenario where a robot drives roughly in a square pattern. Initially, code might look lengthy when adding arm movements or servo claw operations between turns. By consolidating the side motion and turn logic into a named function, the main loop becomes cleaner and easier to modify.
When testing reveals the robot doesn't drive a perfect square, the function approach allows changing values in one location, with changes reflected everywhere that function is called. Users can refine the movement by adjusting the right motor's power or timer settings.
How a Mecanum Drivetrain is programmed largely depends on the driver's preference for how the controller is configured.
In our provided example, the left joystick controls forward/back and strafe then the right joystick controls turning. This code is based on the sample provided by FIRST for Blocks (BasicOmniOpMode) available in the Robot Controller Console.
| Port Type | Port Number | Device Type | Name |
|-----------|-------------|-------------|------|
| Motor | 0 | REV Robotics Ultraplanetary HD Hex Motor | frontLeft |
| Motor | 1 | REV Robotics Ultraplanetary HD Hex Motor | backLeft |
| Motor | 2 | REV Robotics Ultraplanetary HD Hex Motor | frontRight |
| Motor | 3 | REV Robotics Ultraplanetary HD Hex Motor | backRight |
Adjust the direction block to change the set direction during initialization.
This example makes use of functions to help organize the code!
At the very beginning of our program, our MOTOR_SETTINGS function is called. Within it the drivetrain motors are set to RUN_WITHOUT_ENCODER and are set to run the appropriate direction.
Next, we need to create some new variables in order to use mecanum.
| Variable | Purpose |
|----------|---------|
| forwardBack | Moving forward and backwards |
| strafe | Strafing side to side |
| turn | Turning left and right |
| leftFrontPower | Sets the front left motor power |
| rightFrontPower | Sets the front right motor power |
| leftBackPower | Sets the back left motor power |
| rightBackPower | Sets the back right motor power |
At the beginning of the MECANUM_DRIVE function, our variables for each movement direction are being set to the value generated by the movement of the matching joystick axis.
Since we now have four motors in play, our equation for setting the needed power to each motor gets a little more complicated.
Our robot first needs to determine the combined movement of the gamepad's left joystick, then calculate with the right stick's value. All our calculations together allows for movement when the left joystick is moved at an angle, such as for strafing along a diagonal!
For example, our leftFrontPower variable will equal:
leftFrontPower = (forwardBack + strafe) + turn
So what if we move our left joystick all the way to the left side along the X-axis. To our robot, our equation will read something like this:
leftFrontPower = (0 + -1) + 0
What would be the power of our other motors?
Answer:
rightFrontPower = (0 - (-1)) + 0
leftBackPower = (0 - (-1)) - 0
rightBackPower = (0 + -1) - 0
Simplified:
leftFrontPower = -1
rightFrontPower = 1
leftBackPower = 1
rightBackPower = -1
As we can see our motors are spinning the same direction as their diagonal partner, meaning the robot will strafe left!
More Complex Example:
What if we had the left joystick at an angle, all the way to the left and halfway towards the top?
leftFrontPower = (0.5 + -1) + 0
In this situation, our leftFront motor would set the power to -0.5!
Or had our left stick forward and right stick all the way right?
leftFrontPower = (1 + 0) + 1
In this case, while our equation equals to 2, our motor cannot power higher than 1 so will cap out at full power!
For our last step, our robot sets the power of each pair of motors based on all our calculations!
While driving, there's a possibility a value may fall outside the range of the motor's power (-1 to 1). To help make sure no inputs are lost because of this, we can use a technique called "normalizing".
What normalizing does is take all of our calculated values and scales them appropriately to remain inside the intended range.
First we need to create a new variable called "max".
In Blocks, we use something called a "list", also known as an "array" to store a set of numbers. In this case, we will be storing all of our motor powers.
We will use a block from our "Math" menu changed to "max", meaning it is returning the largest value from our list of motor powers.
Since our motor power will sometimes be negative, such as when turning in reverse, we want to make sure we're using the absolute value of our motor powers.
Next, we will set up our If/Else to check if our "max" is higher than 1 and therefore outside the motor's range.
Using this statement, we'll readjust each of our motor's power back to be within range proportionally by dividing each by the m
[... guide continues at REV docs ...]