How to create blocking/non-blocking functions?

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?

Most (if not all) calls in pros are non-blocking by design. If you wish for it to be blocking, then I suggest using something like okapi’s settledUtil (https://github.com/OkapiLib/OkapiLib/blob/master/src/api/control/util/settledUtil.cpp)

1 Like

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)

8 Likes

Thanks! That makes more sense!

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.

2 Likes