710 likes | 888 Views
Introduction to VEX Programming with EasyC. Peter Johnson Northrop Grumman Space Technology Programming Mentor, Beach Cities Robotics (FRC/FTC/VRC Team 294) 1 Mar 2008. Agenda. Getting Started The Big Picture The Robot Controller Motors, Servos, and Sensors The C Programming Language
E N D
Introduction to VEX Programming with EasyC Peter Johnson Northrop Grumman Space Technology Programming Mentor, Beach Cities Robotics (FRC/FTC/VRC Team 294) 1 Mar 2008
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
Programming – What Binds It All Together 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?
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!
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
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)
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
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
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
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
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)
The C Programming Language Mostly from robotics.hideho.org Fall 2007 Workshops
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++
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); }
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);
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
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);
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.
C Syntax – No Whitespace in Names • Spaces do matter in names. • The following statement has two errors: Set PWM(LEFT _MOTOR, 157);
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); } }
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.
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.
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.
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.
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.
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
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;
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.
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
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
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
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)
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)
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
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); }
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);
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…
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(); }
For Loops • The previous loop count = 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(); }
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.
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
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)... }
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);
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... }
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);