Navigating the maze using the Parallax PING sensor

From ROBOTC API Guide
< Tutorials‎ | Arduino Projects/Mobile Robotics/BoeBot
Revision as of 14:52, 16 October 2012 by Jwatson (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Notepad.gif NOTE: This is a place holder for a video.
Please add the id for the YouTube video with description "BoeBot navigating a simple maze using a PING sensor"

Concepts

We have already navigated a maze using timing and the whiskers. However, what do we do if the maze is of unknown dimensions, and we can't touch the walls? As we discussed before, this is when the Ultrasonic sensor is useful. By using the ultrasonic sensor to find the distance to the walls, it is possible to change the lengths of the straight paths to just about any value. This works since the robot only needs to turn just before there is a wall. So you just replace the time based pause with one that waits for a wall to be a set distance away, and you are good to go.

Configuration

The robot configuration for this program will be the same as the one in the previous program, where the robot avoided obstacles.

  • Parallax Boe Shield
  • leftServo on pin 10 as a continuous rotation servo
  • rightServo on pin 11 as a reversed continuous rotation servo
  • ping on pin 3 as a SONAR [PING] (inch)

Once everything is configured you should have the following configuration code at the top of your program file.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl3,  ping,           sensorSONAR_Ping_inch)
#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               !!*//

Programming

Since we already have a program that uses sensor input to navigate the maze, we are going to modify it to use the PING sensor.

#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 second before starting.
  wait1Msec(1000);
 
  DriveForwardUntilWall();
  TurnLeft();
 
  DriveForwardUntilWall();
  TurnRight();
 
  DriveForwardUntilWall();
  TurnRight();
 
  DriveForwardUntilWall();
  Stop();
}

Now we need to modify the "DriveForwardUntilWall()" function to wait for the PING sensor to detect an obstacle 4 inches away. This is done by changing the While statement condition.

// 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();
}

becomes something like

// drive forward at speed 15 until a wall is found
void DriveForwardUntilWall()
{
  motor[leftServo] = 15;
  motor[rightServo] = 15;
  while(SensorValue[ping] >= 4) {}
}

Now we don't need the code to make the robot back up, so we can just delete it. 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, dgtl3,  ping,           sensorSONAR_Ping_inch)
#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 DriveForwardUntilWall()
{
  motor[leftServo] = 15;
  motor[rightServo] = 15;
  while(SensorValue[ping] >= 4) {}
}
 
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();
}