Milestone 2

Objective:

  • Have the robot successfully circle an arbitrary set of walls
  • Demonstrate that the robot can do line tracking, and wall sensing together

New Sensor Layout and Threshold Values

For this milestone, we added three new sensors to the robot, specifically IR proximity sensors. One facing forward, one facing left, and one facing right. For each of the sensors, the supply voltage pin was connected to the 5V output of the arduino, the GND pin was connected to ground, and the output voltage pins were connected to analog pins 3, 4, and 5. To measure the threshold values, we placed the robot with the sensors on a line and placed a wall half a square away, measured the analog input values by printing them to the serial monitor. Due to the geometry of the robot, the side sensors ended up having the same threshold value and the forward sensor had a different threshold value. If a sensor’s reading is higher than our measured threshold, we say it detects a wall.

Wall-following Method

To enable the robot to successfully navigate mazes by right-wall following, we elaborated on how it handles itself when it arrives at an intersection of lines. In terms of our Arduino code, we made no changes to its line-following method, but used the reading from the IR sensors in to decide which direction to turn. When at an intersection, if the right-facing sensor does not detect a wall, the robot turns right. If the right-facing sensor detects a wall but the forward facing sensor does not, the robot continues moving forward. If the right and forward sensors detect a wall, but the left one does not, it turns left. If all three (right, left, forward-facing) detect a wall, the robot turns around as seen in Video 1 below.

Video 1: Robot Wall Following

Demonstration of Line Sensing and Wall Following:

For the demonstration, the robot performs right-hand wall-following to traverse a simple set of walls. We built the test maze to incorporate left turns, right turns, and U-turns when the robot detects that it has reached a dead end. To indicate the robot’s “thought process,” we added three LEDs: one red, one yellow, and one green. The green LED turns on every time an intersection is detected, regardless of whether the robot decides to continue straight or turn. The red LED turns on when the robot detects a wall straight ahead, meaning that it will definitely make a turn of some kind. Finally, because we are implementing right-hand wall-following, we have the yellow LED turn on whenever the robot does not detect a wall on its right side. Thus, the robot will make a right turn when the yellow light is on. All of the functionality described above can be seen in Code Snippet 1 and Video 2 below.

Possible LED States:

centered image

											
#include <Servo.h>

// Initialize Analog Pins
#define rLineS A1
#define lLineS A2
#define fWallS A3
#define rWallS A4
#define lWallS A5

// Initialize Sensor Thresholds
#define l_thresh    750
#define fw_thresh_0 180
#define fw_thresh_1 60
#define sw_thresh_0 280
#define sw_thresh_1 80

// Initialize right and left servo
Servo rServo;
Servo lServo;

// Initialize line sensor values
int rLineV;
int lLineV;
int fWallV;
int rWallV;
int lWallV;

// Initialize LED Pins
int RED = 0;
int YELLOW = 1;
int GREEN = 2;

void setup() {
  // Attach servos: right to 10 and left to 11
  rServo.attach(10);
  lServo.attach(11);
  // Initialize line sensors
  pinMode(rLineS, INPUT);
  pinMode(lLineS, INPUT);
  // Initialize Indicator LED Pins
  pinMode(RED, OUTPUT);
  pinMode(YELLOW, OUTPUT);
  pinMode(GREEN, OUTPUT);
  // Stop the robot for a second before beginning
  stopMoving();
  delay(1000);
}

void loop() {
  // continually follow lines in figure eight shape
  lineFollow();

  readWall();
  // write "thought process" LEDs based on 
  if (fWallV > fw_thresh_0){
    digitalWrite(RED, HIGH);
  }
  else {
    digitalWrite(RED, LOW);
  }
  if (rWallV < fw_thresh_0){
    digitalWrite(YELLOW, HIGH);
  }
  else{
    digitalWrite(YELLOW, LOW);
  }
    
}

// Makes the robot follow lines, deciding which direction to turn at intersections
void lineFollow() {
  readLine();
  
  if(rLineV > l_thresh && lLineV > l_thresh){
    goForward();
  }
  else if (rLineV > l_thresh && lLineV <= l_thresh){
    corrLeft();
  }
  else if (rLineV <= l_thresh && lLineV > l_thresh){
    corrRight();
  }
  else { 
    // Turn on Green LED when at Intersection
    digitalWrite(GREEN, HIGH);
    turn();
    digitalWrite(GREEN, LOW);
  }
}

// Makes the robot stop
void stopMoving() {
  rServo.write(90);
  lServo.write(90);
}

// Collects data from both line sensors
void readLine() {
  rLineV = analogRead(rLineS);
  lLineV = analogRead(lLineS);
}

// Drives robot forward at full speed
void goForward() {
  rServo.write(0);
  lServo.write(180);
}

// Slows down the left wheel so the robot veers left
void corrLeft() {
  rServo.write(0);
  lServo.write(95);
}

// Slows down the right wheel so the robot veers right
void corrRight() {
  rServo.write(85);
  lServo.write(180);
}

// Turns robot left at an intersection
void turnLeft() {
  goForward();
  delay(200);
  stopMoving();
  rServo.write(0);
  lServo.write(0);
  delay(750);
  while(rLineV > l_thresh) {
    readLine();
  }
  stopMoving();
}

// Turns robot right at an intersection
void turnRight() {
  goForward();
  delay(200);
  stopMoving();
  rServo.write(180);
  lServo.write(180);
  delay(750);
  while(lLineV > l_thresh) {
    readLine();
  }
  stopMoving();
}

// Turns robot around
void turnAround() {
  goForward();
  delay(200);
  stopMoving();
  rServo.write(180);
  lServo.write(180);
  delay(1500);
  while(lLineV > l_thresh) {
    readLine();
  }
  stopMoving();
}

// Keeps robot moving forward through an intersection
void keepForward() {
  goForward();
  delay(200);
  stopMoving();
}

// Collects data from wall sensors
void readWall() {
  fWallV = analogRead(fWallS);
  rWallV = analogRead(rWallS);
  lWallV = analogRead(lWallS);
}

// Decides which direction to turn based on wall sensor reading
void turn() {
  
  readWall();
  if (rWallV < sw_thresh_0) {
    turnRight();
  }
  else if (rWallV > sw_thresh_0 && fWallV > fw_thresh_0 && lWallV < sw_thresh_0) {
    turnLeft();
  }
  else if (rWallV > sw_thresh_0 && fWallV > fw_thresh_0 && lWallV > sw_thresh_0){
    turnAround();
  }
  else {
    keepForward();
  }
}
											
										

Code Snippet 1: Wall Following + Line Sensing Integration

Video 2: Robot Wall Following and Line Sensing with LEDs

*The power cable of the robot sticks too far back and knocks over a wall by accident during the U-turn