RobotC Programming for VEX-IQ
RobotC Programming for VEX-IQ
1|Page
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
3|Page
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Scope
There are over hundreds of APIs. You should look into the Functions Explorers and their help windows to
explore them. Most of them are listed in the TMotorTypes or RobotsInstrinsics.h.
In this tutorial, only the most commonly used APIs and basic tools are covered in this tutorial. You should
always consult the Functions Explorers. You often can right-click on a particular function or system variables to
find out what other APIs, RobotC/VEX-IQ data types, etc. available.
Background needed:
1. You should have already known some basics in programming in C/C++:
o Primitive data types: char, int, float, long, bool, unsigned…
o Some pre-processor directives: #define , #undef, #include
o Basics in control structure statements:
o if … else if …. Else
o switch
o while … do { } while
o Single array
2. Basics in working with functions:
o void func()
o void func(int, …. )
o int func(…)
o bool func(…), etc.
3. More advanced ones will be good too:
o typedef
o Simple pointers
o Simple structure
o typedef enum
Download Firmware
In order to be able to begin programming your VEX-IQ robot, you must first download the most up to date
firmware from the VEX website. Go to http://www.vexrobotics.com/vexiq/software/firmware, and follow the
instructions to get started. (You must also download RobotC firmware before programming. Simply open
RobotC and select Firmware Download from the top of the screen.)
This tutorial was written based on Version 4.25, and VEX IQ Firmware Update Utility for Windows dated
July of 2014. You must follow their installation process of this firmware because it may actually need to update
the firmware of the sensors and motor devices as well.
4|Page
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
The following preprocessor directives will be inserted at the top of your program:
#pragma config(Motor, motor9, LM,tmotorVexIQ, PIDControl, encoder)
#pragma config(Motor, motor10,RM,tmotorVexIQ, PIDControl, encoder)
#pragma config(Motor, motor11,ARM,tmotorVexIQ, PIDControl, encoder)
setMotorEncoderUnits(encoderCounts);
SensorType[LM] = tmotoVexIQ;
setMotorBrakeMode(LM, motorBrake);
…etc.
5|Page
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
The following preprocessor directives will be inserted at the top of your program:
#pragma config(Sensor, port1, Leye, sensorVexIQ_ColorGrayscale)
#pragma config(Sensor, port2, Reye, sensorVexIQ_ColorGrayscale)
#pragma config(Sensor, port3, Lping, sensorVexIQ_Distance)
#pragma config(Sensor, port4, Rping, sensorVexIQ_Distance)
#pragma config(Sensor, port5, Gyro, sensorVexIQ_Gyro)
#pragma config(Sensor, port6, DiscoLight, sensorVexIQ_Color12Color)
#pragma config(Sensor, port7, FrontBumper, sensorVexIQ_LED)
#pragma config(Sensor, port8, BackBumper, sensorVexIQ_Touch)
SensorType[Reye] = sensorVexIQ_ColorGrayscale;
SensorType[Lping] = sensorVexIQ_Distance;
SensorType[Rping] = sensorVexIQ_Distance;
SensorType[Gyro] = sensorVexIQ_Gyro;
SensorType[DiscoLight] = sensorVexIQ_Color12Color;
SensorType[FrontBumper] = sensorVexIQ_LED;
SensorType[BackBumper] = sensorVexIQ_Touch;
6|Page
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
You should look up all the display functions from the Function explorers.
Using Sound
Play a sound to signal a certain stage of execution can also be very informative too if you use wisely.
playSound(TSounds);
where Tsounds can be in many values such as soundTada, soundSiren2, etc.. Right click on the function in
the IDE, the IDE will open RobotCIntrinsic.c where you will find the sounds available.
You can play with playSoundfile(…) and playNote(…), but these usually are not very useful in real time
debugging.
7|Page
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Set breakpoint Step into each expressions. Watch the change of the variable here.
8|Page
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
9|Page
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Warm Up - challenge
Challenge 2: Write a program to create a variable called “ct”. Create a loop so that your screen will display the
following:
1
2
3
4
5
6
7
8
Challenge 3:
Draw a small rectangle with coordinates with top left point at (10, 20) and bottom right point at (25, 5), .e.g
drawRect(10,20, 25, 5). Make it expand to the max size of screen, then shrink back with dimension of 1 pixel
width and height.
Challenge 4: Given the radius. Generate Circumference and Area of a circle. Only 2 decimal places. Do it in
one’s increment four times. E.g.
R Cir Area
================
7.00 43.96 314.15
14.00 65.94 153.86
21.00 131.95 1385.44
28.00 175.93 2463.01
10 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Challenge 5: Given the width and length of a rectangle. Generate the area of the biggest circle to fit inside this
rectangle. E.g.
W L CirA
2 53.14
Challenge 6: Draw the rectangle, as well as the painted complete circle fit inside the rectangle.
W L CirA
50 60 1962.50
Challenge 7: Given the measurement of base and height of a right angle triangle, find out the measurement of
the hypotenuse of the triangle. (Pythagorean Theorem)
B H Hyp
50 60 1962.50
11 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
3. Write a program to calculate a square root of a number using Newton’s method. This is how it works:
12 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Type : sensorVexIQ_Motor
You may set the ports to many other type of devices. Look into the TMotorTypes.h at your RobotC installation
directory.
Instead of using the configuration setup wizard, you may do inside your code, e.g.:
SensorType[motor9] = sensorVexIQ_Motor
Note: In the configuration wizard, if you should check the “reversed” box for your a motor port, it will be in a
mirrored position on your chassis. Depending on how your mount your motors, this may avoid confusion by
ensuring that both motors drive in a forward direction when positive speed values are passed to them and vice
versa.
There are other options such as set up for motor feedback control. This is outside the scope of this tutorial.
RobotC comes with a good amount basic motor movements. Use their samples will be sufficient.
14 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Type : sensorVexIQ_Touch
Before you can use your sensors, you must configure them. Using the Motors and Sensors Setup window is a
quick and easy way to do so. Create a name for each of your sensors and identify their respective port
locations. However, remember: all “pragma” statements must be at the top of your file.
Instead of using the configuration setup wizard, you may do inside your code, e.g.:
SensorType[ port3 ] = sensorVexIQ_Touch
repeatUntil(getBumperValue(port8) == 1)
{
//Set both left and right motors to run at 50% speed (continuously)
setMotorSpeed(motor1, 50);
setMotorSpeed(motor6, 50);
}
//Stop the motors after the movement is complete
setMotorSpeed(motor1, 0);
15 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
setMotorSpeed(motor6, 0);
This sensor serves not so much as a sensor but output device. This is more for fun elements. The samples
from RobotC has already well identified how to use it. Therefore, we will skip this topic .
Type: sensorVexIQ_LED
16 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
The color sensor is an input device that can measure colors in a variety of ways. It can measure simple colors
(Red, Blue, Orange, etc), overall color hue, independent red, blue and green channels, ambient light, and even
the proximity of objects. The values returned by the sensor depend on which command is being used to
control it (below). The default port for the color sensor is port #9.
Values returned will vary depending on the surface being detected, ambient light, and other environmental
factors (example: brighter ambient light may cause the sensor to return higher values than average.)
For those familiar with the NXT light sensor, the methodology is very similar. You must take the sensor
readings over dark and light, then average those two numbers to get your threshold.
Types: sensorVexIQ_ColorNotActive
sensorVexIQ_ColorGrayscale
sensorVexIQ_ColorHue
sensorVexIQ_Color12Color
Configures the color sensor to return the grayscale value of a detected object.
1. 3 ... 359
Darkest Brightest
Actual values returned will vary depending on the surface being detected, ambient light, and other
environmental factors (example: brighter ambient light may cause the sensor to return higher average values
than normal.) *Note that due to the nature of our typical robotics challenges, we will normally focus on using
Color Greyscale mode.
17 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Configures the color sensor to return values between 0 and 255, with each value corresponding to a specific
shade of the color spectrum.
359
255
18 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
long getColorValue(nDeviceIndex);
long getColorHue(nDeviceIndex);
long getColorValue(nDeviceIndex);
TSimpleColors getColorName(nDeviceIndex);
19 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
20 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Type : sensorVexIQ_Distance
The distance sensor measures its distance from an object by sending out high frequency sound waves. It
measures the amount of time a sonar wave takes to reflect off of an object and return to the sensor. The
distance sensor also has the ability to detect three different object distances at the same time.
The closest object to the distance sensor can be measured with the getDistanceValue command. The
getDistanceSecondStrongest command can be used to get the distance of the second closest object to the
sensor, and the largest object can be detected with the getDistanceMostReflected command.
Note that the distance sensor returns all values in millimeters for maximum precision. The default port for the
distance sensor is port #7.
21 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
22 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Although the following functions are not commonly used, I found them to be indeed very useful. However,
you will need to do some experiments to polish the usage.
typedef enum
{
strongestSignal = 0,
secondStrongestSignal = 1,
mostReflective =2
} TDistanceFilterMode;
23 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Type: sensorVexIQ_Gyro
24 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
void resetGyro(nDeviceIndex)
long getGyroDegrees(nDeviceIndex)
float getGyroDegreesFloat(nDeviceIndex)
Long getGyroRate(nDeviceIndex)
25 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
26 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
By default, the rotation of the VEX motor is measured in degrees (360 degrees per rotation). Therefore,
assuming that your wheel is attached directly to the motor, you can easily convert centimeters traveled to
rotations of the motor:
1 𝑟𝑜𝑡𝑎𝑡𝑖𝑜𝑛 𝑜𝑓 𝑚𝑜𝑡𝑜𝑟 = 𝑐𝑖𝑟𝑐𝑢𝑚𝑓𝑒𝑟𝑒𝑛𝑐𝑒 𝑜𝑓 𝑡𝑖𝑟𝑒
360 𝑑𝑒𝑔𝑟𝑒𝑒𝑠 = 𝜋 ∗ 𝑑𝑖𝑎𝑚𝑒𝑡𝑒𝑟 𝑜𝑓 𝑡𝑖𝑟𝑒 (𝑖𝑛 𝑐𝑚)
360
= 1 𝑐𝑚
𝜋 ∗ 𝑑𝑖𝑎𝑚𝑒𝑡𝑒𝑟
360
The quantity represents degrees the motor rotates when the tire travels one cm. We can use
𝜋∗𝑑𝑖𝑎𝑚𝑒𝑡𝑒𝑟
this conversion factor multiplied by desired centimeters in order to tell our robot how many degrees to rotate
the motor in order to reach the target.
27 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Must use waitUntilMotorStop(nMotorIndex) command to ensure that the motor reaches its
target (see sample code below)
28 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
29 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
resetMotorEncoder(motor1);
resetMotorEncoder(motor6);
setMotorTarget(motor1, target, 50);
setMotorTarget(motor6, target, 50);
while ( StillMoving(motor1) || StillMoving(motor6) )
sleep(10);
}
30 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
This section will use line tracing as an example for using feedback control.
The full range of weighted values is shown below. We assign a numerical value to each one.
Binary Value Weighted Value
00001 4
00011 3
00010 2
00110 1
00100 0
01100 -1
01000 -2
11000 -3
10000 -4
00000 -5 or 5 (depending on the previous value)
Use this weighted values to adjust the turning. The range of possible values for the measured position is
-5 to 5.
Now, this method is also considered to be feedback control system.
31 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
PID stands for Proportional – Integral – Derivative and is a control loop feedback mechanism widely used in
industrial control systems. Basically, it is a way to calculate an error value as the difference between a
measured process variable and a desired setpoint. This is often referred as “Closed Loop” System vs. “Open
Loop”. “Closed Loop” system means output is self-adjusted with signal feedback, while “Open Loop” system
generates output without feedback.
The goal is to minimize the error by adjusting the process through the use of manipulated variables .
To simplify, let’s use one of our typical activities – line tracing. Our goal is going to be to trace a line smoothly
using only one color sensor.
32 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
“I” value (ki) Set a factor value which works like a It tells us if the robot has been on the line in
knob to tune accumulative errors the last few moments or not. The goal is to
over time. watch the elapse time in between the time to
bring the bot to the ideal target location (ie..
the threshold)
“D” value (kd) Set a factor value which works like a It tells a prediction of future errors.
knob to tune the possible future This “D” means rate of change of error from
error. the last reading done for the control output.
Effects
Term Expression Effect
Proportional Kp * error It reduces a large part of the error based on present time error.
Reduces the final error in a system. Cumulative of a small error over time
Integral Ki * sumError would help us further reduce the error. However, you must extra precaution of
this one. We will go through this later in this chapter.
Derivative Kd * dError / dt Counteracts the Kp and Ki terms when the output changes quickly.
Note: Kp, Ki, and Kd will determine the the magnitude of each turn.
leftpower = tp + totalErr
rightpower = tp - totalErr
Let’s take each of these factors and parameters and see how to code them.
Should always start with something smaller first, say 30, in order to ensure that we don’t stray too far from the
line.
33 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Kp is essentially the factor that you must multiply with the error to get the needed turn. A good rule of thumb
for calculating Kp is to take the target power level for your motors and divide by the maximum possible error.
Kp = 30/110 = 0.27
Now we can say “for every 1 unit of change in the error, we will increase the power of one motor by 0.27”. The
other motor’s power gets decreased by 0.27.
In pseudo code:
Kp = 0.27
tVal = 150
Tp = 30
while (true)
{
currValue = getcolorsensorval
currErr = currValue – tVal
turn = Kp * currErr
lpwr = Tp + turn;
rpwr = Tp – turn;
}
*Note that both Kp and Tp can and should be fine-tuned, based on the performance of the code.
34 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Our “I”, or integral, term is going to keep track of the sum of the errors. Each time we get a color sensor
reading and calculate an error, we will add that error to an integral variable:
integral = integral + error
Next, we will create another proportionality constant, called kI, and multiply that by our integral. This product
is then added to Kp*error to get a new value for the totalErr:
In pseudo code:
Kp = 0.27
Ki = 0.1
tVal = 150
Tp = 30
integralErr = currErr = 0
while (true)
{
currValue = getcolorsensorval
currErr = currValue – tVal
integralErr = integralErr + currErr
turn = Kp * currErr + Ki * integralErr
lpwr = Tp + turn;
rpwr = Tp – turn;
*When fine-tuning your code, you may find that the integral is increasing too quickly. If the line is a spiral, you
may even add data overflow. Therefore, you may use some mechanism to do a reset it the line may indeed
go spiral. Possible ways to do this:
1) set some kind data most upper and lowest bound.
2) reset once in a while
3) use a dynamic Ki value based
35 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
Our “D”, or derivative, term is going to look into the future by assuming that the next change in the error is the
same as the last change in the error. This means that the next error is expected to be the current error plus the
change in the error between the two preceding sensor readings. If we were to plot our error on an xy plane,
this change in error between two consecutive points would be the slope of the line, which is what a derivative
is.
Why is the derivative so useful? If the current error is larger than the previous error, then the D term tries to
correct the error. If the current error is smaller than the previous error, then the D term tries to stop the
controller from correcting the error. The latter is particularly useful. If the error is getting close to zero, then
we are approaching the point where we want to stop correcting. Since the system probably takes a while to
respond to changes in the motors’ power, we want to start reducing the motor power before the error has
actually gone to zero, otherwise we will overshoot.
Sensors:
Sensors are the first requirement in the process of line following. When selecting the type of sensors, there are
three things you need to keep in mind – response time, sensitivity and ambient light protection. There is
good tutorial about how to choose the right sensors at
http://www.societyofrobots.com/member_tutorials/book/export/html/350 .
36 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
There are two more parameters which affect kp : battery power level and motor current. Unfortunately,
this is not something easy to tell unless you have done a good amount of data collection.
2) Simply put :
a. if robot wobbles tune Kp and vice versa.
b. If robot turns too slow, tune Kp
e.g. Start with 1.0, too sluggish… change to 3.0, wobbles too much…
change to 2.0… too much…. Change to 1.5..etc.
3) Tune the Kp value till the robot smoothly follows a curvy line even. Your robot should go with no
acceleration on straight lines, but speeds up the turn on curves.
4) But then, depending the size of your chassis and location of the light sensors, your robot may very likely
to struggle around 90 degrees turn.
If (! At threshold)
ki = ki + 0.1;
else
ki = 0;
But, there are times when the response time is not fast enough, your integral value may get really high
at times. Then, your robot will easily be off line even when the kp alone works well by itself.
37 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
3) So, considering that usually the “kp” takes care of the line tracing pretty well, except 90 degree inner
turns. See the diagram below…
If (see dark)
ki = ki + 0.1;
else
ki = 0;
You really need to test it out with your robot to see which works better.
Very important point, because of the fact that this takes accumulative errors, you must make sure to
minimum noise. Two things you should at least do it yourself:
a) Shield the light sensor from ambient light
b) Keep the distance between the light sensor to the surface consistent.
38 | P a g e
RobotC for VEX-IQ Computational Thinking and Engineering For Kids
39 | P a g e