Milestone 2: Wall and Robot Detection
Storing Proximity Sensor Readings
For the second milestone we focused on wall detection for the maze. We connected three proximity sensors for wall detection to the front of the robot, and we used three analog pins for these three sensors. However, for the below functionality we only used the middle proximity sensor. We also created an array of the 50 most recent sensor reading to aid in the implementation of a smoothing functionality that uses a moving average of values read from the sensors so as to not affect the robot behavior if there is one bad reading. A variable stores the sum of the most recent 50 reading values, and another variable stores the average of the most recent 50 values. In our loop the least recent sensor reading value is subtracted from the total and then its spot in the array is replaced with the new value from analog read. Then this new value is added to the sum of the most recent 50 values. We wrap around this array and store values in the least recently used spot, and we chose to use 50 values for smoothing because it is the smallest number of readings that had a smoothing effect.
The code used to update the proximity sensors is shown below.
IR_total = IR_total - readings[read_index]; // subtract the last reading readings[read_index] = mid_prox; // read from the sensor IR_total = IR_total + readings[read_index]; // add the reading to IR_total read_index++; // advance to the next position in the array if (read_index >= max_readings) { // if we're at the end of the array wrap around to the beginning read_index = 0; }
Wall Detection
We wrote an obstacle sensing function that has three inputs: the average of the most recent 50 values, the sum of the most recent 50 values, and the maximum number of readings in our average. In this function we calculate the average reading from these most recent 50 values. If this average is greater than 120, we set a Boolean variable to be true; otherwise we set the value to be false and returned this value. We used a threshold value of 120 because from our testing, this was the ideal value that sensed a wall with an intersection still left in front of the robot that would allow the robot to make a turn. The obstacle Boolean would be set to true. Then if an intersection and obstacle were detected, the robot makes a right turn. Please see the video below for this wall following behavior.
The code for the obstacle sensing function is shown below.
bool obstacle_sensing(int IR_average, int IR_total, int max_readings) { bool obstacle; IR_average = IR_total / max_readings; if(IR_average > 120) { obstacle = true; } else { obstacle = false; } return obstacle; }
Turning After Detecting a Wall
To make the robot act upon detecting an intersection and an obstacle, detection flags are updated and used in an if-statement to determine if turning is necessary. In the code below, the intersection and obstacle detection flags are updated, and if they are both true, the robot turns right.
// update intersection flag intersection = intersection_sensing(left_line, right_line); // update obstacle flag obstacle = obstacle_sensing(IR_average, IR_total, max_readings); // line following routine line_following(left_line, right_line); // wall following behavior if(intersection && obstacle) { turn(RIGHT, DEG_90, left_line, right_line); intersection = false; }
The video below show our robot successfully circling a set of walls through right hand wall following. Additionally, a red LED lights up when a wall is detected, and this LED lights up before it hits the intersection (to show that this functionality is wall detection rather than simply intersection detection). This shows line tracking and wall detection together.