Team 3 David Letteer Greg Broadwell Kathryn della Porta BE-1200: Basic Engineering I Midterm

Midterm Report [Clarify Objectives] Design, build, and program a robot that will follow the path of a black line, detect and navigate an obstacle, refind and resume navigation of the line, and stop and play a sound upon reaching a green square. Optionally, the robot may run the entire course twice with a single program and circle the obstacle twice using a rotation sensor to count to circles before resuming following the line.

Solid Object

Green Square

START

[Identify Constraints] Creation of the robot is limited to the parts available in the lego mindstorms kit and the control abilities of the NQC software.

[Establish User Requirements] User must be able to press the “run” button on the robot, as well as move the robot by hand in the initial setup of the program to retrieve the correct light sensor values.

[Establish Functions] This robot begins its journey on the green square. First the robot retrieves a light sensor value for the green square, then the white space, and then the black line, with a three second break between retrieving each value in which the user must move the robot over the specified color. The robot the proceeds along the course on its own. The robot follows the left edge of the line until the touch sensor is triggered. Then the line following function is stopped, the robot backs up until the rotation sensor alerts the robot that it has backed up to the proper distance from the obstacle. The robot then rotates 90 degrees to its left and begins circling the obstacle. When the rotation sensor has determined that the robot has circled the obstacle two and a half times, at which point the robot begins following the line again. The robot proceeds past the green square and performs a second lap in the same fashion. This time, however, once the robot has navigated the obstacle, the robot waits until the rotation sensor alerts the robot that it has traveled far enough from the obstacle, at which point the robot continually checks for the green square value, stopping when it reaches the green square.

[Establish Design Specifications] The robot must have a mechanism to detect the obstacle, a method for following the line that will most likely be light sensor based, the same or a similar method for detecting the green square, a method of movement that allows for detailed turns, and, for the extra credit a method of incorporating a rotation sensor.

[Generate Alternatives] Movement of the robot was the first item we addressed. Initially we had a form of tankbot leftover from the last assignment. Tankbot was certainly capable of performing the necessary tasks, but we wanted to come up with a more efficient solution. Two large drive wheels in the front of the robot would allow for more rapid and accurate course corrections. The sheer size of the wheels made incorporating a rotation sensor difficult, so we began with a simple caster mounted to the back of the robot that used the rotation sensor as a housing for the wheel axle as well as the mount for the pivot that connected to the main robot. A single downward facing light sensor mounted to the front of the robot was chosen over a two light sensor model to allow for more sensor ports to be open and therefore easing the dirrerentiation of sensor readings in the programming process. A touch sensor arm similar to the antennae of bugbot would serve as the line following and object detection mechanisms. We ignored using a light sensor as a proximity sensor also to simplify the code writing process.

[Model or Analyze Design] Macros Description

ARM Touch sensor arm; SENSOR_1

EYE Light sensor; SENSOR_2

ROT Rotation sensor; SENSOR_3 L Left motor; OUT_A

R Right motor; OUT_C

Global Variables Description green Holds the value corresponding to the light sensor reading over the green square (in percent mode). tooDark Holds the value corresponding to a light sensor reading interpreted to indicate “black” (in percent mode). tooBright Holds the value corresponding to a light sensor reading interpreted to indicate “white” (in percent mode). loop Holds the value corresponding to the current progress of the robot. The variable is incremented after the robot completes two and a half circles around the cylindrical obstacle.

Local Variables Description found Semaphore used to break a do-while loop within the seek_green task, indicating that the robot has found the green square for the second time, and should stop.

Functions Description setup() Reads in light sensor values over the green square, white mat, and black line. Calculates thresholds and assigns values to green, tooDark, and tooLight. User assistance required.

Tasks Description watch_arm The robot watches the touch sensor, ARM. When the touch sensor indicates that the robot has collided with the obstacle, it stops the follow task, circles the obstacle two and a half times, then restarts the follow task. follow The robot follows the black line. seek_green The robot watches for the green square. The first time it sees the green square, it passes it and plays a sound. The second time it sees the green square, it stops and plays a sound. main The main task initializes the sensors, sets the event monitoring, runs the setup() function, and starts the watch_arm, follow, and seek_green tasks.

[Test and Evaluate Design] Line Following Interactive setup() to read in Robot consistently followed line around track. No changes. values for white mat and black line, light sensor, mounted on front of robot ~8mm from track surface, in percent mode

Obstacle Circumnavigating Robot bumps obstacle with When rear caster wheel not perfectly straight (most of the time), it feeler arm, backs up, turns, would turn underneath the robot and skid, leading to inconsistent drives forward to start position, backup distances. Positioning of robot for start of circumnavigation circles obstacle using calculated know; getting robot to consistently position itself presents difficulties. pulse width modulation of When properly positioned, circles obstacle perfectly using dead motor power. Rotation sensor reckoning. Changed rear caster wheel from swivel to fixed position counts as robot circles obstacle. and changed tires from truck tires to plastic pulleys. Robot bumps into obstacle with With rear caster wheel in a fixed position and able to skid, backup feeler arm, backs up, turns in distance now consistent, so positioning for start of circumnavigation of place 90° to (new) start obstacle now more consistent. Small adjustments may be needed on a position, circles obstacle using per-run basis. calculated pulse width modulation of motor power. Rotation sensor counts as robot circles obstacle.

Green Square Finding Two checks for green value, Inconsistent results. Approximately as many false positives as local variable loop successful identifications, as well as several false negatives. Added a incremented once green found third check for green to decrease probability of a false positive. for first time, local variable Made loop a global variable. The variable loop is now incremented found incremented once green after the obstacle is circumnavigated, reducing the span of track over found second time. which false positives may be read. Three checks for green value, Fewer false positives and false negatives, but results not consistent. global variable loop Added a check on the rotation sensor count to the first check for the incremented once the robot has green value. The first check will only be passed once the robot has completed circumnavigating the traveled nearly to the green square. obstacle. Three checks for green value, Robot successfully and consistently found and stopped on the green global variable loop square. incremented once the robot has completed circumnavigating the obstacle, check for distance along track from obstacle before checks for green value.

[Refine and Optimize Design] From inception to final design, most of the robot was redesigned. A gear ratio of 5:1 was added between the motors and the tires to reduce the speed of the robot. The rear caster wheel was modified multiple times, culminating in the fixing of the position of the wheel and exchanging the tractor wheels for plastic pulleys that could skid as the robot turned. The end of the front feeler arm was modified multiple times as well.

[Design Communication/Document Design]

[Code]

/* midterm_v4.nqc David Letteer Greg Broadwell Kathryn della Porta */ // sensor and motors #define ARM SENSOR_1 #define EYE SENSOR_3 #define ROT SENSOR_2 #define L OUT_A #define R OUT_C #define CAN 1

// use variables for thresholds int green; int tooDark; int tooBright; int loop = 0; void setup() { // read in value for green green = EYE; PlaySound(SOUND_UP);

// wait 3 seconds Wait(300);

// remember bright value tooBright = EYE; PlaySound(SOUND_UP);

// wait 3 seconds Wait(300);

// get dark value tooDark = EYE;

// move values in int delta = (tooBright - tooDark) / 5; tooDark += delta; tooBright -= delta; } task watch_arm() { while (true) { monitor(EVENT_MASK(CAN)) { while(true); } catch { stop follow; PlaySound(2); ClearSensor(ROT);

// back up OnRev(L + R); //Wait(38); until(ROT == 8);

// spin in place 90 degrees OnFwd(R); OnRev(L); Wait(60);

// circle can do { OnFwd(L + R); Wait(20); Off(R); Wait(10);

}while(ROT > -620); until(ROT < -620); PlaySound(2);

Off(L); OnFwd(R); Wait(160);

start follow;

loop++; ClearSensor(ROT); } } } task follow() { On(L+R); while(true)

if (EYE <= tooDark) { Off(L); On(R); } else if (EYE >= tooBright) { Off(R); On(L); } else { On(L+R); } }

task seek_green() { // declare local variables int found = 0; // semaphore

do { until(ROT < -300 && EYE==green); Wait(5); if(EYE==green) { Wait(5); if(EYE==green) { if(loop==2) { stop follow; Off(L + R); repeat(3){PlaySound(SOUND_UP);} found = 1; } else if(loop==1) { repeat(2){PlaySound(SOUND_DOUBLE_BEEP);} Wait(100); } } } }while(found==0); } task main() { SetSensor(EYE, SENSOR_LIGHT); //SetSensor(ARM, SENSOR_TOUCH); SetSensor(ROT, SENSOR_ROTATION);

SetSensorType(ARM, SENSOR_TYPE_TOUCH); SetSensorMode(ARM, SENSOR_MODE_RAW);

SetEvent(CAN, ARM, EVENT_TYPE_RELEASED);

SetPower(L+R, 1); setup(); start seek_green; start watch_arm; start follow; }