Difference between revisions of "Tutorials/Arduino Projects/Mobile Robotics/BoeBot/Driving Functions"

From ROBOTC API Guide
Jump to: navigation, search
(Passing Parameters)
(Passing Multiple Parameters)
 
(8 intermediate revisions by one user not shown)
Line 3: Line 3:
 
{{tl|1|}}
 
{{tl|1|}}
 
== Repetition ==
 
== Repetition ==
By now you have probably notice that blocks of code are often repeated multiple times throughout your code. Take for example the code to drive forward at speed 20.
+
By now you have probably noticed that blocks of code are often repeated multiple times throughout your code. For example, let's look at the code to drive forward:
  
 
{|
 
{|
Line 13: Line 13:
 
|}
 
|}
  
or the code to stop
+
and the code to stop:
  
 
{|
 
{|
Line 23: Line 23:
 
|}
 
|}
  
After repeatedly entering this blocks of code, you are probably wondering if there is any way to reduce this repetition.
+
To reuse common segments of code without having to retype or copy and paste each line of code, you can use a '''function''' to repeatedly utilize segments of code.
 
+
Fortunately, can use something called a function.
+
  
 
== What is a Function? ==
 
== What is a Function? ==
A Function is a special block of code that runs as a single unit when called from another location in the code. It is common for each function to represent a specific behavior in the program. Each function has a unique name within the code. It is by referencing this name that you call and thus run the function.
+
A Function is a special block of code that runs as a single unit when called from another location in the code. It is common for each function to represent a specific behavior in the program. Not only do they help make complex code easily accessible to the rest of the program, they allow you to run the same code multiple times with very little extra coding lines. This helps eliminate redundant code and makes the entire program length shorter.
 +
 
  
The first step to using a function is to define it. Lets say that we have the following code.
+
Let's say that you are running the following code:
  
 
{|
 
{|
Line 74: Line 73:
 
|}
 
|}
  
You might notice that the code to stop driving for 1 second, occurs 3 times in the program.
+
Notice that the code to make the robot stop driving for 1 second occurs three different times in the program. This is a great of example of where a function would be useful.
 
+
 
{|
 
{|
 
|-
 
|-
Line 88: Line 86:
 
=== Defining a Function ===
 
=== Defining a Function ===
  
So if we wanted to make the code shorter, and in most cases easier to read, we could put the stopping code into a function and call that function when we want to stop. To do this we would first place the following function definition in the file before "task main()".
+
Before we can use a function, however, we must define it. To do this we would first place the following function definition in the file before "task main()".
  
{|
+
{|  
 
|-
 
|-
 
|<syntaxhighlight lang="ROBOTC">
 
|<syntaxhighlight lang="ROBOTC">
Line 96: Line 94:
 
void StopFor1Second()
 
void StopFor1Second()
 
{
 
{
  motor[leftServo] = 0;
+
 
  motor[rightServo] = 0;
+
}
  wait1Msec(1000);
+
 
 +
task main()
 +
{
 +
 
 
}</syntaxhighlight>
 
}</syntaxhighlight>
 
|-
 
|-
 
|}
 
|}
  
Lets talk about the structure of a function definition. You'll notice that there is a comment on the first line of the code block. This comment is not required but it is a good practice to have a comment that explains what the function does. This can make it easier to follow the coding and also makes it easier to come back to a program after some time and modify it.
+
The first line contains a comment explaining what the function does. While not required to make the robot run, it is good practice to comment all functions to enable easy understanding of the code.
  
Next you will see "void StopFor1Second()". This line tells the compiler that the code in the brackets is a function. The first ''word'' on the line is void. The word "void" can be replaced by a few others, however that is for a later tutorial. For now all you need to know is that "void" basically tells the compiler that when the function is called, just run the function code, then return right back to where it was called from. The next ''word'' is the name of the function. In this case we are calling the function "StopFor1Second" since it will make the robot stop for 1 second. You will also notice the parentheses immediately after the function name. The purpose of these will be discussed later.
+
Next is the 'void StopFor1Second()' line. This line actually sets up the function and defines it as a 'void' type with the name of 'StopFor1Second'. The void type means that the function will not return a value to wherever it was called from. The parentheses after the function name (StopFor1Second) are used to pass parameters into the function. Neither the function type nor parameters are used in this program and will be more fully covered in a later tutorial.
  
{{Note|When naming your functions you need to remember that the name can not contain any white spacing. That means no spaces, new lines, or tabs. To make function names easier to understand, it is standard practice with any C based language, to capitalize the fist letter of each "word" in the name. For example, if you are thinking "do this simple task" you would name it "DoThisSimpleTask".}}
+
After the function is declared there is a set of curly braces that denote the start and end points of the function (similar to task main() ). Whatever code you want the function to run (in this case, the code to stop the robot for 1 second) will be inside the braces. These braces are necessary for the code to compile and run correctly.
  
{{Note|It is a good idea to make the name of your function relevent to the task that it performs. For example, if you have a function that makes the robot drive forward, name it something like "DriveForward" and not "Function1". This will help document the code with fewer comments since you don't need to to add a comment saying that the function called is for driving forward.}}
+
There are some special rules that must be followed when defining a function. The function name cannot be already defined or in use by ROBOTC (a 'keyword'). The name cannot contain any whitespaces. If defining a non-void return type function, the function must return an appropriate value (again, more information on this will be available in a later tutorial. Generally, making sure the function has a relevant name helps avoid confusion (FunctionOne is much less descriptive than StopFor1Second) and using the standard C coding principle of capitalizing the first letter of each word in a function increases its readability (StopFor1Second is easier to read than stopfor1second).
  
 
Now you define the code that will be run when the function is called. Just like with "task main()", while loops, and for loops, this code is placed inside of curly brackets "{}".
 
Now you define the code that will be run when the function is called. Just like with "task main()", while loops, and for loops, this code is placed inside of curly brackets "{}".
Line 115: Line 116:
 
=== Using a Function ===
 
=== Using a Function ===
  
Now that the function is defined, we can go ahead and replace the code in "task main()" to stop the robot, with a call to the new function. To call a function you simply enter the name of the function where you want to run it followed by a semi-colon. In this case the name of the function is "StopFor1Second()", so we would use "StopFor1Second();". So if we replace all the code we get
+
Now that the function is defined, we can move the code in "task main()" to stop the robot to the new function. Once the code is in place, we will need to 'call' the function to access it. To call a function, you simply type the name of the function (including the two parentheses) followed by a semicolon. In this case the name of the function is "StopFor1Second()", so we would use "StopFor1Second();".
  
 
{|
 
{|
Line 156: Line 157:
 
|-
 
|-
 
|}
 
|}
 +
 +
This code will start by defining StopFor1Second(), starting task main(), and moving the robot forward for one second. When it reaches the StopFor1Second() function call, the program will 'jump' to the start of the function (opening brace), run the code inside of the StopFor1Second() function, and 'return' to where it was called from when it reaches the closing brace. Program flow will then pick up exactly where it left off; in this case, after the semicolon of the first StopFor1Second() function call.  When task main reaches the second call to StopFor1Second the process repeats itself.
  
 
== Advanced Functions ==
 
== Advanced Functions ==
Of course it is possible to use functions to do more than just reduce repetition.
+
It is possible to use functions to do more than just reduce repetition.
  
 
=== Passing Parameters ===
 
=== Passing Parameters ===
Parameters are a way of passing information into a function, allowing the function to run its commands differently, depending on the values it is given. It may help to think of the parameters as placeholders – all parameters must be filled in with real values when the function is called, so in the places where a parameter appears, it will simply be replaced by its given value.
+
Parameters are a way of passing information into a function, allowing the function to run its commands with different values. It may help to think of the parameters as placeholders – all parameters must be filled in with real values when the function is called. When a parameter appears in the function's code it will simply be replaced by the value passed up during the function call.
  
Now lets say that you have some blocks of code that are very similar, and the only difference is that they have different motor speeds.
+
As an example, let's say you would like to stop for one second the first time the function is called, but stop for two seconds the second time it is called. Without parameters, you would need to make another, separate function for each different stop command:
  
 
{|
 
{|
 
|-
 
|-
 
|<syntaxhighlight lang="ROBOTC">
 
|<syntaxhighlight lang="ROBOTC">
task main()
+
void StopFor1Second()
 
{
 
{
  //drive forward at speed 20 for 1 second
 
  motor[leftServo] = 20;
 
  motor[rightServo] = 20;
 
  wait1Msec(1000);
 
  
  //stop for 1 second
+
}
  motor[leftServo] = 0;
+
  motor[rightServo] = 0;
+
  wait1Msec(1000);
+
  
  //drive backward at speed 10 for 1 second
+
void StopFor1.5Seconds()
  motor[leftServo] = -10;
+
{
  motor[rightServo] = -10;
+
 
  wait1Msec(1000);
+
}
 +
 
 +
void StopFor2.78Seconds()
 +
{
 +
 
 +
}
 +
 
 +
task main()
 +
{
  
  //stop for 1 second
 
  motor[leftServo] = 0;
 
  motor[rightServo] = 0;
 
  wait1Msec(1000);
 
 
}</syntaxhighlight>
 
}</syntaxhighlight>
 
|-
 
|-
 
|}
 
|}
  
It is still possible to use functions to make the code less repetitive, cleaner, and more manageable by using functions with parameters. In the case of the code above, we would pass the desired motor speed to the function in a parameter.
+
Not only will this method create multiple copies of redundant code (which is exactly why we created a function in the first place; to eliminate redundant code), it is extremely inflexible if you need to stop for a time that doesn't already have a function created for it. However, parameters allow you to pass values into a function and use that value inside the function's code. To use parameters in the StopFor1Second program, for instance, we would need to modify the function declaration to include the necessary parameters and ensure we pass appropriate values from task main().  
  
To define a function that accepts parameters you take the basic function definition and inside the parentheses, you place the variable name and type of the parameter you wish to use. In this case we want to pass a int the represents the motor speed, so we will call it "speed".
+
The first step, modifying the function declaration, is were you decide what type of value is going to be passed into the function. Since we are using the Wait1MSec command we will need to use the integer type. We want to ensure the name of the integer fits what the value will be used for and is easy to read; in this case, we will call it 'stopTime'. To add the parameter to the function, simply create the integer inside of the functions parentheses:
  
 
{|
 
{|
 
|-
 
|-
 
|<syntaxhighlight lang="ROBOTC">
 
|<syntaxhighlight lang="ROBOTC">
//set both drive motors to the specified speed and wait 1 second
+
void StopFor1Second(int stopTime)
void SetBothMotors(int speed)
+
 
{
 
{
  motor[leftServo] = speed;
+
 
  motor[rightServo] = speed;
+
}
  wait1Msec(1000);
+
 
}</syntaxhighlight>
+
</syntaxhighlight>
 
|-
 
|-
 
|}
 
|}
  
Using a function with parameters is very similar to using one without any. The differance is that when calling the function, instead of having empty parentheses, you place the value you wish to pass inside the parentheses.
+
Now, every time the StopFor1Second function is called it will need an integer value passed to it:
 +
 
  
 
{|
 
{|
 
|-
 
|-
 
|<syntaxhighlight lang="ROBOTC">
 
|<syntaxhighlight lang="ROBOTC">
//set both drive motors to the specified speed and wait 1 second
+
void StopFor1Second(int stopTime)
void SetBothMotors(int speed)
+
 
{
 
{
  motor[leftServo] = speed;
+
 
  motor[rightServo] = speed;
+
  wait1Msec(1000);
+
 
}
 
}
  
 
task main()
 
task main()
 
{
 
{
  //drive forward at speed 20 for 1 second
+
StopFor1Second(1000);
  SetBothMotors(20);
+
}
  
  //stop for 1 second
+
</syntaxhighlight>
  SetBothMotors(0);
+
|-
 +
|}
  
  //drive backward at speed 10 for 1 second
+
This will pass a value of 1000 to the integer 'stopTime' in the StopFor1Second function. Now, all we need to do is add it to the code that already exists by replacing the Wait1MSec values with 'stopTime' and adding an integer value to each calling of StopFor1Second:
  SetBothMotors(-10);
+
  
   //stop for 1 second
+
{|
   SetBothMotors(0);
+
|-
}</syntaxhighlight>
+
|<syntaxhighlight lang="ROBOTC">
 +
void StopFor1Second(int stopTime)
 +
{
 +
   motor[leftServo] = 0;
 +
   motor[rightServo] = 0;
 +
  wait1Msec(stopTime);
 +
}
 +
 
 +
task main()
 +
{
 +
StopFor1Second(1000);
 +
}
 +
 
 +
</syntaxhighlight>
 
|-
 
|-
 
|}
 
|}
  
You are also able pass more than one parameter to a function. This is done by separating the list of parameters with commas. So say that we needed to modify the above code to allow variable times, you would end up with
+
If you want to stop the robot for a different amount of time (2 seconds, for example), all you have to do is add a second call to the StopFor1Second that passes a value of 2000 (2000ms = 2 seconds).
  
 
{|
 
{|
 
|-
 
|-
 
|<syntaxhighlight lang="ROBOTC">
 
|<syntaxhighlight lang="ROBOTC">
//set both drive motors to the specified speed and wait 1 second
+
void StopFor1Second(int stopTime)
void SetBothMotors(int speed, int time)
+
 
{
 
{
   motor[leftServo] = speed;
+
   motor[leftServo] = 0;
   motor[rightServo] = speed;
+
   motor[rightServo] = 0;
   wait1Msec(time);
+
   wait1Msec(stopTime);
 
}
 
}
  
 
task main()
 
task main()
 
{
 
{
  //drive forward at speed 20 for 1 second
+
StopFor1Second(1000);
  SetBothMotors(20, 1000);
+
StopFor1Second(2000);
 +
}
  
  //stop for 1 second
+
</syntaxhighlight>
  SetBothMotors(0, 1000);
+
|-
 +
|}
  
  //drive backward at speed 10 for 2 seconds
+
Finally, you may want to change the name of the function to something more appropriate since it no longer stops the robot only for one second. Remember to not only change the function name when it is declared, but also the name of the function each time it is called (in this example, change it to 'StopForTime'):
  SetBothMotors(-10, 2000);
+
  
   //stop for 1 second
+
{|
   SetBothMotors(0, 1000);
+
|-
}</syntaxhighlight>
+
|<syntaxhighlight lang="ROBOTC">
 +
void StopForTime(int stopTime)
 +
{
 +
   motor[leftServo] = 0;
 +
  motor[rightServo] = 0;
 +
  wait1Msec(stopTime);
 +
}
 +
 
 +
task main()
 +
{
 +
StopForTime(1000);
 +
StopForTime(2000);
 +
}
 +
 
 +
</syntaxhighlight>
 +
|-
 +
|}
 +
 
 +
==Passing Multiple Parameters==
 +
 
 +
You can pass more than one parameter to a function each time you call it. Since you already know how to pass a single parameter, passing a second (or third) parameter is relatively simple. For example, let's create a new 'MoveWheels' function to accept both motor power levels and a wait time. To do this, create a new function but instead of creating one parameter variable (like you did in the StopForTime program with 'stopTime'), you will make three integer variables separated by a comma. They will be named leftPower, rightPower, and moveTime:
 +
 
 +
{|
 +
|-
 +
|<syntaxhighlight lang="ROBOTC">
 +
void MoveWheels(int leftPower, int rightPower, int moveTime)
 +
{
 +
 
 +
}
 +
 
 +
</syntaxhighlight>
 +
|-
 +
|}
 +
 
 +
Now that the MoveWheels function has been initialized, it will need to be called in task main(), just like the StopForTime function, only this time you will be passing three values to it:
 +
 
 +
{|
 +
|-
 +
|<syntaxhighlight lang="ROBOTC">
 +
void MoveWheels(int leftPower, int rightPower, int moveTime)
 +
{
 +
   motor[leftServo] = leftPower;
 +
  motor[rightServo] = rightPower;
 +
  wait1Msec(moveTime);
 +
}
 +
 
 +
task main()
 +
{
 +
MoveWheels(50, 50, 1000);
 +
MoveWheels(25, 75, 2500);
 +
MoveWheels(0, 0, 1000);
 +
}
 +
 
 +
</syntaxhighlight>
 
|-
 
|-
 
|}
 
|}
  
{{FuncDetails|Tutorials/Arduino_Projects/Additional_Info/Functions|Functions}}
+
By passing up both the motor power levels and wait time parameters to the MoveWheels function, you can now change your robot's direction, speed, and movement duration with one line of code.

Latest revision as of 20:27, 12 October 2012

Repetition

By now you have probably noticed that blocks of code are often repeated multiple times throughout your code. For example, let's look at the code to drive forward:

motor[leftServo] = 20;
motor[rightServo] = 20;

and the code to stop:

motor[leftServo] = 0;
motor[rightServo] = 0;

To reuse common segments of code without having to retype or copy and paste each line of code, you can use a function to repeatedly utilize segments of code.

What is a Function?

A Function is a special block of code that runs as a single unit when called from another location in the code. It is common for each function to represent a specific behavior in the program. Not only do they help make complex code easily accessible to the rest of the program, they allow you to run the same code multiple times with very little extra coding lines. This helps eliminate redundant code and makes the entire program length shorter.


Let's say that you are running the following code:

task main()
{
  while(true)
  {
    //drive forward at speed 20 for 1 second
    motor[leftServo] = 20;
    motor[rightServo] = 20;
    wait1Msec(1000);
 
    //stop driving for 1 second
    motor[leftServo] = 0;
    motor[rightServo] = 0;
    wait1Msec(1000);
 
    //right point turn at speed 20 for 1 second
    motor[leftServo] = 20;
    motor[rightServo] = -20;
    wait1Msec(1000);
 
    //stop driving for 1 second
    motor[leftServo] = 0;
    motor[rightServo] = 0;
    wait1Msec(1000);
 
    //drive backward at speed 10 for 2 seconds
    motor[leftServo] = -10;
    motor[rightServo] = -10;
    wait1Msec(2000);
 
    //stop driving for 1 second
    motor[leftServo] = 0;
    motor[rightServo] = 0;
    wait1Msec(1000);
  }
}

Notice that the code to make the robot stop driving for 1 second occurs three different times in the program. This is a great of example of where a function would be useful.

//stop driving for 1 second
motor[leftServo] = 0;
motor[rightServo] = 0;
wait1Msec(1000);

Defining a Function

Before we can use a function, however, we must define it. To do this we would first place the following function definition in the file before "task main()".

//function to stop the robot for 1 second
void StopFor1Second()
{
 
}
 
task main()
{
 
}

The first line contains a comment explaining what the function does. While not required to make the robot run, it is good practice to comment all functions to enable easy understanding of the code.

Next is the 'void StopFor1Second()' line. This line actually sets up the function and defines it as a 'void' type with the name of 'StopFor1Second'. The void type means that the function will not return a value to wherever it was called from. The parentheses after the function name (StopFor1Second) are used to pass parameters into the function. Neither the function type nor parameters are used in this program and will be more fully covered in a later tutorial.

After the function is declared there is a set of curly braces that denote the start and end points of the function (similar to task main() ). Whatever code you want the function to run (in this case, the code to stop the robot for 1 second) will be inside the braces. These braces are necessary for the code to compile and run correctly.

There are some special rules that must be followed when defining a function. The function name cannot be already defined or in use by ROBOTC (a 'keyword'). The name cannot contain any whitespaces. If defining a non-void return type function, the function must return an appropriate value (again, more information on this will be available in a later tutorial. Generally, making sure the function has a relevant name helps avoid confusion (FunctionOne is much less descriptive than StopFor1Second) and using the standard C coding principle of capitalizing the first letter of each word in a function increases its readability (StopFor1Second is easier to read than stopfor1second).

Now you define the code that will be run when the function is called. Just like with "task main()", while loops, and for loops, this code is placed inside of curly brackets "{}".

Using a Function

Now that the function is defined, we can move the code in "task main()" to stop the robot to the new function. Once the code is in place, we will need to 'call' the function to access it. To call a function, you simply type the name of the function (including the two parentheses) followed by a semicolon. In this case the name of the function is "StopFor1Second()", so we would use "StopFor1Second();".

//function to stop the robot for 1 second
void StopFor1Second()
{
  motor[leftServo] = 0;
  motor[rightServo] = 0;
  wait1Msec(1000);
}
 
task main()
{
  while(true)
  {
    //drive forward at speed 20 for 1 second
    motor[leftServo] = 20;
    motor[rightServo] = 20;
    wait1Msec(1000);
 
    StopFor1Second();
 
    //right point turn at speed 20 for 1 second
    motor[leftServo] = 20;
    motor[rightServo] = -20;
    wait1Msec(1000);
 
    StopFor1Second();
 
    //drive backward at speed 10 for 2 seconds
    motor[leftServo] = -10;
    motor[rightServo] = -10;
    wait1Msec(2000);
 
    StopFor1Second();
  }
}

This code will start by defining StopFor1Second(), starting task main(), and moving the robot forward for one second. When it reaches the StopFor1Second() function call, the program will 'jump' to the start of the function (opening brace), run the code inside of the StopFor1Second() function, and 'return' to where it was called from when it reaches the closing brace. Program flow will then pick up exactly where it left off; in this case, after the semicolon of the first StopFor1Second() function call. When task main reaches the second call to StopFor1Second the process repeats itself.

Advanced Functions

It is possible to use functions to do more than just reduce repetition.

Passing Parameters

Parameters are a way of passing information into a function, allowing the function to run its commands with different values. It may help to think of the parameters as placeholders – all parameters must be filled in with real values when the function is called. When a parameter appears in the function's code it will simply be replaced by the value passed up during the function call.

As an example, let's say you would like to stop for one second the first time the function is called, but stop for two seconds the second time it is called. Without parameters, you would need to make another, separate function for each different stop command:

void StopFor1Second()
{
 
}
 
void StopFor1.5Seconds()
{
 
}
 
void StopFor2.78Seconds()
{
 
}
 
task main()
{
 
}

Not only will this method create multiple copies of redundant code (which is exactly why we created a function in the first place; to eliminate redundant code), it is extremely inflexible if you need to stop for a time that doesn't already have a function created for it. However, parameters allow you to pass values into a function and use that value inside the function's code. To use parameters in the StopFor1Second program, for instance, we would need to modify the function declaration to include the necessary parameters and ensure we pass appropriate values from task main().

The first step, modifying the function declaration, is were you decide what type of value is going to be passed into the function. Since we are using the Wait1MSec command we will need to use the integer type. We want to ensure the name of the integer fits what the value will be used for and is easy to read; in this case, we will call it 'stopTime'. To add the parameter to the function, simply create the integer inside of the functions parentheses:

void StopFor1Second(int stopTime)
{
 
}

Now, every time the StopFor1Second function is called it will need an integer value passed to it:


void StopFor1Second(int stopTime)
{
 
}
 
task main()
{
 StopFor1Second(1000);
}

This will pass a value of 1000 to the integer 'stopTime' in the StopFor1Second function. Now, all we need to do is add it to the code that already exists by replacing the Wait1MSec values with 'stopTime' and adding an integer value to each calling of StopFor1Second:

void StopFor1Second(int stopTime)
{
  motor[leftServo] = 0;
  motor[rightServo] = 0;
  wait1Msec(stopTime);
}
 
task main()
{
 StopFor1Second(1000);
}

If you want to stop the robot for a different amount of time (2 seconds, for example), all you have to do is add a second call to the StopFor1Second that passes a value of 2000 (2000ms = 2 seconds).

void StopFor1Second(int stopTime)
{
  motor[leftServo] = 0;
  motor[rightServo] = 0;
  wait1Msec(stopTime);
}
 
task main()
{
 StopFor1Second(1000);
 StopFor1Second(2000);
}

Finally, you may want to change the name of the function to something more appropriate since it no longer stops the robot only for one second. Remember to not only change the function name when it is declared, but also the name of the function each time it is called (in this example, change it to 'StopForTime'):

void StopForTime(int stopTime)
{
  motor[leftServo] = 0;
  motor[rightServo] = 0;
  wait1Msec(stopTime);
}
 
task main()
{
 StopForTime(1000);
 StopForTime(2000);
}

Passing Multiple Parameters

You can pass more than one parameter to a function each time you call it. Since you already know how to pass a single parameter, passing a second (or third) parameter is relatively simple. For example, let's create a new 'MoveWheels' function to accept both motor power levels and a wait time. To do this, create a new function but instead of creating one parameter variable (like you did in the StopForTime program with 'stopTime'), you will make three integer variables separated by a comma. They will be named leftPower, rightPower, and moveTime:

void MoveWheels(int leftPower, int rightPower, int moveTime)
{
 
}

Now that the MoveWheels function has been initialized, it will need to be called in task main(), just like the StopForTime function, only this time you will be passing three values to it:

void MoveWheels(int leftPower, int rightPower, int moveTime)
{
  motor[leftServo] = leftPower;
  motor[rightServo] = rightPower;
  wait1Msec(moveTime);
}
 
task main()
{
 MoveWheels(50, 50, 1000);
 MoveWheels(25, 75, 2500);
 MoveWheels(0, 0, 1000);
}

By passing up both the motor power levels and wait time parameters to the MoveWheels function, you can now change your robot's direction, speed, and movement duration with one line of code.