You are on page 1of 12

Add in Commands to Back Up and turn Tribot around when you detect an obstacle.

Do
this using 3 approaches:
a.
inserted into the main Line-Following Code or a separate task (1 or 2 tasks, your
choice)

**PROGRAMS ALL NEED TO BE TESTED ON BOARD WITH LINE + OBSTACLE **

PART A (2 SEPARATE TASKS)


// since we dont use Mutex on part a of the assignment, will the motors act funny? If so, we need
to document this on our blog
//code from 2-3 with the color threshold
//LinebotSingleLightSensorCode.nxc
//follows a black line on white background
#define THRESHOLD 38
#define BUMP SENSOR_1
task check_sensor () //SS: this task is to get the bot to turn around after hitting the brick
{
//SetSensorLight(IN_3); //set in while loop
//OnFwd(OUT_AC, 75); not necessary?
while (true)
{
SetSensorTouch(BUMP);
if (BUMP==1)
{
OnRev(OUT_AC, 75);
Wait(500);
OnFwd(OUT_C, 50);
Wait (500);
OnFwd(OUT_AC, 75);
}
}
}
task line_follow ()
{
while (Sensor(IN_3) > THRESHOLD)
{

OnRev(OUT_C, 20);
Wait(100);
until(Sensor(IN_3) <= THRESHOLD);
OnFwd(OUT_AC, 50);
}
}
task main()
{
Precedes (line_follow, check_sensor);
//SetSensorTouch(IN_1);
SetSensorLight(IN_3);
}

PART A -- Alternative, everything in main task


//everything in main task
#define THRESHOLD 38
#define BUMP SENSOR_1
task main ()
{
//SetSensorTouch(BUMP); set in while loop
SetSensorLight(IN_3);
while (Sensor(IN_3) > THRESHOLD)
{
OnRev(OUT_C, 20);
Wait(100);
until(Sensor(IN_3) <= THRESHOLD);
OnFwd(OUT_AC, 50);
}
while (true)
{
SetSensorTouch(BUMP);
if (BUMP==1)
{
OnRev(OUT_AC, 75);
Wait(500);
OnFwd(OUT_C, 50);

Wait (500);
OnFwd(OUT_AC, 75);
}
}
}

Add in Commands to Back Up and turn Tribot around when you detect an obstacle. b.
as a separate task turnaround() .(based on part a results in
i. use Start/Stop task commands
2 or 3 tasks)
ii. Using a Mutex on the motors
#define THRESHOLD 38
#define BUMP SENSOR_1
task turnaround ()
{
//SetSensorLight(IN_3); set in task main
//OnFwd(OUT_AC, 75); not necessary
while (true)
{
//SetSensorTouch(BUMP);
if (BUMP==1)
{
StopTask(line_follow); //JK edited
OnRev(OUT_AC, 75);
Wait(500);
OnFwd(OUT_C, 50);
Wait (500);
OnFwd(OUT_AC, 75);
StartTask(line_follow); //JK edited
}
}
}
task line_follow ()
{
while (Sensor(IN_3) > THRESHOLD)
{
OnRev(OUT_C, 20);

written

Wait(100);
until(Sensor(IN_3) <= THRESHOLD);
OnFwd(OUT_AC, 50);
}
}
task main()
{
SetSensorTouch(IN_1); //set in while loop earlier , JK-Sensors must be set in task main
SetSensorLight(IN_3);
/*StartTask(line_follow); //JK - I dont think this will work.
StartTask(turnaround);
StopTask(line_follow);
StopTask(turnaround);*/
}

Add in Commands to Back Up and turn Tribot around when you detect an obstacle. b.
as a separate task turnaround() .(based on part a results in
2 or 3 tasks)
ii. Using a Mutex on the motors
mutex moveMutex;
#define THRESHOLD 38
#define BUMP SENSOR_1
task turnaround ()
{
//SetSensorLight(IN_3); set in task main
//should Acquire (moveMutex); be here?
//OnFwd(OUT_AC, 75); no reason for this to be here
while (true)
{
SetSensorTouch(BUMP);
if (BUMP==1)
{

written

Acquire(moveMutex);
OnRev(OUT_AC, 75);
Wait(500);
OnFwd(OUT_C, 50);
Wait (500);
/*put until statement or while statement to get it to recognize the line
until(Sensor(IN_3) <= THRESHOLD); OnFwd(OUT_AC, 50);
OnFwd(OUT_AC, 75);*/
Release(moveMutex);
}
}
}
task line_follow ()
{
while (Sensor(IN_3) > THRESHOLD)
{
Aquire(moveMutex);
OnRev(OUT_C, 20);
Wait(100);
until(Sensor(IN_3) <= THRESHOLD);
OnFwd(OUT_AC, 50);
Release(moveMutex);
}
}
task main()
{
//SetSensorTouch(IN_1); set in while loop earlier
SetSensorLight(IN_3);
Precedes (line_follow, turnaround);
}

Add in Commands to Back Up and turn Tribot around when you detect an obstacle.
c.
written as a separate function or subroutine called from the Line-Following task. (this
will reduce your number of tasks by one)

#define THRESHOLD 38
#define BUMP SENSOR_1
sub turnaround() //change to inline void
{
while (true) //may not compile as subroutines do not work with while loops
{
SetSensorTouch(BUMP);
if (BUMP==1)
{
OnRev(OUT_AC, 75);
Wait(500);
OnFwd(OUT_C, 50);
Wait (500);
OnFwd(OUT_AC, 75);
}
}
}
task line_follow () // if we made this task main () would it be okay?
{
while (Sensor(IN_3) > THRESHOLD)
{
OnRev(OUT_C, 20);
Wait(100);
until(Sensor(IN_3) <= THRESHOLD);
OnFwd(OUT_AC, 50);
}
turnaround;
}
task main() // will this just immediately start with task line_follow? Or are the Start/StopTasks
necessary?
{
SetSensorLight(IN_3);
/*StartTask(line_follow); \\ place these in condition statements
StopTask(line_follow);*/
}

a.
i.
ii.
b.
i.
1.
2.
ii.
1.

2.
c.
i.

ii.

Advantages/Disadvantages of each code (UNFINISHED -- will be completed after we test out


the programs on the boards with the black lines)
putting everything under task main()
advantages: can never have the issue of conflicting commands on the motors. Only one task is
used, which saves memory.
disadvantages: the code is long and difficult to understand immediately. Had to add 3
while(condition) statements in order for bot to function correctly.
separate task turnaround()
used Start/Stop task commands
advantages: ensures that only one task has complete control over the motors.
disadvantages: Because the task that does not involve in StartTask and StopTask must be
first, code could be incorrect and difficult to read.
using Mutex
advantages: Mutex ensures that only one task is driving the robot at any given moment. Code
does not have to be in order according to the Precedes() command. Code is easier to read and
understand. Code written between the mutex assures motors are being used one task at a time.
Mutex is used to control access to resources shared across multiple threads. Theres never a need
to declare a mutex variable.
disadvantages: Since tasks are used one at a time, tasks will not run parallel to each other.
created inline void turnaround() and put it in task line_follow
advantages: inline functions are copied every time they are used and they can be used infinitely
many times in a program. Inline functions make the code compact, easy to understand and also
allow for extremely quick changes.
disadvantages: not stored separately so use more memory

Part 1 (DONE)
#define THRESHOLD 52
task main ()
{
OnFwd(OUT_AC, 25);
SetSensorLight(IN_3);
SetSensorTouch(IN_1);
while (true)
{
while (Sensor(IN_3) > THRESHOLD)
{
OnFwd(OUT_A, 25);
OnRev(OUT_C, 15);
Wait(100);

until(Sensor(IN_3) <= THRESHOLD);


OnFwd(OUT_AC, 25);
}
while (SENSOR_1==1)
{
OnRev(OUT_AC, 75);
Wait(500);
OnFwd(OUT_C, 50);
Wait (1000);
OnFwd(OUT_AC, 75);
}
}
}
PART 2. A. Start/StopTask Commands
#define THRESHOLD 52
task line_follow()
{
OnFwd(OUT_AC, 25);
while (true)
{
if(Sensor(IN_3) > THRESHOLD)
{
OnFwd(OUT_A, 25);
OnRev(OUT_C, 15);
Wait(100);
until(Sensor(IN_3) <= THRESHOLD);
OnFwd(OUT_AC, 25);
}
}
}

task turnaround()
{
while (true)
{
if (SENSOR_1==1)
{
StopTask(line_follow);
OnRev(OUT_AC, 50);

Wait(1000);
OnFwd(OUT_C, 20);
Wait (2000);
OnFwd(OUT_AC, 75);
StartTask(line_follow);
}
}
}
task main()
{
SetSensorTouch(IN_1);
SetSensorLight(IN_3);
Precedes(line_follow, turnaround);
}

PART 2.B. Mutex


mutex moveMutex;
#define THRESHOLD 52
task turn_around()
{
while (true)
{
if (SENSOR_1==1)
{
Acquire(moveMutex);
OnRev(OUT_AC, 75);
Wait(500);
OnFwd(OUT_C, 50);
Wait (1000);
OnFwd(OUT_AC, 75);
Release(moveMutex);
}
}
}
task line_follow ()
{
OnFwd(OUT_AC, 25);
while (true)

{
if (Sensor(IN_3) > THRESHOLD)
{
Acquire(moveMutex);
OnFwd(OUT_A, 25);
OnRev(OUT_C, 15);
Wait(100);
until(Sensor(IN_3) <= THRESHOLD);
OnFwd(OUT_AC, 50);
Release(moveMutex);
}
}
}
task main()
{
SetSensorLight(IN_3);
SetSensorTouch(IN_1);
Precedes (line_follow, turn_around);
}
PART 3
#define THRESHOLD 52

inline void turnaround()


{
if (SENSOR_1==1)
{
OnRev(OUT_AC, 75);
Wait(500);
OnFwd(OUT_C, 50);
Wait (1000);
OnFwd(OUT_AC, 75);
}
}

task line_follow()
{
while (true)

{
OnFwd(OUT_AC, 25);
while (Sensor(IN_3) > THRESHOLD)
{
OnFwd(OUT_A, 25);
OnRev(OUT_C, 15);
Wait(100);
until(Sensor(IN_3) <= THRESHOLD);
OnFwd(OUT_AC, 50);
}
turnaround();
}
}
task main()
{
SetSensorLight(IN_3);
SetSensorTouch(IN_1);
Precedes(line_follow);
}

WEEBLY Post
Week 2/14/16 - 2/20/16
This weeks Homework 3 gave us more experience with tasks, subroutines, Mutex, and
functions. While tasks, subroutines, and functions can save us a lot of time and make the code
easier to read, they can also lead to errors as there may be multiple tasks trying to control the
same resources. The way to rectify this problem is to use either the moveMutex or
Start/StopTask commands.
Through trial and error we learned that the Start/StopTask commands were very particular about
their placement in the code as well as the arrangement of the tasks. For example, when we tried
to put all the Start/StopTask commands in task main(), this resulted in nothing actually
happening. Our TA, Paul, explained that since everything in task main() executes first, the tasks
were being told to stop as soon as they were being told to start. We resolved this issue by placing

the Start/StopTask commands in the tasks that were not task main(). Universally we agreed that
moveMutex was much easier to use as it is straightforward with its use of the Acquire and
Release statements.
Weve also learned that subroutines/inline functions actually saved us time when typing our
program and it used less memory. It was also the more preferable with the StartTask and
StopTask since the moveMutex is universally more helpful without it. Our team was also
struggling to write the program when it came to using the inline functions because when using
them, the subroutine seemed to not compile with the NXT bot. We believe this reason was due to
the fact that when using sub (name of subroutine) command, it may have required a variable
that would control the value of output to the motors in the statement. So since it wouldnt
compile with the NXT bot, we used an inline function command, which turnout to be in our
favor. The NXT behaved as expected.