Using the Sharp IR Sensor to Follow Walls
|
An Unusual Way of Following Walls
One way of following walls is to move the sensor onto the side of the robot and have it measure the distance to the wall and program the robot to correct itself every time it gets too close or too far from the wall. The problem that this method often encounters is that the robot can easily turn too steeply into or away from the wall, and the IR sensor will not pick up the correct distance. Correcting for this problem requires a lot more code and more sensors.
The Idea
Fortunately, there is another way of going about it that we can do without changing anything on the robot. What we want to do is "leapfrog" along the wall, using a code that is similar to the one we used to avoid obstacles. The robot will pick up the wall, turn, and then drive in an elongated swing turn back to the wall. the motor power difference will be small so that the robot drives almost straight during this swing turn but slowly banks back towards the wall, and eventually hits it, detects it, turns again, and does another 'leap' to a point further down the wall. And if the robot hits a corner in the wall, then it will either detect the wall that is now suddenly in front of it, turn, and start leapfrogging down that wall, or its 'leap' will carry it around to the new wall (or the other side of the wall if it an end point).
Coding
To start out, we're simply going to copy our obstacle evasion code into a new file for following walls. (This will also automatically configure the robot the same way that it was in the other program).
#pragma config(CircuitBoardType, typeCktBoardUNO) #pragma config(PluginCircuitBoard, typeShieldDFRobotMotor) #pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0) #pragma config(Sensor, anlg2, sharpIR, sensorAnalog) #pragma config(Motor, motor_5, rightServo, tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl5, dgtl4) #pragma config(Motor, motor_6, leftServo, tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl6, dgtl7) //*!!Code automatically generated by 'ROBOTC' configuration wizard !!*// task main() { int threshold=300; //The value for the distance you want to keep from the wall. Values under 200 are not advised. while (true) { if (SensorValue[sharpIR] >= threshold) { //there is something closer than the threshold value //Back up motor[leftServo] = -100; motor[rightServo] = -100; wait1Msec(500); //turn out of the way motor[leftServo] = -100; motor[rightServo] = 100; wait1Msec(500); } else { //nothing in the threshold range // move forward motor[leftServo] = 100; motor[rightServo] = 100; } } } |
Now, all we have to do is change the "move forward" command to be a long swing turn. Since we're turning right to avoid the wall, we should curve left to head back into it. We'll set the Left servo to 105 instead of 100.
#pragma config(CircuitBoardType, typeCktBoardUNO) #pragma config(PluginCircuitBoard, typeShieldDFRobotMotor) #pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0) #pragma config(Sensor, anlg2, sharpIR, sensorAnalog) #pragma config(Motor, motor_5, rightServo, tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl5, dgtl4) #pragma config(Motor, motor_6, leftServo, tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl6, dgtl7) //*!!Code automatically generated by 'ROBOTC' configuration wizard !!*// task main() { int threshold=300; //The value for the distance you want to keep from the wall. Values under 200 are not advised. while (true) { if (SensorValue[sharpIR] >= threshold) { //there is something closer than the threshold value //Back up motor[leftServo] = -100; motor[rightServo] = -100; wait1Msec(500); //turn rignt out of the way motor[leftServo] = -100; motor[rightServo] = 100; wait1Msec(500); } else { //nothing in the threshold range // Swing back in left motor[leftServo] = 105; motor[rightServo] = 100; } } } |