Just a note, trying to use startRotateFor then immediately calling spin will override the startRotateFor. If you want to do movement based on sensors that aren’t in the motors, ignore the various forms of rotateFor and rotateTo.
For autonomous where there is usually no loop like driver control has, one way to accomplish tasks that would otherwise be blocking is to separate them into their own threads. There are some complexities to using threads, especially in the context of the competition template, but they can definitely be done.
I wrote some documents a while back on threading and the competition template, just talking about the basics of what the classes and methods do and are for.
The first step to using a thread for a task in autonomous is writing a function to execute the task, which you have already done. The next is to start a thread that uses that function when you want it to execute:
thread doFlapperHalf(FlapperHalf);
This will start a thread that runs your function. The program will switch back and forth between active threads while it has more than one. (In a competition scenario, this will be between the competition management thread, the autonomous or driver control thread, any threads you have started, and the main thread if it is still running.)
The complication to using your own threads with the competition template is that the competition manager will only automatically stop the autonomous or drivercontrol threads. Any threads that you create will have to be stopped by you. For your example, it’s fairly easy to accomplish this by adding some extra checks to your while loop:
while (Potentiometer2.value(analogUnits::range12bit) < 10
&& Competition.isAutonomous()
&& Competition.isEnabled()) {
If the competition mode changes to disabled or driver control, the while loop will exit and the thread will end. If you later want to wait to make sure that the task is finished, you can do so by using the join method on the thread:
doFlapperHalf.join();
Join will block until the thread in question is finished. So with your example with driving forward, if you wanted both tasks to be complete before moving on you could do:
thread doFlapperHalf(FlapperHalf);
RightWheel.startRotateFor(120,rotationUnits::deg,30,velocityUnits::pct);
RightWheel2.startRotateFor(120,rotationUnits::deg,30,velocityUnits::pct);
LeftWheel2.startRotateFor(120,rotationUnits::deg,30,velocityUnits::pct);
LeftWheel.RotateFor(120,rotationUnits::deg,30,velocityUnits::pct);
doFlapperHalf.join();
One limitation of threads, however, is that you can’t pass arguments to the functions that they call. This means that they are most useful for actions that will always be the same, or for monitoring and responding to a sensor independent from the rest of the program.