Let the robot enter evacuation area built according to RCJ Rescue Line rules. Follow right wall but do not allow the robot to exit. Base Your code on the example we already made for this purpose, but notice that it was not perfect. If the robot follows the wall shortly, it will not have enough time to align to wall properly. If it is going too much leftwards (inside the room), it will usually not be a problem since it will detect the wall after the exit at a longer distance, the situation it can overcome. However, if it is going too much righward (toward the wall), it will partially exit the room, probably hitting door frame. This is the problem You have to solve. The former code:
Solution
void RobotLine::loop() {
static bool avoidingExit = false;
if (frontLeft() < avoidingExit ? 200 : 90) // Wall ahead?
go(-50, 50);
else {
if (rightFront() > 400) { // Exit?
go(50, 50);
avoidingExit = true;
}
else {
int error = (rightFront() - 100) * 0.5;
error = constrain(error, -50, 50);
go(50 + error, 50 - error);
avoidingExit = false;
}
}
}
The problem is that front lidar's detection angle is rather narrow. If it detects front wall only at 90 mm, like it has been by now, it will be too late. It should start the detection at a greater distance, like 200 mm, when the prospects for detecting are better.
In order to know that it is in process of avoiding exit, it has to remember that fact and use it in the next run. The way to do it is to use a variable. As there are only 2 states (avoids exit or not), a Boolean variable will suffice. Hence, we first declare one: "avoidingExit".
Find in the code 2 lines:
avoidingExit = true;
...
avoidingExit = false;
Note that the variable is set to "true" if there is no right wall (thus, exit) and set to "false" as soon as a wall is found again.
Let's examine the first pass and assume there is a wall on the right side.
- First line declares "avoidingExit" and sets it to "false".
- In the line that checks if there is a wall ahead, there is short hand "if":
avoidingExit ? 200 : 90
As "avoidingExit" is to "false", the result will be 90, as before. So, the robot will avoid a front wall as usual.
- In the last "else" there is this line:
avoidingExit = false;
Because "avoidingExit" is "false" already, it will do nothing.
Now, let's assume the right wall disappeared.
rightFront() > 400
will will be true, "if" will execute the next block setting "avoidingExit" to "true".
- The function will end and the new pass will start. As "avoidingExit" is now "true",
avoidingExit ? 200 : 90
will return 200 forcing the robot to avoid a wall at 200 mm. That is the behaviour we tried to achieve.
As soon as it detect the right wall again, "avoidingExit" will be reset to "false" and the normal wall following will resume.
This program will not be a perfect solution, but more an idea for You how You can solve this problem. You should change parameters and probably add some more program logic in order to get satisfactory trajectory.