Function Library
Function Libraries are collections of programs or subroutines that perform specific tasks that we call "functions". For example, a function of the robot may be to "Drive Forward" or to "Follow the Line" or to "top After 2 Seconds". If possible the functions should be given names that are relevant to the action/task being performed. Try to avoid calling a function: "A1" or "My Great Function" as neither of these names adequately describes the action being performed by the robot.
While certainly you can write your entire program without the use of functions, you will find that functions can provide flexible building blocks that enable you to condense the size of the program and enable you to write programs that are in a natural language (i.e., easier to understand).
There are some useful functions which should form the basis of your function library.
Parameters
Functions can be classified in a number of ways. One classification is based on the presence or absence of "parameters". Some functions may contain parameters while other functions do not. In some functions certain parameters may be optional while in others they are required. You may create some functions with a combination of required and optional parameters.
As an example, a function that does not require parameters is: StopMoving(). No other qualification is needed. If the robot executes that function, it will stop moving. A function with optional parameters is: DriveForward(). This function has two optional parameters (distance and power level). So, you can execute any of the following forms of the function:
DriveForward();
DriveForward(12);
DriveForward(12, 50);
In the examples above, the first one gets the robot moving forward. Some other function will be needed to make it stop. The second example, gets the robot moving forward at the default power level and will continue to drive forward for a distance of 12 inches at which time it will stop. The third example the robot will drive for a distance of 12 inches at the 50 percent power level.
Variables
Variables can be used to help coordinate the actions of the robot so that the functions can be combined with fewer parameters and initializing variables. Common variables can be accessed by different functions. For example, a variable storing the current speed of the robot can be used by any of the moving functions to determine how fast to move the robot. Consider the following program:
PowerLevel = 30;
DriveForward();
UntilDistance(24);
SwingTurnClockwise(90);
DriveForward(6);
The PowerLevel variable is used by both DriveForward functions and the SwingTurnClockwise function in the program above. One variable not shown in the program above is a variable storing the direction the robot is moving (forward, backward, or stopped). The "direction" variable is important because the "SwingTurnClockwise" function does not specify how the "left" motor is supposed to be moved to perform the SwingTurn. In a "SwingTurnClockwise" function, the left motor will be used. However, if the robot is moving forward, the "left" motor will move forward in the SwingTurn. If the robot is moving backward, then the "left" motor will move backward in the SwingTurn.
Configuration variables can also help coordinate the actions performed by the functions. For example, if the motors are mounted up-side down in the robot, then "Forward" will require one type of rotation of the motor whereas if the motors are mounted right-side up in the robot, the "Forward" will require the opposite type of rotation. Fortunately, these variables can be used to store values of -1, +1, and 0 such that the motor is given power that is multiplied by the direction of the robot and orientation of the motors.
MotorA = PowerLevel x Orientation x Direction;
Simplification
Variables and functions simplify your code.
//
// Without Functions and Variables:
motor[MotorB] = 30;
motor[MotorC] = 30;
startDegree = motorEncoder[MotorB];
currentDegree = motorEncoder[MotorB];
while(abs(startDegree - currentDegree) >= 4500) {
currentDegree = motorEncoder[MotorB];
}
motor[MotorC] = 0;
startDegree = motorEncoder[MotorB];
currentDegree = motorEncoder[MotorB];
while(abs(startDegree - currentDegree) >= 800) {
currentDegree = motorEncoder[MotorB];
}
motor[MotorC] = 30;
startDegree = motorEncoder[MotorB];
currentDegree = motorEncoder[MotorB];
while(abs(startDegree - currentDegree) >= 1125) {
currentDegree = motorEncoder[MotorB];
}
motor[MotorB] = 0;
motor[MotorC] = 0;
//
// With Functions and Variables:
PowerLevel = 30;
DriveForward();
UntilDistance(24);
SwingTurnClockwise(90);
DriveForward(6);
Which program would you rather work on? Both make the robot perform the same actions. It's just that the program with the functions and variables is a little easier to understand. And it takes up a fraction of the code.
Redundant?
Aren't these functions redundant? I mean, doesn't the NXT-G language already provide a Move block where I can specify the number of rotations (degrees to turn)? Yes. NXT-G does provide a Move block. However, you have to specify in that block all of the needed characteristics such as direction to turn (forward or backward), power level, rotations (or degrees), and what to do afterward (coast or break). Turning in NXT-G is a little limited in that you have only certain choices for turning radius.
When you create your own "user defined" functions, you are able to specify how the variables are initialized and used. You can specify what actions the robot will perform and what feedback it can give back to the user.
Navigation
Driving Straight- Drive Forward (optional: distance, power level)
- Drive Backward (optional: distance, power level)
- Sends the robot driving forward/backward. Please note that the DriveForward and DriveBackward functions do not contain loops (even if a distance is specified). If a distance is specified then the function will also execute the StopAfterDistance() function. These functions will set the value of the "Direction" variable. This "Direction" variable is used in the StopAfterDistance() function to tell that function whether it should check for
- Back Into Wall (optional: power level)
- This is a special function that is configured according to the particular robot (with touch sensors in the bumper; with specific durations of movement).
Stopping- Stop Moving = A simple function that turns off all power to the motors and sets the direction variable to "Stopped".
- Stop After Distance - The "Distance" (in inches) is converted to degrees of rotation through an algebraic formula based on the wheel circumference in millimeters:
targetDegrees = 360 * inches * 25.4 / wheelCircumferenceMM * gearRatio * direction * motorOrientation + currentRotationSensor; - Stop After Degrees
- Stop on Line
- Stop on Ultrasonic Sensor
Turning- Point Turn - Turns wheels/treads in opposite directions.
- Swing Turn - Turns just one wheel/tread
- Gradual Turn - Turns both wheels/treads in the same direction but at different rates/speeds
Accessory Manipulation
Orientation of the accessory motor has a direct impact on the direction that the motor needs to be turned in order to perform specific actions. For example, if the motor is positioned right-side-up or upside-down on the robot, you may need to give instructions to move in the forward or backward direction in order to get the accessory to move in one specific direction.
- Move for Specific Number of Degrees
- Move to Specific Degree
- Move until Stall
Reading and Detecting Values from Sensors
- Get Percentage of Light
- Until Touch
- Until Ultrasonic Sensor is (x) inches
Until Functions
- Until Line
- Until Distance
- Until Touch
- Until Sonar
Special Functions
- Align with Line
- Until Ultrasonic Sensor is (x) inches
- Accelerate Over Distance
- Wait for Orange Button / Enter Key
Program Control