Introduction to VEX Programming with EasyC
-
Upload
kaden-head -
Category
Documents
-
view
64 -
download
2
description
Transcript of Introduction to VEX Programming with EasyC
1
Introduction to VEX Programming with EasyCPeter JohnsonNorthrop Grumman Space TechnologyProgramming Mentor, Beach Cities Robotics(FRC/FTC/VRC Team 294)1 Mar 2008
2
Agenda
Getting Started The Big Picture The Robot Controller Motors, Servos, and Sensors The C Programming Language Programming Tips and Tricks Parting Thoughts
Getting Started
Downloading the Master Code (only needed once) Downloading code The Terminal Window On-Line Mode
3
Programming – What Binds It All Together
4
Programming
Programming – What Binds It All Together
Programming needs to be involved from the very beginning of design and strategy
Work with the mechanical design team Make sure the sensors you need are designed in from the
start Are there enough controller ports to do what is planned?
Work with the drivers More than if they prefer tank or arcade What buttons should do what and how quickly
Don’t forget about autonomous mode Encoders and ultrasonic sensors may not be useful in
operator control mode, but they may be critical to autonomous mode!
Work with the strategy team Are the planned autonomous modes possible?
5
The VEX Robot Controller
6
VEX Controller Overview
7
Microcontroller
The microcontroller inside the VEX controller is a Microchip PIC18F8520… some specs:
8-bit datapath 10 MIPS (million instructions per second) 32 Kbytes of program memory 2 Kbytes of RAM 1 Kbytes of data memory
Compare this to your PC: 64-bit datapath ~20,000 MIPS 2 Gbytes of RAM/program/data memory
Don’t get discouraged… we got to the moon with less processing power onboard than the VEX controller has!
8
Controller I/O
6 interrupt ports The FTC competition template reserves two for
enable/disable of autonomous and operator control Optical encoder takes 1 or 2 (for quadrature) Ultrasonic sensor takes 1
8 motor ports You may Y motors together, but that means they will
drive the same direction, so watch the gearing! 16 analog inputs / digital I/O ports
Analogs must be in a group starting at port 1 Light sensor takes 1 analog Ultrasonic sensor takes 1 digital Limit/Bumper sensor takes 1 digital
9
Motors, Servos, and Sensors
10
VEX Motor Theory of Operation
The VEX motors are DC Without going into details, the best way to control
the speed of a DC motor is via a technique called Pulse Width Modulation (PWM)
The voltage going to the motor is pulsed, with varying duty cycle (longer times on)
By reversing the polarity to the motor, the motor can be run in reverse
You cannot control the torque generated by the motor – that’s determined by the gear ratio (mechanical design team)
11
VEX Motor Programming
What does this mean for programming? You can set the speed and direction of each motor Built-in function: SetPWM() Takes a value from 0-255:
0 = full speed counter-clockwise 127 = idle 255 = full speed clockwise In-between values are linearly scaled speed
Question: If I have an input that varied from 0-255, but I wanted 0 to mean clockwise and 255 to mean counter-clockwise, how would I easily change it into the correct motor value?
Hint: values very close to 127 (not just 127) still act as idle
12
VEX Servo Operation
VEX servos also use PWM control Unlike a motor, a servo has only a limited range of
motion (in VEX, about 120 degrees) The PWM value sets the position as a fraction of the
range of motion 0 = fully counter-clockwise 255 = full clockwise
Still use SetPWM() to set the position
Caution: the VEX controller sets all servo positions to center (127) on power-up
Warn your mechanical team about this behavior
13
Sensors – A Programmer’s Best Friend
Limit Switch Connects to 1 digital input 0 when closed, 1 when open Use to limit range of mechanical motion in both
autonomous and operator control modes Fragile - always have a mechanical hard stop too!
Bumper Switch More robust than limit switch, but otherwise
operates identically Can itself act as a mechanical hard stop
14
Sensors – A Programmer’s Best Friend
Optical Shaft Encoder Connects to 1 or 2 interrupt ports Interrupt count (90 ticks/revolution) With 2 interrupt ports, can also tell direction Most useful on drivetrain or anything that rotates (like a
lifting arm) Useful for distance, rotation, and driving straight in
autonomous Ultrasonic Range Finder
Connects to 1 interrupt port and 1 digital port Senses distance to a object in inches (2 to 100) Useful for determining distance in a particular direction
to walls, robots, or other objects
15
Programming Sensors
Limit Switches and Bumpers input = GetDigitalInput(X)
Optical Encoder StartEncoder(X) PresetEncoder(X, 0) ticks = GetEncoder(X)
Optical Quadrature Encoder Same as encoder, except two inputs and functions named
with “Quad” Ticks may be negative (direction information)
Ultrasonic Sensor StartUltrasonic(interrupt, output) distance = GetUltrasonic(interrupt, output)
16
The C Programming Language
Mostly from robotics.hideho.org
Fall 2007 Workshops
17
A Bit of History…
Developed 1969-1973 by Dennis Ritchie at Bell Labs Widely used for operating systems, applications,
and embedded systems (robots!) Influenced many other languages (Perl, PHP, …),
and most significantly C++
18
A Simple Example
This program will move the robot forward for 2 seconds, then back it up for 2 seconds, and then stop it:
void main(void)
{
SetPWM(LEFT_MOTOR, 107);
SetPWM(RIGHT_MOTOR, 147);
Wait(2000);
SetPWM(LEFT_MOTOR, 147);
SetPWM(RIGHT_MOTOR, 107);
Wait(2000);
SetPWM(LEFT_MOTOR, 127);
SetPWM(RIGHT_MOTOR, 127);
}
19
Program Sequence
The statements will be executed in the order written. Start at the top, go to the bottom, one statement at a
time. Each line is called a statement.1 SetPWM(LEFT_MOTOR, 107);
2 SetPWM(RIGHT_MOTOR, 147);
3 Wait(2000);
4 SetPWM(LEFT_MOTOR, 147);
5 SetPWM(RIGHT_MOTOR, 107);
6 Wait(2000);
7 SetPWM(LEFT_MOTOR, 127);
8 SetPWM(RIGHT_MOTOR, 127);
20
Key Bits of Syntax
Statements end with a semicolon (;) { } around a list of statements is a compound
statement – looks like a single statement to control structures
21
C is Case Sensitive
C is CaSe SeNsiTiVe Capital letters are considered different than
lowercase letters This means all of the following are different and will
probably cause easyC to complain:
SetPWM(LEFT_MOTOR, 157);
setpwm(left_motor, 157);
SETpwm(left_MOTOR, 157);
22
C Syntax – Whitespace
C doesn't care about spaces, returns, or anything. This means all of the following are the same.
SetPWM(LEFT_MOTOR, 157);
SetPWM( LEFT_MOTOR , 157 ) ;
SetPWM(
LEFT_MOTOR ,157
);
Don’t do this! You want your program to be easy to read. EasyC drag and drop will help make it consistent. Notice the semicolon at the end of each statement.
This is how C knows when the statement ends.
23
C Syntax – No Whitespace in Names
Spaces do matter in names. The following statement has two errors:
Set
PWM(LEFT _MOTOR, 157);
24
Simple Programs
This program will run forever. It will let you drive the robot using the RC
transmitter.
void main(void)
{
while (1 == 1)
{
Tank2 (PORT_1, CHANNEL_3, CHANNEL_1,
LEFT_MOTOR, RIGHT_MOTOR, 1, 0);
}
}
25
Program Sequence
The while is called a loop. The sequence here will be 1, 2, 1, 2, 1, 2, 1, 2... forever (or at least until the batteries die)
1 while (1 == 1)
{
2 Tank2 (PORT_1, CHANNEL_3, CHANNEL_1,
LEFT_MOTOR, RIGHT_MOTOR, 1, 0);
} This is a special type of loop called an infinite loop.
It never ends. Why does it never end? Because 1 always equals 1.
More on that later.
26
Variables
Variables are named bits of memory in the processor. You use variables to keep bits of computations that you
have done or to control the robot.
pwm1 = p1_x;
pwm2 = 255 – p1_y;
bumperSwitch = GetDigitalInput(10);
speedLeftMotor = GetAnalogValue(3) * 2;
speedRightMotor = speedLeftMotor / 2;
The variables above are pwm1, pwm2, p1_x, p1_y, bumperSwitch, speedLeftMotor, and speedRightMotor.
27
Variable Types
Variables in C must be given a type. The type says what kind of information can be stored in
the variable. The type for a variable is given in a variable declaration.
unsigned char speedLeftMotor;
int leftWheelCounts;
The underlined parts are the type of the variable. The rest is the name of the variable. Note: Notice the semicolon at the end. easyC will insert
it for you.
28
Variable Types
Integral types May be “signed” or “unsigned” (signed by default) On the VEX controller, have the following sizes:
There are more, but these are the ones you will usually use. unsigned char is for controlling motors and reading analog
values. Some sort of int or long is good for reading optical encoders.
29
Specifier Bits Min Value Max Value
char 8 -128 +127
unsigned char 8 0 +255
int 16 -32768 +32767
unsigned int 16 0 +65536
long 32 -big +big
unsigned long 32 0 +really big
Variable Declarations
Variables must be declared before they are used. It is an error if they are used before being declared. The declarations must happen at the top of a
function or subroutine, or in the parameter list of a function or subroutine.
30
Variables are Case-Sensitive Too
Remember, C is case sensitive. Capital letters are considered different than lowercase letters.
This means all of the following are the names of different variables.
motorSpeed motorspeed MoToRsPeEd MOTORSPEED
Try not to distinguish variables by the case of their letters. This would make it difficult to read your program and hard
to find errors. ALLCAPS and allcaps are probably okay.
Try to be consistent in variable naming
31
Assignment
Assignment gives a variable a value.
variable = expression;
motorSpeed = 127;
pwm1 = 255 - p1_x;
value = 2 * Limit(2 * GetAnalogValue(3), 255);
shouldThrowBall = operatorSwitch1 && limitSwitch2;
32
Assignment
The same variable can appear on both sides of an assignment statement.
motorSpeed = 127;
motorSpeed = motorSpeed + 1;
What does that mean? Evaluate the right hand side first using the value
the variable has at that moment. Whatever that right hand side value is, store it in
the variable given on the left hand side.
33
Expression Operators
Expressions consist of variables, numbers, and function calls, possibly put together with the following operators:
There are many more that I didn’t list
Examples:
1 + 2 * 3
pwm1 + 4
34
Operator Operation
* Multiplication
/ Division
+ Addition
- Subtraction
Condition Expressions
Also called boolean or comparison expressions. These have a value of true (1) or false (0).
Equality operators are: == Both sides are equal
a == (b + 1)
GetDigitalInput(3) == CLOSED != Both sides are not equal to each
other
a != (b + 1)
GetDigitalInput(3) != CLOSED
35
Condition Expressions – Assignment??
Beware... equality is checked by ==, not = = is for assignment
The following will either give an error from the compiler or not do what you want.
a = b + 1
GetDigitalInput(3) = CLOSED
36
Other Comparison Operators
Other arithmetic comparison operators are: < Left side is less than the right side
a < b + 1
GetAnalogInput(3) < 100 <= Left side is less than or equal to the right side
a + 7 <= b + 1
GetAnalogInput(3) <= 100 > Left side is greater than the right side
a > 2 * (b + 1)
GetAnalogInput(3) / 2 > 100 >= Left side is less than or equal to the right side
a >= b + 1
GetAnalogInput(3) >= 100 + GetAnalogInput(4)
37
Condition Expressions
You can combine boolean expressions with boolean operators.
&& And. True if both sides are true. Otherwise false.
(a < b + 1) && (GetAnalogInput(3) < 100) || Or. False if both sides are false. Otherwise true.
GetDigitalInput(3) == CLOSED || GetAnalogInput(3) <= 100
! Not. Makes false into true and true into false.
!((a < (b + 1)) && (GetAnalogInput(3) <= 100))
Can get fairly complicated.
((a < b + 1) && (GetAnalogInput(3) < 100)) || (a < 4)
38
Loops
Loops provide a way to repeat a group of statements over and over again until some condition is met.
while ( condition ) {
...statements to repeat (called the body of the loop)...
} where condition is a condition expression
(remember, these have a true or false value). The body of the loop will be repeated while the
condition expression is true. Put curly braces around the body
easyC drag and drop does this for you
39
Forever Loops
This program will run forever. The conditional expression is always true.
while (1 == 1)
{
Tank2 (PORT_1, CHANNEL_3, CHANNEL_1,
LEFT_MOTOR, RIGHT_MOTOR, 1, 0);
}
40
Loop Example
Gradually increase the speed of the robot while a switch is open.
When the switch closes, the motors will turn off.
speed = 130;
while (GetDigitalValue(3) == OPEN)
{
speed = speed + 1;
SetPWM(MOTOR_LEFT, speed);
SetPWM(MOTOR_RIGHT, speed);
}
SetPWM(MOTOR_LEFT, 127);
SetPWM(MOTOR_RIGHT, 127);
41
Loop Example
Start some event and use the loop to wait until some other event happens, then do something else.
SetPWM(WINCH_MOTOR, 178);
while(GetAnalogInput(WINCH_POT) < 200)
{
}
SetPWM(WINCH_MOTOR, 127);
Might this be useful for autonomous? Hmm…
42
Counted Loops
Loops can count to repeat a group of statements some number of times.
count = 1;
while (count <= numberBalls)
{
throwBall();
count = count + 1;
} The following doesn’t work. Why?
count = 1;
while (count <= numberBalls)
{
throwBall();
}
43
For Loops
The previous loopcount = 1;
while (count <= numberBalls)
{
throwBall();
count = count + 1;
}
Can instead be written as (less error-prone):for (count = 1; count <= numberBalls; count = count + 1)
{
throwBall();
}
44
Nested Loops
Loops can contain other loops. For instance, this program will stop the robot if a switch is closed
and let the robot move again when the switch is open again.
while (1 == 1)
{
while (GetDigitalInput(10) == CLOSED)
{
SetPWM(LEFT_MOTOR, 127);
SetPWM(RIGHT_MOTOR, 127);
}
Tank2 (PORT_1, CHANNEL_3, CHANNEL_1,
LEFT_MOTOR, RIGHT_MOTOR, 1, 0);
} Maybe this isn’t the best way to write this. See my advanced talk.
45
Loop Body
Can have assignment statements, calls to functions (subroutines), conditionals, and other loops inside of a loop.
Remember to put the { } around the body of the loop Drag and drop EasyC will do it for you
46
Conditionals
Conditionals evaluate a condition expression (remember, these have a value of true or false).
The conditional will execute a block of code (called the body of the conditional) if the value is true.
if ( condition ) {
...statements to do if condition has a true value...
...(called the body of the conditional)...
}
47
Conditional Example
If the button is pushed, stop the motors and throw the ball.
Always run the motors from the RC Transmitter.
if ( GetDigitalValue(3) == CLOSED )
{
SetMotors(127);
ThrowBall();
}
Tank2 (PORT_1, CHANNEL_3, CHANNEL_1, LEFT_MOTOR, RIGHT_MOTOR, 1, 0);
48
Chained Conditionals
You can have a series of
else if statements chained together. If condition 1 is true, its body will be executed. All conditionals below it
will be skipped. If condition 1 is false, condition 2 will be evaluated. If condition 2 is true, its body will be executed, and all other conditionals
below it will be skipped, etc.
if ( condition1 ) {
...done if condition 1 is true...
}
else if ( condition2 ) {
...done if condition 2 is true...
}
else if ( condition3 ) {
...done if condition 3 is true...
}
49
Chained Conditional Example
If one switch is closed, stop the motors and throw the ball. Otherwise, if the other switch is closed, pick up a ball. Always run the motors from the operator interface.
if (GetDigitalInput(4) == CLOSED)
{
SetMotors(127);
ThrowBall();
}
else if (GetDigitalInput(5) == CLOSED)
{
PickUpBall();
}
Tank2 (PORT_1, CHANNEL_3, CHANNEL_1, LEFT_MOTOR, RIGHT_MOTOR, 1, 0);
50
Final Conditional
You can end a conditional series with an
else statement. The body of the else will be done if all conditions above it are false.
if ( condition1 ) {
...done if condition 1 is true...
}
else if ( condition2 ) {
...done if condition 2 is true...
}
else if ( condition3 ) {
...done if condition 3 is true...
}
else {
...done if none of the conditionals above are true...
}
51
Final Conditional Example
If one switch is closed, stop the motors and throw the ball. Otherwise, if the other switch is closed, don't change the motors and pick up a
ball. Now the motors will be run from the operator interface only if neither switch was
closed.
if (GetDigitalInput(4) == CLOSED)
{
SetMotors(127);
ThrowBall();
}
else if (GetDigitalInput(5) == CLOSED)
{
PickUpBall();
}
else
{
Tank2 (PORT_1, CHANNEL_3, CHANNEL_1, LEFT_MOTOR, RIGHT_MOTOR, 1, 0);
}
52
Conditional Body
You can have assignment statements, calls to functions (subroutines), other conditionals, and loops inside of the body of a conditional.
Remember to put the { } around the body of the conditional.
Drag and drop EasyC does this for you
53
Conditionals and Loops
Conditionals can go inside of loops.
while (1 == 1)
{
if (GetDigitalInput(4) == CLOSED)
{
ThrowBall();
}
else if (GetDigitalInput(5) == CLOSED)
{
PickUpBall();
}
Tank2 (PORT_1, CHANNEL_3, CHANNEL_1,
LEFT_MOTOR, RIGHT_MOTOR, 1, 0);
}
54
Functions
Functions are named sections of code that can be called from other sections of code.
Also called subroutines. Every executable statement in C must live in a function.
The function definition specifies the “return value” and the “parameters” of the function:
<return value> FunctionName(<param1>, <param2>)
{
<function body>
} Return value is “void” if nothing is to be returned Parameters is “void” if nothing is to be passed in
55
Function Example
Function call
pwm1 = limit((px_1 – 127) * 2 + 127); Function definition
int limit(int value)
{
if (value > 255)
{
return 255;
}
else if (value < 0)
{
return 0;
}
else
{
return value;
}
} The statements inside the function are called the body of the function.
56
Function Example
Another function call
moveForward(147); Function definition
void moveForward(unsigned char speed)
{
SetPWM(LEFT_MOTOR, 255 – speed);
SetPWM(RIGHT_MOTOR, speed);
}
57
Functions for Program Structure
count = 1;
while (count <= numberBalls)
{
SetPWM(WINCH_MOTOR, 180);
while (GetAnalogValue(WINCH_POT) < 200) { }
SetPWM(WINCH_MOTOR, NEUTRAL);
SetPWM(THROW_MOTOR, 255);
while (GetDigitalValue(THROW_LIMIT_SWITCH_THROW) == OPEN) { }
SetPWM(THROW_MOTOR, NEUTRAL);
SetPWM(THROW_MOTOR, 0);
while (GetDigitalValue(THROW_LIMIT_SWITCH_ARMED) == OPEN) { }
SetPWM(THROW_MOTOR, NEUTRAL);
SetPWM(WINCH_MOTOR, 0);
while (GetAnalogValue(WINCH_POT) > 0) { }
SetPWM(WINCH_MOTOR, NEUTRAL);
count = count + 1;
}
58
Functions for Program Structure
count = 1;
while (count <= numberBalls)
{
raiseWinch();
throwBall();
resetBallThrower();
lowerWinch();
count = count + 1;
} Much easier to read and understand!
59
Functions for Program Structure
void raiseWinch(void)
{
SetPWM(WINCH_MOTOR, 180);
while (GetAnalogValue(WINCH_POT) < 200) { }
SetPWM(WINCH_MOTOR, NEUTRAL);
}
void throwBall(void)
{
SetPWM(THROW_MOTOR, 255);
while (GetDigitalValue(THROW_LIMIT_SWITCH_THROW) == OPEN) { }
SetPWM(THROW_MOTOR, NEUTRAL);
}
void resetBallThrower(void)
{
SetPWM(THROW_MOTOR, 0);
while (GetDigitalValue(THROW_LIMIT_SWITCH_ARMED) == OPEN) { }
SetPWM(THROW_MOTOR, NEUTRAL);
}
60
Function Prototypes
Description of the function. Usually placed in .h files. A prototype is needed if the function is used before
it is defined, or if it is written in one .c file and used in a different .c file.
void raiseWinch(void);
void throwBall(void);
void resetBallThrower(void);
int limit(int value);
Drag and drop EasyC generates these for you
61
Some Useful Terms
Compiler Turns C program into the machine language for the
controller. Has a preprocessing phase (for #define).
pwm1 = limit(p1_x*2, 255); Machine Language
What the robot controller actually understands. Found in .HEX files.
10110100
11100101
00001011 Loader
Loads the machine language output of the compiler (along with other stuff) into the robot controller.
62
Macros
Allows programmer to create aliases for variables, constants, or expressions which make a program easier to read.
The compiler replaces the aliases with their values before the compiler produces machine code.
Definitions usually placed in .h files. Not required, but usually the alias names are written
in all capital letters.
63
Macro Example
Can give constants a name that is easier to understand. The definitions:
#define LEFT_MOTOR 0
#define RIGHT_MOTOR 1 In your program code:
SetPWM(LEFT_MOTOR, 147);
SetPWM(RIGHT_MOTOR, 107); The compiler sees:
SetPWM(0, 147);
SetPWM(1, 107); Find this feature in the Globals section of the Main function
window in EasyC or via Options|Program Globals Perfect for robot controller I/O
64
Comments
Comments are human readable descriptions of what the program is doing.
The computer does not pay attention to these comments; they are only for humans reading the code. The compiler throws them away.
speed = SPEED(30); // This comment goes to end of line.
/*
This comment covers several lines until the bottom
asterisk slash. The comments to the right of the 3
and 4 are legal, but makes the code hard to read.
*/
SetPWM(3 /* Left motor */, speed);
SetPWM(4 /* Right motor */, speed);
65
Things To Remember
Use semicolons where necessary. Use after variable declarations, assignment
statements, function (subroutine) calls, function prototypes.
Do not use semicolons after #defines or comments or function definitions.
Conditionals and loops should have curly braces
{
and
}
around the body of the conditional or loop. Generally drag and drop EasyC will place them in the
right spots for you
66
Programming Tips and Tricks
67
Programming Tips and Tricks
Simplify your code Microcontrollers are not your PC! They are very slow (MHz not GHz) and your drivers
will notice lag if you try to do too much Don’t do floating point math (fractions)
Or if you must, keep it very simple and only do it once, not in a loop
All floating point math is emulated and takes thousands of instructions to perform
Comment (usefully) Use consistent naming conventions Use functions to help organize and reuse common
code
68
Programming Tips and Tricks
Document your inputs and outputs Summarize the needed ones at the start Consider making #define’s so the code is more
self-documenting Draw/print a picture of the mechanical wiring
The controller configuration dialog in easyC is very useful for this
Label the wires on the robot – makes it easy to reconnect a wire that’s been disconnected
Test all of your limit switches every time you move wires around
69
Example Controller Configuration
70
Parting Thoughts
Start early! Have fun! Resources:
Chief Delphi: http://www.chiefdelphi.com/
71