You are on page 1of 19

Midterm Project

BE1200
Dennis DAntonio, Mahir Chowdhury, Francesco Abouna
Objectives

Develop and Design an NXT robot that will:


navigate around a track following a black line
circumnavigate a 5inch tall red paint can twice (4 total for extra credit)
stop on green the second time and play a musical selection for >5 seconds

Constraints

We are only able to use touch sensors, light sensors, motors, ultrasonic
sensors and anything else inside of the NXT kit that is provided.
Code shouldnt require any tweaking (plug and play)
Ultrasonic sensor needs to be lower than 5 inches
Must be coded using NXC using the BrixCC IDE
User Requirements
User must be able to navigate through the NXT brick (power on/off and start
program)
User must be able to listen to specific sounds and remember to setup the
dynamic thresholds properly by placing the bot on a white area first, then
after the beep place the bot on the black line just in front of the green patch
(counter clockwise from the center)
User must be able to provide sufficient power either through battery or the
rechargeable bot
User must be able to adjust the green threshold values manually by using the
view function on the brick
Functions
I.
II.

III.
IV.
V.

After the user sets up the dynamic thresholds Tribot will start following the
black line at the start position on the track.
After encountering an obstacle it will back up, turn in reverse, move forward
and proceed to navigate around the cylindrical object for 2 revolutions and
then continue on to the rest of the track.
It will notice a green patch for the first time briefly stopping and then finding
the black line again.
The first 2 steps will be repeated
Tribot will detect green a second time, move forward slightly, stop, play a
musical selection for >5 seconds and terminate the program.

Design specifications:
We used the same tribot from homework 4 but modified the bumper to be
more easily pressed by adding a small two-dot lego piece behind the sensor
flap. Additionally we mounted an ultrasonic sensor to the left of the bot
attached to the Nxt brick. The last modification we had was an additional
light sensor attached to the front left of the bot.
Tribot originally was built and consisted of 2 motors controlling 2 wheels, a
third rotational wheel in the back and a bumper in the front (bumpbot
addition)
Overall this robot uses 1 programmable NXT Brick, 2 9V motors, 1 ultrasonic
sensor, and two light sensors, in addition to the various bricks needed to
create Tribot and mount the additional sensors needed.
Generate Alternatives
Option
Parallel tasks using acquire mutex or
start/stop task

Using the touch sensor instead of the


ultrasonic sensor for going around the
paint can

2 light sensors to follow a line

Use light sensor for circumnavigating


paint can
Use different tones to make our own
tune

Not use functions

Why eliminated
Dennis already had working code from
HW4 that only used one task main() and
called different functions. It seemed
logical to continue off of this blue print.
Also, it seemed a lot more difficult to
have to keep track of multiple tasks.
We would have had to further fine tune
the motors and add timers to deal with
this. The ultrasonic sensor seemed a lot
more dynamic and straightforward to
use.
Again, Denniss code from HW4 only
used one sensor to follow the line. Even
though we had to change up the way it
followed to accommodate curves it
seemed to work just as well albeit a little
slower than some people that used two.
This option was ruled out because we
are using two sensors to detect for
green.
Uploading a .rso file to play on the NXT
using PlayFile() allowed for our code to
be a lot shorter and also helped us
better understand uploading files to the
nxt.
This approach could have worked but it
would be messy. Having separate
functions allows our code to be more
readable and easier to debug.

Testing, Evaluating, Refining, and Optimizing design

Stage 1: Line Following


Trial
1

Execution
Use our line
following code from
HW4 to get tribot to
make it
around all of the
black line parts of
the track.
Use more versatile
line following code
that moves one
motor while
shutting of the
other and vice
versa to follow the
line.
Use dynamic black
and white threshold
obtaining code

Adjusted the
rotational wheel in
the back to be
more stable
allowing the sensor
readings to be
more accurate.

Success % after 5
runs
0%

Results

Correction

Code from that


program was only
good for following
straight lines or
circles

Use code that


sweeps left to
right

0%

The program
would follow the
line better but
would sometimes
deviate from the
track

find a way to
get better
black and
white values

60%

The code would


line follow most of
the time but
sometimes would
read in bad
values and
deviate from the
line.
Tribot successfully
navigates around
all of the tracks
black line

adjust
mechanical
properties of
tribot

100%

Stage 2: Stopping on green

N/A

Trial

Execution

Use code from HW4


that double checks
if it is on green
(function)

Adjust the code to


check for green
after every line
following execution

0%

Tribot deviates
from the line
especially at
turns

Reduce
Off(OUT_AC);Wait(1
00); time to
Wait(50);
Got rid of the code
that makes tribot
move forward for
1ms after entering
the checking for
green function.
Try changing light
sensor
SetSensor(IN_3,
SENSOR_3) format
to
SetSensorLight(IN_
3)

0%

Tribot still
deviates from the
black line now

0%

Tribot will now


follow the line but
will still turn when
checking for
green.

Relook at code
for problems.

60%

Tribot will almost


consistently stop
on green now and
follows the line
more tightly (an
unexpected
result). However
there are some
false positives
occuring for the
black line. For
some odd reason
the old way we
had it written
worked but was
subpar. After
using the new
format we
realized that the
light sensor now
lights up.
Tribot will now
stop on green

Relook the
mechanical
structure of
tribot.

Add another light


sensor at a position

Success % after 5
runs
0%

100%

Results

Correction

Tribot turns at the


green patch

Find a way to
adjust
stopping on
green for new
line following
code
Make the code
move forward
less after
checking for
green false
positive.
need it to stop
deviating from
line

a little forward from


the first to check if
both of the sensors
are on green

consistently and
has 0 false
positives from the
black line.

Stage 3: Collision with can


Trial

Execution

Use function from


HW 4 that detects
obstacles. See if it
works placed in
main

Adjust the code to


back up at 30%
power for 5ms and
then reverse A for
7.5ms so that tribot
is perpendicular to
the can
Turn other motor
(OUT_C) off while A
is reversing to
tribot in
perpendicular
position

Success % after 5
runs
100% (initial test
only)

0%

100%

Results

Correction

check_obstacle
function still
works being
placed in the task
main while loop
just like from
Denniss HW4.
The function
works but tribot
doesnt end up
perpendicular

Need to make
it back and get
into a position
to start wall
following

Tribot is now in a
position
perpendicular to
the can and we
are ready to add
on wall following

N/A

Turn other
motor (OUT_C)
off while A is
reversing

to be executed
after this block of
code
Stage 4: Obstacle navigation Part 1
Get tribot to go around the paint can and find the line

Trial
1

Execution
Use the ultrasonic
sensor to detect
the wall and keep
at a distance using
two condition if
statements. One for
9cm and the other
for 10cm that make
one motor move
slower than the
other and vice
versa to
dynamically
navigate around
the paint can
add an else
statement that
simply moves both
motors forward if
inside the range

Success % 5 runs
0%

Results
tribot detects the
object but ends
up running into
the paint can.

Correction
Adjust the wall
following code
by adding
another option

0%

tribot almost
navigates around
the can but still
hits it

make tribot
move forward
a little after
reversing and
getting
perpendicular
to the can
adjust
ultrasonic
distances and
their
corresponding
motor speeds

Change obstacle
detecting code
chunk to add
OnFwd(OUT_AC,
60);Wait(1000); at
the end

40%

tribot will now


navigate around
the can but it
doesnt stay at a
consistent
distance

changed the range


of US values to
adjust to be
between 10 and 7
cm. and slowed
down the motors to
a ratio of 20:40 and

60%

Now tribot will


navigate around
the can and
resume line
following but
sometimes refinds the line in

add piece of
code that
forces tribot to
go into the
right direction
on the line

40:20 when
adjusting against
the can
decided to add this
OnFwd(OUT_C, 40);
OnRev(OUT_A, 30);
until(Sensor(IN_3)
<= tooDark);

100%

the wrong
direction(towards
the can)
Tribot successfully
goes around the
paint can and
continues on the
black line in the
right direction

Move on to
part 2.

Stage 4: Obstacle navigation Part 2


Get tribot to go around the paint can twice and find the line
Trial
1

Execution
Add a black line
counter that will
detect when tribot
went over the line
5 times and
continue on line
following
add another
statement to some
of the dynamic wall
following code that
checks if the sensor
is on black or white
while wall following

Success % 5 runs
0%

Results
Tribot still only
goes around the
can a half turn

Correction
add to the
dynamic wall
following
condition
statements

0%

Tribot still only


goes around the
can a half turn

added another if
condition under the
else if statement
that checks if the
bot is actually on
black and if it is,
adds to a counter

100%

make tribot
check if it is
actually on
black by
checking for
false positives
briefly (like
with green
patch code)
N/A

Now tribot will


circumnavigate
around the paint
can 2 times and
proceed line
following this is all
inside a do while
statement that
checks
while((Sensor(IN_
3) >=
tooDark)&&(line<
5));

Stage 5: extra credit

Get tribot to go around the track twice before stopping on the green patch
the second time
and playing a musical note

Stage 5A: Going pass the green patch the first time
Trial
1

Execution
Try making tribot
move forward for
1.5 seconds and
then continue on to
line following in
task main()

Success % 5 runs
40%

Results
sometimes when
going over green
the first time it
misses the black
line and turns in
the wrong
direction.

After trivial errors


of tweaking the
times and motors:
OnRev(OUT_A, 40);

100%

Now tribot will


consistently move
past the green
patch the first
time without the
issue of stopping
at an angle and
moving at an
angle away from
the black line.

Wait(500);
OnFwd(OUT_AC,40)
;

Correction
add code that
forces tribot
after detecting
green the first
time to turn
itself to the
right move
forward and
then turn left
until it hits the
black line
ensuring no
deviation.

Wait(2000);
OnFwd(OUT_A, 40);
OnRev(OUT_C, 10);
Stage 5B: Stopping on the green patch the second time
Trial
1

Execution
Add a counter that
stops tribot the
second time it
reaches green and
before it would
normally execute

Success % 5 runs
40%

Results
It sometimes
doesnt detect
green after the 2nd
time
encountering the
patch but when it

Correction
check green
values

the initial green


patch detected
code. Also add in
the code that plays
a .rso train file
uploaded to the
NXT for 5 seconds.
Slightly widened
the green
thresholds
assuming it is the
problem
We better mounted
the second light
sensor

Document Design:
Stage 1: basic tribot/bumpbot

Stage 2: added second sensor

does the bot


plays the .rso
music file we
uploaded.

40%

The same failure


to detect it the
second times
occurs.

Stabilizing the
2nd light sensor

100%

turns out the


unsecure 2nd light
sensor was
causing tribot to
not detect the
green patch with
wildly varying
readings

N/A

Stage 3: added ultrasonic sensor to left side perpendicular

Implementation:
1) First impressions we get from this assignment are that we will need a similar
robot from earlier assignments. It will need a touch sensor to detect the can
and possibly an ultrasonic sensor that will sense how far away it is from the
can and adjust accordingly.
2) We decided to use Denniss code from HW4 that successfully navigated the
black line using functions and one task main(). Functions appear to be a lot
more concise and easier to implement than parallel tasks or using mutexs to
control the motors/functions.
3) We realize that the track consists of sharp turns and need to implement a
better way to line follow.
4) Professor Shreves dynamic threshold line following code from blackboard is
implemented and we now are able to flexibly use the track in different

conditions without recalibrating the dark and bright thresholds. We now use a
setup function that runs at the beginning of the program.
5) After debugging and perfecting line following we moved on to stopping on
green.
6) We decided to use the same green stopping function as from HW4 that when
called would constantly be looking out for a possible green patch and
disregard any false positives it came across.
7) After debugging and testing we came to the conclusion that it would be
better to omit the line of code that would move forward before checking to
see if it is on a green patch. This solution stopped our robot from deviating
from the track looking for false positives.
8) We then had to move on to the obstacle paint bucket. We accomplished this
by including it in the check obstacle function that currently only backs up.
Using code that dynamically adjusted (based on an ultrasonic sensor) itself
around the can we performed more debugging/testing. Later we learned that
we had to make 1 revolution around the can. Since we had to make 1
revolution around the can anyways we decided to do the extra credit and
perform two revolutions around the can before proceeding to the line. This
was done by implementing a global variable (int line).
9) After getting our robot to make 2 revolutions using a counter variable we
encountered another issue. This was that when the robot encountered the
line for the 5th(last) time it would sometimes go into the wrong direction. This
was solved by adding in code that reversed the bot until it hit the line and
then the program would continue on in task main to line following code.
10)
After debugging and tweaking we ended up with a robot that
performed most of the functions we need it to do. The only thing left was
getting it to go around the track twice. This was done the same way as the
check_obstacle function that uses a line counter. We decided to implement a
green_count counter variable that would keep track of the number of times it
went over the track.
11)
Now we moved on to getting the robot to go around the track twice.
After some debugging and testing we came to the conclusion that our global
variable line counter was still keeping track of the old cans revolutions. So
then we had to add a line of code before the do-while statement containing
the wall following code that set line = 0;. This solved that issue and we now
have a robot that goes around the track twice. Final touches included adding
sounds to play at the end and tweaking the sensor positions for better
results.
*See Testing, Evaluating, Refining, and Optimizing design section for more
details about implementation and debugging

Advanced Strategies:

The first advanced strategy we implemented was dynamic thresholds. This was
done by making tribot initially read in the white value make a sound/wait and then
then read black value. After the readings, a variable called delta would subtract
black from white and divide by 3. Delta would be added to our black value and
subtracted from our white value to include a more accurate averaged range.
Another tactic we used was counting variables. We used two total, one for counting
how many times it went over the green patch and another for counting how many
times it crossed the black line.

Program Table:
Definitions and Variables
#define THRESHOLD2 54
Green lower threshold
#define THRESHOLD3 63
Green upper threshold
int tooDark;
Sensor value on black line + delta used
for line following
int tooBright;
Sensor value on white + delta used for
line following
int green_count;
counter for stopping on green
int line;
counter for going around paint can
int delta;
((tooBright - tooDark)/3);
Functions
void setup()
This function reads in the light sensor
value white (tooBright), waits 5 seconds
reads in the black line value (tooDark),
calculates int delta and adds that
number to tooDark and subtracts from
tooBright.
void check_obstacle()
This function checks if the touch sensor
is pressed. If it is it will proceed to back
up and reverse into position and move
forward before starting a do-while
statement. The do while statement
utilizes the ultrasonic sensor(IN_2) and
light sensor(IN_3) in a series of if, elseif,
and else statement(s) that adjust the
motors based on the distance to the wall
and check how many times it went over
the black line in order to circumnavigate
a paint can twice before refinding the
line.
void green_patch
This function checks whether the bot is
over a green patch(light sensors read
within the green upper and lower
thresholds). If it is true then it proceeds

task main()

to check for a false positive and turns off


for 1ms and then checks the same exact
condition statement again. If true, the
function will proceed moving both
motors forward at 30% power for 1.5
seconds and add 1 to the green_count
variable. Next it checks whether the bot
has moved over the patch twice. If so, it
will stop both motors and play a .rso
music file for 5 seconds before
terminating the program. However if this
is the first time going over the green
patch the function will instead proceed
to find the black line again.
Tasks
This is the only task. It is where the light
sensors, touch sensor, and ultrasonic
sensors are set. It will first call the setup
function, move forward and then start an
infinite while statement. Here it checks
the check_obstacle function and then the
green_patch function before proceeding
to basic black line following using
variables int tooDark and int tooBright.
Here if light Sensor(IN_3) reads <=
tooDark motor C will be turned off while
motor A moves forward at 55% power
else if Sensor(IN_3) is >=tooBright vice
versa will occur, else the loop will just
move both motors forward at 55%
power. The only way this loop can be
terminated (on its own) is if after
checking the function green_patch() it
senses that it is the second time going
over the patch.

//**********GROUP5
//**********MIDTERM

//Green upper and lower constants


#define THRESHOLD2 54 //Green lower thresh
#define THRESHOLD3 63 //Green upper thresh

//******************************************************************

//Dynamic wall following varirables


int tooDark;

//black value initialized

int tooBright;

//white value initialized

//other variables
int green_count;
int line;

//green patch counter

//line counter

//******************************************************************
//******************************************************************

void setup()
{
// remember bright value
tooBright = Sensor(IN_3);
PlaySound(SOUND_UP);

// wait 5 seconds
Wait(5000);

// get dark value


tooDark = Sensor(IN_3);

// move values in
int delta = ((tooBright - tooDark)/3);
tooDark += delta;
tooBright -= delta;

void check_obstacle() //goes around paint can twice and refinds line
{
if(SENSOR_1==1)

//if touch sensor is pressed perform this statement

{
//backup and prepare to wall sense code
OnRev(OUT_AC, 30);Wait(300);
OnRev(OUT_A, 50);OnFwd(OUT_C,50);Wait(550);
OnFwd(OUT_AC, 60);Wait(400);
line = 0; //This resets the line count for the second time

//Start ultrasonic sensing

do
{

if((SensorUS(IN_2) > 10) && (Sensor(IN_3)>= tooBright))

//adjust

inward
{
PlayTone(600, 40);
OnFwd(OUT_C, 20);
OnFwd(OUT_A, 40);
}
else if((SensorUS(IN_2) < 7)&&(Sensor(IN_3)>=tooBright))
outward
{
PlayTone(700, 40);

//adjust

OnFwd (OUT_A, 20);


OnFwd(OUT_C, 40);
}
else if(Sensor(IN_3) >= tooBright)

//no adjustment

{
OnFwd(OUT_AC, 40);
}
else if (Sensor(IN_3) <= 50)

//check for black line

{
Off(OUT_AC);
Wait(50);
if(Sensor(IN_3) <= tooDark)
{

//count black line


line +=1;

}
OnFwd(OUT_AC, 40);
Wait(550);
}
}
while((Sensor(IN_3) >= tooDark)&&(line<5));
counts the number of times it went over line

OnFwd(OUT_C, 40);
OnRev(OUT_A, 30);

}
}

//have a counter that

//will turn to the right before it refinds the black line

void green_patch()
{

if((Sensor(IN_4)>=THRESHOLD2)&&(Sensor(IN_4) <THRESHOLD3) &&


(Sensor(IN_3)>=THRESHOLD2)&&(Sensor(IN_3) <THRESHOLD3)) //if sensor reads
green variable
{
Off(OUT_AC);Wait(100);
if((Sensor(IN_4)>=THRESHOLD2)&&(Sensor(IN_4) <THRESHOLD3) &&
(Sensor(IN_3)>=THRESHOLD2)&&(Sensor(IN_3) <THRESHOLD3))
//if sensor still
reads within green range
{
OnFwd(OUT_AC, 30);
for false positive********

//******check

Wait(1500);
green_count = (green_count +1);
if(green_count == 2)
{
Off(OUT_AC);
PlayFileEx("train.rso",100,FALSE);
Wait(6000);//Wait 6 seconds
Stop(true);
}

OnRev(OUT_A, 40);
OnFwd(OUT_C, 10);
Wait(500);

OnFwd(OUT_A, 40);
OnRev(OUT_C, 30);// will occur until it finds the black line again in task
main

}
}

task main()
{

SetSensorLight(IN_3, SENSOR_LIGHT); //configure light sensor in port 3 (EYE)


SetSensor(IN_1, SENSOR_TOUCH); //configure touch sensor in port 1
SetSensorLight(IN_4, SENSOR_LIGHT); //port 4 light sensor
SetSensorUltrasonic(IN_2); // ultrasonic sensor in port 2

setup();

//obtain white and black dynamic thresholds

OnFwd(OUT_AC, 50);

while(true)
{
check_obstacle(); //testing this spot
green_patch(); //check green
if((Sensor(IN_3)<= tooDark))
{
Off(OUT_C);
OnFwd(OUT_A, 55);
}
else if((Sensor(IN_3) >= tooBright))

//line following

{
Off(OUT_A);
OnFwd(OUT_C, 55);
}
else
{
OnFwd(OUT_AC, 55);

}
}
}

Group Efforts:

Dennis DAntonio: Main coder, Flowchart, Program table,


testing/evaluation/optimizing table, Generated alternatives,
Francesco Abouna: record keeping, robot design, debugging,
Mahir Chowdhury: Implementation, debugging, robot design

You might also like