Navigating the simple maze using switches
|
Concepts
We have already navigated a maze using timing. However, that only works it you know that the path will always be the same length. What if the maze was twice as big? The times used to drive straight would no longer be correct. We can solve this problem by using the BoeBot whiskers to detect the walls of the maze. By using the walls to find the distance, it is possible to change the lengths of the straight paths to almost any value. This approach works in this particular case since the robot only needs to turn where there is a wall. Replacing the time based pause with one that waits for the whisker to become low and adding code to back away from the object before turning should allow the robot to use this method of maze-solving.
Programming
The robot configuration for this program will be the same as the one in the 'Detecting Obstacles with a Switch' program .
- Parallax Boe Shield
- leftServo on pin 10 as a continuous rotation servo
- rightServo on pin 11 as a reversed continuous rotation servo
- leftSwitch on pin 7 as a Digital Input
- rightSwitch on pin 8 as a Digital Input
We need to add a function to back away from the wall so that we don't hit it when turning. For this function, move the robot backward at 15 power for 400 ms.
//drive backward at 15 power for 400 ms to back away from the wall void DriveBackward() { motor[leftServo] = -15; motor[rightServo] = -15; wait1Msec(400); } |
Now we need to modify the code to navigate the maze. Remove the 'wait' command in the drive forward function and replace it with the code to wait for contact and back away from the wall:
// drive forward at speed 15 until a wall is found void DriveForwardUntilWall() { motor[leftServo] = 15; motor[rightServo] = 15; while(SensorValue[leftSwitch] == 0 && SensorValue[rightSwitch] == 0) {} DriveBackward(); //could also replace with the code contained in the DriveBackward() function } |
Notice that this if statement has the "&&" Boolean logic operator 'and' which only returns true if the values on BOTH sides evaluate to true.
Now all that remains is to remove the time parameters from the calls to "DriveForward()" in task main(). Once you have done that you end up with
#pragma config(CircuitBoardType, typeCktBoardUNO) #pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot) #pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0) #pragma config(Sensor, dgtl7, leftSwitch, sensorTouch) #pragma config(Sensor, dgtl8, rightSwitch, sensorTouch) #pragma config(Motor, servo_10, leftServo, tmotorServoContinuousRotation, openLoop, IOPins, dgtl10, None) #pragma config(Motor, servo_11, rightServo, tmotorServoContinuousRotation, openLoop, reversed, IOPins, dgtl11, None) //*!!Code automatically generated by 'ROBOTC' configuration wizard !!*// void DriveBackward() { motor[leftServo] = -15; motor[rightServo] = -15; wait1Msec(400); } void DriveForwardUntilWall() { motor[leftServo] = 15; motor[rightServo] = 15; while(SensorValue[leftSwitch] == 0 && SensorValue[rightSwitch] == 0) {} DriveBackward(); } void TurnRight() { motor[leftServo] = 15; motor[rightServo] = -15; wait1Msec(470); //will probably need to adjust time for your robot } void TurnLeft() { motor[leftServo] = -15; motor[rightServo] = 15; wait1Msec(475); //will probably need to adjust time for your robot } void Stop() { motor[leftServo] = 0; motor[rightServo] = 0; } task main() { //wait 1 seconds before starting. wait1Msec(1000); DriveForwardUntilWall(); TurnLeft(); DriveForwardUntilWall(); TurnRight(); DriveForwardUntilWall(); TurnRight(); DriveForwardUntilWall(); Stop(); } |