Line Robot - Basic lessons - Exercises - Follow any wall
This exercise closely matches task of following wall in RCJ Rescue Line evacuation zone.
Task: follow any of the 2 side walls.
If any side wall is closer than 300 mm, follow it. Turn in front of a wall and continue following the next wall. Always drive one pair of wheels at chosen maximum speed. Use built-in function turn() to turn left the robot left or right by 90°. To turn it left, call "turn(-90)". "-90" is number of degrees clockwise.
Solution
void RobotLine::wallFollow() {
const int MAXIMUM_WALL_MM = 300; // If distance bigger than this value, do not follow wall.
const int FOLLOW_WALL_MM = 90;
const int FOLLOW_WALL_STRENGTH = 5; // The bigger this factor, the more will the robot turn.
const int WALL_AHEAD_MM = 80;
const int TOP_SPEED = 70;
static bool followLeftWall; // Used to determine where to turn if wall ahead.
int left = leftFront();
int right = rightFront();
// No wall in sight, just go straight ahead.
if (left > MAXIMUM_WALL_MM && right > MAXIMUM_WALL_MM)
go(TOP_SPEED, TOP_SPEED);
// Follow wall.
else {
followLeftWall= left < right; // Choose closer wall
int error = ((followLeftWall? left : right) - FOLLOW_WALL_MM) * FOLLOW_WALL_STRENGTH; // Negative error - robot too much to the left, it should go right
if (!lastFollowedLeft)
error = -error;
// Drive one side at top speed.
go(error < 0 ? TOP_SPEED : TOP_SPEED - error, error < 0 ? TOP_SPEED + error : TOP_SPEED);
}
// Wall ahead
if (leftFront() < WALL_AHEAD_MM)
// Turn away from the side wall.
turn(followLeftWall? 90 : -90);
}
}
This is one of many possible solutions.
- Keyword "const" is not important. It states that the variable being declared will not change value. The first block, constants, defines parameters that determine how the robot will behave. It is not necessary but enables You to easier change them in one place.
- lastFollowedLeft will determine which wall is being followed, the closer one. It also remembers (static!) the value for the next pass through the function.
- First "if" evaluates "true" if no wall is in sight. The robot will continue straight ahead.
- error variable obviously stores error and the function "go()" uses it to drive the robot, trying to keep it close to 0. Check various positions of the robot and the wall to see why this logic is correct for both walls and for robot being too close or too far from the wall.
- Last "if" avoids wall ahead. turn() is a very handy function which uses compass to turn exactly.