In VexCode and RMS, many motor movement methods like rotateTo have a boolean parameter to decide whether or not it will block the execution of the following code until the movement is completed.
I am wondering how I could go about making a function like this in PROS. My first thought is to create a new thread if it should allow the rest of the code to execute, but the PROS documentation discourages the use of multithreading for single, short tasks. Any ideas?
I am more thinking about how I would go about making one of my own functions that is blocking (like a custom built drivetrain PID loop for example, that takes the target distance as a parameter) non-blocking.
Let’s say I used this PID function in an autonomous to drive 3 feet forward, but I wanted the arm to start lifting after 2 feet. I can think of two ways of doing this: 1) have two separate threads, one controlling the drivetrain, and one controlling the arm (making it lift once the error is 1 foot) or 2) somehow make the PID function itself non-blocking so all of the code can be written in one place, instead of two separate threads. If the way I would go about making the PID non-blocking would be to start a separate thread, I think that would still improve the readability of the code, because all of the instructions are in one place and are in order.
My only hesitation is that PROS documentation discourages using threads for actions that will terminate quickly. Should I just ignore that warning, or is there a better way?
You don’t need to start a new thread, a blocking function is blocking the execution of the currently running thread. Blocking functions in VEXcode would follow this general form.
void
blockingFunction( bool waitForCompletion ) {
int32_t _timeout = 500; // some value, this would be 5 seconds
bool done = false;
// do something here like start a motor moving
if( waitForCompletion ) {
// wait for completion or timeout
for(int t = _timeout;t >= 0 && !done; t-=10 ) {
this_thread::sleep_for( 10 );
// depending on the function, something will determine when it is done
if( getCompletionCondition() )
done = true;
}
// if we had timeout
if(!done) {
// perhaps do something on timeout
}
}
}
Now, if you need a non-blocking function that is doing something like PID, then a new thread is needed.
In the case of motor spinTo etc. the motor itself is performing the move, essentially the motor is running the additional thread (because it has its own cpu running a separate program)
Thanks for explanation of blocking function. How do I create non-blocking function in auton. e.g. I want to move arm 90 degree up while chassis is moving. I know I can us move_relative() in pros and similarly rotateFor() in vexcode to achieve this. But in general in c/++ how can I use sensor/encoder and motor speed function to achieve this. Thanks
You don’t need to create a separate thread for that.
You could have a while(1) loop in your autonomous function that constantly checks all sensors, calls short wait() functions and then either calls non-blocking version of rotateFor() functions with waitForCompletion argument set to false, or issues spin command that just start the motors with certain velocity.