© Fort Street High School Robotics
To begin, you're expected to know how to manipulate C variables, obtain sensor values and output motor speeds.
Make sure you can:
So far, we have learnt how to detect certain colours that are within certain ranges. For example, we can get the colours from both sensors, add them together, and repeatedly check if they are between 300 and 400.
Note: code won't work when simply copy pasting.
task main() {
// Initialise sensor variables (left rgb, right rgb)
int lr, lg, lb;
int rr, rg, rb;
int lall, rall; // Store sums of rgb
// Repeatedly get sensor values and process them
while (1) {
getColorRawRGB(sensorLeft, lr, lg, lb);
getColorRawRGB(sensorRight, rr, rg, rb);
lall = lr + lg + lb;
rall = rr + rg + rb;
// if both are between 300 and 400, stop
if (lall > 300 && rall > 300 && lall < 400 && rall < 400) {
motor[mLeft] = 0;
motor[mRight] = 0;
}
// Otherwise, continue forwards
else {
motor[mLeft] = 20;
motor[mRight] = 20;
}
}
}
The thresholds here is "between 300 and 400". It's easy to see that this can be extended to thresholds for white/white, white/black, black/white and black/black.
// #defines are CONSTANTS, they stay the same throughout the whole code. Use them for fixed numbers like thresholds.
#define L_MIN_WHITE 200
#define L_MAX_WHITE 1000
#define R_MIN_WHITE 200
#define R_MAX_WHITE 1000
#define L_MIN_BLACK 0
#define L_MAX_BLACK 199
#define R_MIN_BLACK 0
#define R_MAX_BLACK 199
task main() {
// Initialise sensor variables (left rgb, right rgb)
int lr, lg, lb;
int rr, rg, rb;
int lall, rall; // Store sums of rgb
// Repeatedly get sensor values and process them
while (1) {
getColorRawRGB(sensorLeft, lr, lg, lb);
getColorRawRGB(sensorRight, rr, rg, rb);
lall = lr + lg + lb;
rall = rr + rg + rb;
// both white, go forward
if (lAll > L_MIN_WHITE && lAll < L_MAX_WHITE && rAll > R_MIN_WHITE && rAll < R_MAX_WHITE) {
motor[mLeft] = 20;
motor[mRight] = 20;
}
// left is white, right is black, turn right
else if (lAll > L_MIN_WHITE && lAll < L_MAX_WHITE && rAll > R_MIN_BLACK && rAll < R_MAX_BLACK) {
motor[mLeft] = 20;
motor[mRight] = 0;
}
// ... etc
}
}
Proportional line follow is a smoother way of doing line follow. Thresholds usually make jerking motions, which aren't desireable.
Threshold line follow is bad because:
Instead, we want to incrementally adjust the speeds based on how dark or how bright the light sensor reads.
How? Consider the extremes. Let's say very black is 1 and white is 5
Cool? We can scale this number to fit the motor speeds. We basically need to use these values to make the left and right motors change speed.
Base speed = 20
l, r => difference | motor left | motor right
5, 5 => 0 | 20 + 0 | 20 - 0
5, 1 => 4 | 20 + 4 | 20 - 4
1, 5 => -4 | 20 + (-4) | 20 - (-4)
In RobotC, we can code this up and use some extra variables for scaling.
// #defines are CONSTANTS, they stay the same throughout the whole code. Use them for fixed numbers like thresholds.
#define L_MIN_WHITE 200
#define L_MAX_WHITE 1000
#define R_MIN_WHITE 200
#define R_MAX_WHITE 1000
#define L_MIN_BLACK 0
#define L_MAX_BLACK 199
#define R_MIN_BLACK 0
#define R_MAX_BLACK 199
task main() {
// Initialise sensor variables (left rgb, right rgb)
int lr, lg, lb;
int rr, rg, rb;
int lall, rall; // Store sums of rgb
int difference;
float multiplier = 0.05; // multiplier to the speed differences
// Repeatedly get sensor values and process them
while (1) {
getColorRawRGB(sensorLeft, lr, lg, lb);
getColorRawRGB(sensorRight, rr, rg, rb);
lall = lr + lg + lb;
rall = rr + rg + rb;
difference = lall - rall;
motor[mLeft] = 20 + difference * multiplier;
motor[mRight] = 20 - difference * multiplier;
// So, the extremes are left-right = 1000 - 150
// difference = 850
// Multiplying by multiplier 850 * 0.05 = 42.5
// left motor goes at 20 + 42.5 = 62.5
// right motor goes at 20 - 42.5 = -22.5
// Is this too much? yes
}
}