I read the task section in the WPILib manual and the class help file, but when I’m having difficulty getting anything working. The example I’m giving has everything extra cut out. (spelling and code punctuation might not be right)
class 4174robot : public InterativeRobot
{
public:
4174robot();
...(Interative Robot Overrides)...
void TestTaskFunction();
...
private:
Task *task1;
...
};
4174robot:4174robot()
{
task1 = new Task("testtask", (VOIDFUNCPTR) TestTaskFunction();
}
...
4174robot:Teleopinit
{
task1->start;
}
...
4174robot:Disabledinit
{
task1->stop;
}
...
4174robot:TestTaskFunction()
{
std::cout<<"task has been started"<<endl;
}
It complies fine (sometimes), but as I watch it on the WTX console, it just says something along the lines of “task failed.” whey I start teleop.
Why do you need to use task? Are you comfortable with multi-tasking programming? To deal with multiple tasks, you need to understand the concept of protecting share resources when accessing them from different tasks (e.g. using semaphores). If you are not familiar with the concept, you may want to avoid using task.
Having said that, our team is using task to offload the vision processing so it doesn’t bog down the main robot task. We have done some performance tests and found out that analyzing a frame takes about 150-200 msec. So if you are doing vision processing in your main robot task, you may need to set the safety expiration longer than the time required to process a frame.
The main reason I want to use a task is so that I can tell one system to do something while continuing to do something else.
No, I’m not really comfortable with multi-tasked programming. But what I’m trying to do won’t be subject to multiple tasks trying to access the same systems. The task that I create will be the only one accessing the systems.
Alright, thanks alot… I’ll try it tomorrow. I wish they would have put more of this in the WPILib Manual.
In addition to that, I noticed that you added the destructor. In a lot of other [FRC] examples, it seems like it is pretty much ignored. Just good coding practices or something more?
You can achieve this without using tasks. We use something call Cooperative multi-tasking. It is not using real tasks, instead we have a periodic function for each subsystem. In our main robot loop, we call the periodic functions of each subsystem. So all subsystems get a chance to run. However, since it is “cooperative”, there are rules to follow when writing such “tasks”. You must not have any loop in these functions and you cannot use any Wait statements. If you need to wait, you use a state machine to remember the state and exit the function. You will continue your processing on the next loop when you will be called again. It works really well for us and you don’t have to worry about all the gotcha’s of real multi-tasking programming.
You will be surprise. It may not be obvious that you are accessing shared resources. Sometimes, you may be accessing it indirectly through calling another function or even the WPI library. That’s why when there is a problem, it’s very hard to debug.
Alright that works… I don’t get it (FUNCPTR vs VOIDFUNCPTR), but it works.
Then I was like, why am I getting no output on my console. Then I remembered that the windriver console only works for the current task. (or something like that)
No, not true. we printed debug output from a different task. I don’t know if the picture showed the whole code but it doesn’t seem to have the task1->Start() call. I don’t think the task get started automatically when created. You need to explicitly start it.
BTW, FUNCPTR and VOIDFUNCPTR are custom types. I don’t have Wind River in front of me at the moment so I can’t find the definitions of FUNCPTR and VOIDFUNCPTR for you. But I think VOIDFUNCPTR defines a function that returns void and FUNCPTR defines a function that returns an integer. Apparent, the task function should be returning an integer. Probably wouldn’t matter but more correctly:
static int TestTaskFunction(void)
{
std::cout<<"task has been started"<<endl;
return 0;
}
4174robot::4174robot()
{
task1 = new Task("testtask", (FUNCPTR) TestTaskFunction);
}
BTW, in WPILib ask.h, the Task class constructor is defined as:
yeah, I have it later on. I’m using wtx console in windriver, not netconsole. If I put a mechanical task in the funcion it works, but not a cout. I’m trying printf now.