Navigating the Simple Maze Using a Touch Sensor
|
Video
Concepts
Using drive times to navigate a maze, like we did before, only works when the distances in the maze are always the same. But what if you made the maze 2 times bigger? The times to drive straight would no longer be correct. We can solve this problem by using the LEGO touch sensor 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 just about any value. This works fine since the robot only needs to turn where there is a wall. So you just replace the time based pause with one that waits for a wall, and add some code to back away from the wall before turning and let the robot do the rest.
Programming
The robot configuration for this program will be the same as the one in the previous program, where the robot avoided obstacles. DFRobot Motor Shield, leftServo on motor_6, rightServo on motor_5, and touchSensor on dgtl2.
We need to add a function to back up away from the wall so that we don't hit it when turning. To accomplish this, let's go backward at speed 90 for 400 ms.
//drive backward at speed 90 for 400 ms to back away from the wall void DriveBackward() { motor[leftServo] = -90; motor[rightServo] = -90; wait1Msec(400); } |
Now we need to take the code to navigate the maze and remove the wait1Msec() in the drive forward function and replace it with a code to wait for the touch sensor to find a wall and code to back away from the wall. So,
// drive forward at speed 90 for the passed time in milliseconds void DriveForward(int time) { motor[leftServo] = 90; motor[rightServo] = 90; wait1Msec(time); } |
becomes something like
// drive forward at speed 90 until a wall is found void DriveForwardUntilWall() { motor[leftServo] = 90; motor[rightServo] = 90; while(SensorValue[touchSensor] == 0) {} DriveBackward(); //could be replaced with the code in the function } |
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, typeShieldDFRobotMotor) #pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0) #pragma config(Sensor, dgtl2, startButton, sensorTouch) #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 !!*// void DriveBackward() { motor[leftServo] = -90; motor[rightServo] = -90; wait1Msec(400); } void DriveForwardUntilWall() { motor[leftServo] = 90; motor[rightServo] = 90; while(SensorValue[touchSensor] == 0) {} DriveBackward(); } void TurnRight() { motor[leftServo] = 90; motor[rightServo] = -90; wait1Msec(470); //will probably need to adjust time for your robot } void TurnLeft() { motor[leftServo] = -90; motor[rightServo] = 90; 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(); } |
Result
If everything has been done correctly, running the program on the robot will navigate the maze using the touch sensor to detect where to turn.