I am currently trying to multitask by using tasks in PROS. So before in robotC, i could just declare a task by:
task my_task(){
cout>>“hello world”;
}
and start it by:
start task(my_task);
Now in PROS, tasks gets more misunderstanding.
Can anyone explain to me how could i use tasks in pros and how do they work?
Is it that tasks in PROS has parameters?
Thanks a lot.
Tasks don’t truly run in parallel. Only one runs at a time. Tasks get swapped out by the scheduler. Every millisecond, the scheduler stops the current task and decides whether to schedule a different task. It could decide to resume the same task or let another task run.
Priority helps the scheduler decide what to run next. A high priority task will always be allowed to run before a low priority task. Most users shouldn’t worry about task priorities - just set it to TASK_PRIORITY_DEFAULT.
Stack space is used by a task to call functions and store variables. Similarly, most users shouldn’t need to worry about running out of stack space, just set it to TASK_STACK_DEPTH_DEFAULT.
Edit:
We say that tasks run in parallel because each task operates independently from one another and tasks are swapped out so quickly that it appears to run in parallel.
if i want to have an integer parameter called speed and a boolean parameter called reverse, how do i declare the task?
also, after i created the task, how do i add in procedures in the task? eg. cout << “hello world”;?
A task is just a function that returns nothing and has a void* argument parameter. You can do “whatever” you want inside the function. ROBOTC taught you that tasks were special things, but they’re not really. In this particular example, you can think of a task function as a function that runs on its own, independent of the task you started it in.
In order to pass in multiple arguments to a task, you could either a) use a global variable or b) give the task a pointer to a struct containing the arguments. a) is typically considered bad practice so I’ll show how to do b) below.
Here’s the example in C:
typedef struct {
int speed;
bool reverse;
} my_task_arg;
void my_task_fn(void* argument) {
// Following two lines get the members of the my_task_arg struct
int speed = ((my_task_arg*)argument)->speed;
bool reverse = ((my_task_arg*)argument)->reverse;
printf("Speed is: %d; reverse is: %d\n", speed, reverse);
}
void opcontrol() {
my_task_arg* argument = malloc(sizeof(my_task_arg));
argument->speed = 100;
argument->reverse = false;
// just separating arguments over new lines for ease of reading on the forum
task_t my_task = task_create(my_task_fn, argument,
TASK_PRIORITY_DEFAULT,
TASK_STACK_DEPTH_DEFAULT,
"My Task");
}
And equivalent example in C++
typedef struct {
int speed;
bool reverse;
} my_task_arg;
void my_task_fn(void* argument) {
// Following two lines get the members of the my_task_arg struct
int speed = ((my_task_arg*)argument)->speed;
bool reverse = ((my_task_arg*)argument)->reverse;
std::cout << "Speed is " << speed << "; reverse is: " << reverse << std::endl;
}
void opcontrol() {
my_task_arg* argument = new my_task_arg();
argument->speed = 100;
argument->reverse = false;
pros::Task my_task(my_task_fn, argument);
}
Tasks themselves aren’t functions, but they run a piece of code that you implement as a function. I think plenty of users made the task keyword into something special.
There’s nothing stopping from doing something like:
void my_function(void* argument) {
printf("I'm running %s\n", (char*)argument);
}
void opcontrol() {
my_function("in operator control");
task_create(my_function, "in my own task", TASK_PRIORITY_DEFAULT,
TASK_STACK_DEPTH_DEFAULT, "Example");
}
Nope, but, in my opinion at least, it’s a really bad habit (not to mention the cpu overhead of doing that)
(and for me it’s nothing to do with ROBOTC. I used many RTOS before ever touching ROBOTC and you just don’t do things like that)
Elliot, we can talk about this somewhere else otherwise we will have to flag our posts as being off topic. My only point was, use functions where appropriate and create a new task where appropriate.
It’s the arguments to task_create as was in the examples above. The first string is the argument to the task entry function (my_function). The second string is the name of the task. It won’t normally be printed unless you explicitly ask to get the current task name.
The C Programming Language book is a great place to learn everything you need to know about C. I’m pretty sure you can find PDFs of the book online. This is the book Purdue and I’m sure nearly every other CS department uses to introduce C to their students. I’d recommend using it as an as-needed reference: when you run into something you haven’t seen before, you can look up the chapter/section that talks about the thing.
leftFront, rightFront, leftRear, rightRear are motor names
stopMove() is just to set drive to 0 power and reset move tick
move ticks and move speeds are declared out of this function