Log in

View Full Version : Image processing and performance


ellisk
19-01-2009, 16:32
Hi everyone,
Currently, I've gotten my program to recognize the pink and green flags, but the image processing functions take a long time (about 1/4 a second or more). I'm using threads ("tasks" on the cRIO) for the different parts of our code, and there's currently 3 threads. I'm wondering if the threads are all getting 1/3 of the CPU, and so that's slowing down our code. Is that possible? If so, can I set the priority of some threads to be higher? I noticed in the constructor for the Task class that I can specify a priority (it defaults to 100). Is 1 the highest or 100? How can I set the priority of the thread which runs OperatorControl?

Thanks,
-Kevin

gvarndell
19-01-2009, 19:48
I'm using threads ("tasks" on the cRIO) for the different parts of our code, and there's currently 3 threads. I'm wondering if the threads are all getting 1/3 of the CPU, and so that's slowing down our code. Is that possible?

It's possible but not likely. The vxWorks kernel doesn't schedule tasks for a fixed length of time. If it did, and there were only 3 tasks, then each would 'use' approximately 1/3 of the CPU time. Under vxWorks, tasks are made ready by events and the highest priority ready task is scheduled to run. That task will run until a) it relinquishes control or b) is preempted by a higher priority task becoming ready. (think about the implications of a high priority task that doesn't relinquish control)

can I set the priority of some threads to be higher? I noticed in the constructor for the Task class that I can specify a priority (it defaults to 100). Is 1 the highest or 100?


Yes. You can do so before the task is created or any time after.
The highest priority is 0 -- 255 is the lowest.
Take my word for this, you don't want to use a priority higher than 51 for your robot tasks unless you know exactly what you're doing.

How can I set the priority of the thread which runs OperatorControl?


If you can get hold of the 'object' for that task, then yes.
Just call the SetPriority method.
I'm neither a C++ fan nor a C++ expert, so I can't tell you how to 'get' a task object for a task your didn't 'instantiate'.
Note that you can create tasks and do whatever you like with them, in a less obfuscated way, by simply calling the vxWorks taskLib API.

Greg McKaskle
19-01-2009, 21:51
It is possible to set priority of a task, but you should be somewhat careful as a higher priority task that doesn't sleep may largely shut down lower priority tasks. A better approach is to look at the tasks and see which of them should be more efficient or sleep because it has nothing better to do.

Greg McKaskle

Jared Russell
20-01-2009, 07:45
Did you try reducing the resolution of the frame?

j_johnson
20-01-2009, 09:54
If you are using a class inherited from IterativeRobot, note that there is no built in delay, so it will use as much processing power as possible, the kernel splitting it equally with tasks of the same priority. To correct this, you can add a taskDelay() call in each of the XXXContinuous functions.

The delay should be long enough to cede as much processing power to other threads as possible without being so long that you are missing calls to the XXXPeriodic functions. (Assuming you are not using the XXXContinuous for anything time sensitive.) Make sure to include taskLib.h which declares this method.

Here is some documentation on VxWorks tasks (http://www.slac.stanford.edu/exp/glast/flight/sw/vxdocs/vxworks/guide/c-basic.html#84257) if you are interested in reading more.

nathanww
20-01-2009, 13:32
You also probably want to take a look at your vision processing system and see if anything can be sped up there. Using the lowest resolution at which you can still identify the target will be helpful, as well as using a nested structure for target identification(for example, only look for a pink flag if a suitable green flag has already been found)

gvarndell
20-01-2009, 16:48
If you are using a class inherited from IterativeRobot, note that there is no built in delay, so it will use as much processing power as possible, the kernel splitting it equally with tasks of the same priority.


Note that vxWorks will not, by default, do round-robin scheduling of tasks with the same priority. If there are 3 tasks with priority 100, and one of them never blocks (timed wait, request unavailable resource, etc.) then that task will forever be the only priority 100 task to run. Lower priority tasks will be locked out -- of course, higher priority tasks can still run.
To enable round-robin scheduling, the user code needs to call kernelTimeSlice() and pass it a tick count.
Those interested in knowing more about this stuff should use the Workbench HELP facility -- Help -> Help Contents.