View unanswered posts | View active topics It is currently Wed Sep 18, 2019 2:56 am

 Page 1 of 2 [ 16 posts ] Go to page 1, 2  Next
 Print view Previous topic | Next topic
Multitasking [sticky] - When and When Not to Multitask
Author Message

Joined: Mon Jun 08, 2009 4:50 pm
Posts: 70
Multitasking [sticky] - When and When Not to Multitask
Multitasking is when the robot performs multiple complex behaviors at the same time (simultaneously). If a robot performs behaviors step-by-step (sequentially) then it is not multitasking and should not be programmed with multiple tasks. Let’s look at few examples and determine whether or not multitasking should be used.

A robot drives forward until the sonar sensor sees and object at 30 cm or less away, turns right and stops.

A flowchart of this program would look like this:
 Code:Program starts,Motors start going forward,Keep going until the sonar sees something <= 30 cm,Turn right (right motor negative, left motor positive),Stop (both motors at 0),End Program.

As you can see, this program is sequential because each step comes after the one above it. We DO NOT use multitasking in this example. Let’s look at another:

A robot follows a line until it is 20 cm or less away from a basket and then drops a ball into the basket.

A flowchart of this program would look like this:
 Code:Program starts,Sonar starts checking for objects <= 20 cm away,Light sensor reads dark:   Motors turn slightly one direction,Light sensor reads light:   Motors turn slightly in the other direction,Sonar sees the basket <= 20 cm away,Motors stop,Arm motor starts and drops ball into basket,End Program.

This program also runs from top-to bottom, but this time we have a sonar sensor and a light sensor that are checking their values and performing behaviors at the same time.
Should we use multiple tasks here? No because we can combine the multiple behaviors into a single task like this:

 Code:task main(){   // do the things in this loop while the sonar sensor is > 30 cm   while(SensorValue(sonar) > 30)   {      // follow line:      if(SensorValue(lineFollower) < threshold)      {         // turn sligtly one direction         motor[rightMotor] = 50;         motor[leftMotor] = 0;      }      else      {         // turn slightly in the other direction         motor[rightMotor] = 0;         motor[leftMotor] = 50;      }   }      // stop motors and dump ball into basket:   motor[rightMotor] = 0;   motor[leftMotor] = 0;   motor[armMotor] = 25   wait1Msec(1000);   motor[armMotor] = 0;}

When multiple behaviors can be combined into a single task, we should always choose to do so instead of multitasking!

When should one use multitasking then? Imagine a program that drives a robot around a room vacuuming up objects while avoiding people. The robot comes with an emergency stop button just incase the systems for avoiding people fail or the robot uprising begins and we need to deactivate our robot quickly (in the real world, kill switches are important for human safety). How would a flowchart for this program look like? It is difficult to make a linear step-by-step chart for this program because it is doing multiple things at the same time. Also, the emergency stop button needs constantly be checking while other behaviors are running because the robot must stop immediately when the button is pressed, no matter what else it may be doing at the time. We need multiple flow charts side-by-side:

Driving flowchart:
 Code:Start program,Turn on vacuum,Start driving around,If sonar sees a person:   stop motors,   turn off vacuum,Sonar no longer sees person:   turn on vacuum,   contine driving around,Loop back to start of program.

E-stop flowchart:
 Code:Begin loop:If E-stop button pressed:End Program.If E-stop button not pressed:Go back to top of loop,

The actual program would look something like this:

 Code:task e_stop(){   while(true)   {      if(SensorValue(e_stopBtn) == 1)      {         StopAllTasks(); // this ends the program      }      wait1Msec(10);  // this prevents the current task from hogging the CPU   }}task main(){   StartTask(e_stop);   while(true)   {      if(SensorValue(sonar) <= 10)      {         motor[rightMotor] = 0;         motor[leftMotor] = 0;         motor[vacuumMotor] = 0;      }      else      {         // code for driving around room here      }      wait1Msec(10);  // this prevents the current task from hogging the CPU   }}

Notice that even though behavior for picking up objects and the behavior for avoiding people are running at the same time, they can be combined into a single task. However, the emergency stop button requires a task on its own that runs in the background while the other behaviors are also running. Also please note the two “wait1Msec” commands that prevent each task from hogging the CPU. If a task doesn’t have any waiting in it, it may hog the CPU meaning that it will not let any other tasks run.

It’s important to remember that task main is the main task of the program and when it finishes execution, all other tasks will be force-quit and the program will end. In our example, task main was always in a while(true) loop and didn’t end until task e_stop stopped all tasks.

This very basic example shows a good use for when to use multitasking, however many very important and dangerous concepts have not been addressed.
I encourage those who wish to know more to research Multitasking (multi threading) in C.

Remember:
99% of all ROBOTC programs can be written without multiple tasks if you combine related behaviors!

and
99.9% of all errors in programs that use multitasking are because of improper use of multitasking!!

_________________
Bence Feher

ROBOTC - Testing/Documentation/Developer

Computer Science, Japanese, East Asian Studies
University of Pittsburgh, Konan University 甲南大学

Wed Jun 22, 2011 1:16 pm

Joined: Tue May 15, 2007 9:02 am
Posts: 409
Re: Multitasking [sticky] - When and When Not to Multitask
Nice post!

_________________
Jesse Flot
ROBOTC Support

Thu Jun 23, 2011 2:08 pm
Rookie

Joined: Sat Nov 22, 2008 8:06 pm
Posts: 48
Re: Multitasking [sticky] - When and When Not to Multitask
100% of all programs can be written without multiple tasks on a single core microcontroller, unless you consider any interrupt a different task, in which case 0% of ROBOT C programs can be written without multiple tasks, because the Robot C operating system is interrupt driven.

Any program can be written without using multiple task, it just a matter of whether it's worth the time and skill to do it.

Sat Aug 27, 2011 12:08 am
Moderator

Joined: Tue Sep 14, 2010 9:19 pm
Posts: 496
Re: Multitasking [sticky] - When and When Not to Multitask
 Quote:Any program can be written without using multiple task, it just a matter of whether it's worth the time and skill to do it.

In some programs, multitasking is definitely the more elegant solution. While writing that program without multitasking may be possible, and it may take skill, it's not necessarily the best way to go about it. Multitasking is a tool, and should be used in the proper circumstances. The problems arise when people use this tool in the improper circumstances.

_________________
sudo rm -rf /

Sat Aug 27, 2011 6:42 am
Rookie

Joined: Sun Sep 18, 2011 3:54 am
Posts: 2
Re: Multitasking [sticky] - When and When Not to Multitask
Multi-tasking is a tricky issue.
Usually it requires knowing about things like semaphores, locks, etc.
RobotC Cortex seems to have a very very rudimentary multi-tasking
basically StartTask StopTask and some priority/time slice functions.
nothing to support/prevent contention on variables, sensors, motors, etc
and no way to WaitForTaskToComplete()

or is this documented elsewhere than http://www.robotc.net/support/vex/WebHelpCortex/ ?

Sun Sep 18, 2011 4:15 am
Rookie

Joined: Mon Jan 10, 2011 11:39 pm
Posts: 16
Re: Multitasking [sticky] - When and When Not to Multitask
A Reply for the poster above:
Its actually not documented but they have some sort of support for semaphores, its really basic and requires you to do most of the checking, its basically just a struct which the firmwares puts information to, like which task owns it and if it is locked or not. Its new with 3.0, you will see it on the cortex platform under Semaphore in the sidebar. As for waiting for a task to complete, you can bypass that by using global variables, for instance a boolean that holds the status and you just create a while loop to keep checking. Example:

boolean Completed = false;
while (Completed == false) {};

BE AWARE: this will cause the task your running this code from to freeze until "exampleTask" has finished executing which can lead to problems if it gets stuck in some sort of infinite loop.

_________________
Regards
Stefan Andres Charsley
charsleysa@gmail.com

Wed Sep 28, 2011 12:48 am

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3654
Location: Rotterdam, The Netherlands
Re: Multitasking [sticky] - When and When Not to Multitask
Consider using these new functions in 3.x:

 Attachment: Screenshot-2011-09-29_20.15.45.png [ 6.31 KiB | Viewed 72955 times ]

- Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]

Thu Sep 29, 2011 2:17 pm
Rookie

Joined: Sat Dec 17, 2011 9:27 pm
Posts: 1
Re: Multitasking [sticky] - When and When Not to Multitask
I'm new to robotC (or programming in general) and am having a hard time getting a handle on the idea of linear steps. I'm much more comfortable with PLC ladder logic and am trying to make robotC work in a similar fashion.

I've been trying to write a program that would, basically, turn on a motor and reverse it's direction at time intervals. While this is going on I want to use a limit switch to stop and start another motor.

I think I'm making this far more complicated than it needs to be. I've been playing around with task control etc but I don't even know what I don't know.

Can anybody suggest some ways I might be able to approach the problem stated above?

Sat Dec 17, 2011 9:36 pm
Moderator

Joined: Tue Sep 14, 2010 9:19 pm
Posts: 496
Re: Multitasking [sticky] - When and When Not to Multitask
Maybe this question should be in a separate thread. You could use boolean flags to make this work without multitasking, but multitasking might make it easier. How do you want the switch to control the second motor? Run it while the switch is pressed and stop when released? Or run when the switch is pressed and released, and stop when it's pressed and released again?

_________________
sudo rm -rf /

Sun Dec 18, 2011 12:32 am
Guru

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1523
Re: Multitasking [sticky] - When and When Not to Multitask
 Code:Set the oven to pre-heat temperature of 400 degree F;Wait for the oven to reach the pre-heat temperature;Put the frozen pizza into the oven;Set a timer for 20 min;Wait for the timer to ding;Take the pizza out and serve it;

Next, list out the steps for doing laundry.
 Code:Put the clothes into the laundry machine;Put detergent/softener into the dispenser;Start the washing machine;Wait for the washing machine  to finish;Transfer the clothes from the washing machine to the dryer;Start the dryer;Wait for the dryer to finish;Take out the clothes and fold them;Put them away;

If you are smart, you are not going to stare at the oven while it is pre-heating or stare at the washing machine while it is washing your clothes. Instead, you leave and do something else and come back to check on it later. That's what multi-tasking is about. Imagine the above steps to bake a pizza or doing laundry are written as separate functions. If you call one function then the other, you are serializing the two tasks. One cannot start before the other is completed. However, if you structure your functions like the following, it will do both tasks simultaneously.
 Code:int pizzaNextStep = 1;int laundryNextStep = 1;void PizzaTask(){    switch (pizzaNextStep)    {        case 1:            Set the oven to pre-heat temperature of 400 degree F;            pizzaNextStep++;            break;        case 2:            if (pre-heat temperature has been reached)            {                pizzaNextStep++;            }            break;        case 3:            Put the frozen pizza into the oven;            Set a timer for 20 min;            pizzaNextStep++;            break;        case 4:            if (timer has ding'd)            {                pizzaNextStep++;            }            break;        case 5:            Take the pizza out and serve it;            pizzaNextStep++;            break;        default:            Done;            break;    }}void LaundryTask(){    switch (laundryNextStep)    {        case 1:            Put the clothes into the laundry machine;            Put detergent/softener into the dispenser;            Start the washing machine;            laundryNextStep++;            break;        case 2:            if (washing machine has stopped)            {                laundryNextStep++;            }            break;        case 3:            Transfer the clothes from the washing machine to the dryer;            Start the dryer;            laundryNextStep++;            break;        case 4:            if (dryer has stopped)            {                laundryNextStep++;            }            break;        case 5:            Take out the clothes and fold them;            Put them away;            laundryNextStep++;            break;        default:            Done;            break;    }}task main(){    while (true)    {        PizzaTask();        LaundryTask();    }}

Since these two tasks are actually running on the same thread, there is no resource contention problem or synchronization issue. In essence, your task main loop is the task scheduler. It calls the next task when the previous task is willingly giving up processing. And it is doing this over and over again until all the tasks are completed.

Sun Dec 18, 2011 3:33 am
Moderator

Joined: Tue Sep 14, 2010 9:19 pm
Posts: 496
Re: Multitasking [sticky] - When and When Not to Multitask
I am not familiar with how the multitasking is done internally in ROBOTC. Would the "cooperative multitasking" that you mentioned above actually execute faster than the method that ROBOTC offers, or would the function overhead make it execute slower? Perhaps I'll run some tests when I get my hand on a cortex again.

_________________
sudo rm -rf /

Sun Dec 18, 2011 10:27 am
Guru

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1523
Re: Multitasking [sticky] - When and When Not to Multitask
It's not about faster or slower. It's about more controlled. In preemptive multi-tasking, the scheduler is on time slices. If a time slice is expiring, the task is suspended regardless of what it is in the middle of processing. I am sorry. I am not familiar with the Cortex so I will show an example of the NXT. For example, in joystickDriver.c.
 Code:if(!bOverrideJoystickDisabling){  bTempUserMode = joystickCopy.UserMode;  bTempStopPgm = joystickCopy.StopPgm;  memset(joystickCopy, 0, sizeof(joystickCopy));//// What if the scheduler decided your time slice is up right here?//  joystickCopy.UserMode = bTempUserMode;  joystickCopy.StopPgm = bTempStopPgm;  joystickCopy.joy1_TopHat = -1;  joystickCopy.joy2_TopHat = -1;}bDisconnected = true;

If the above code got preempted at the specified spot, autonomous will get started erronously when communication is lost for a split second because StopPgm would have been zero'd briefly. That's just one of the gotcha's you will hit when programming with preemptive multi-tasking (accessing a common resource in multiple tasks). In this case, the common resource is the joystickCopy structure.
Regarding performance, cooperative multi-tasking puts the scheduling in your own hand. If you task mis-behaved (e.g. have a wait or a loop in your task), the other tasks are going to be starved (hence cooperative).

Sun Dec 18, 2011 10:56 am
Moderator

Joined: Tue Sep 14, 2010 9:19 pm
Posts: 496
Re: Multitasking [sticky] - When and When Not to Multitask
Couldn't you just use hogCPU() and releaseCPU() to make sure that your tasks aren't interrupted at critical moments?

_________________
sudo rm -rf /

Sun Dec 18, 2011 11:46 am
Guru

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1523
Re: Multitasking [sticky] - When and When Not to Multitask
Yes, but then you are assuming you are aware of where in the code you need to protect by critical section. Sometimes this may not be obvious and hence hard to find bugs.

Sun Dec 18, 2011 2:09 pm
Rookie

Joined: Fri Jun 24, 2016 2:23 am
Posts: 1
Re: Multitasking [sticky] - When and When Not to Multitask
Even if one instruction runs on a CPU at any given time, computer programs comprise a lot more than just atomic assembly instructions. So for example, writing to the console (or a file) means you have to have to lock to ensure it works like you want. Only one thread can lock the object at a time, and any contending threads are blocked until the lock is released. If more than one thread contends the lock, they are queued on a “ready queue” and granted the lock on a first-come, first-served basis. More about...Thread Lock

William

Fri Jun 24, 2016 2:27 am
Display posts from previous:  Sort by
 Page 1 of 2 [ 16 posts ] Go to page 1, 2  Next

#### Who is online

Users browsing this forum: No registered users and 2 guests

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum

Search for:
 Jump to:  Select a forum ------------------ ROBOTC Applications    ROBOTC for LEGO MINDSTORMS       Third-party sensors    ROBOTC for CORTEX & PIC    ROBOTC for VEX IQ    ROBOTC for Arduino    Robot Virtual Worlds    Multi-Robot Communications    Issues and Bugs Competitions & Partners    Mini Urban Challenge    CS2N Robot Virtual Worlds Competitions       VEX Skyrise Competition 2014-2015       VEX Toss Up 2013-2014       FTC Block Party! 2013-2014    Competitions using VEX - BEST, TSA, VEX, and RoboFest!    FTC Programming    RoboCup Junior and Other ROBOT Competitions Virtual Brick Robotics Discussions    General Discussions    Project Discussions Off-Topic ROBOTC Forum & ROBOTC.net Suggestions/Feedback    ROBOTC Forums Suggestions/Comments    ROBOTC.net Suggestions/Comments       NXT Programming: Tips for Beginning with ROBOTC       VEX Programming: Tips for Beginning with ROBOTC    2013 Robotics Summer Of Learning       VEX Toss Up Programming Challenge       FTC Ring It Up! Programming Challenge    International Forums       Spanish Forums          ROBOTC for MINDSTORMS          ROBOTC for VEX       French Forums          ROBOTC pour Mindstorms          ROBOTC pour IFI VEX       Japanese Forums （日本語のフォーラム）       German Forums    2015 Spring Carnival Event    PLTW (Project Lead The Way)    Robotics Merit Badge    2014 Robotics Academy Summer of Learning

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.