Quote:
Originally Posted by Ether
Notice that the apparent concurrent execution is done without the use of threads or tasks
|
I would say that using tasks or threads also only give the appearance of concurrent execution. There is only one cpu that can only execute one instruction at a time so the operating system is giving the appearance of concurrence by executing one task for a short time then saving that task off and executing a second taks for a short time and then switching back (context switching). If both of those tasks are "busy" (i.e. doing lots of computations) then switching back forth between the two will only make them take twice as long but get done at the same time (assuming they are doing the same exact job for illustration). If one task works all the time and a second task mostly sleeps and works sporadicly then multiple tasks might make more sense.
Of course if you have multiple execution cores and are actually assigning tasks to run on those different cores that is a different story.
If you are using tasks then you can block (sleep/wait) in those tasks and the operating system will take care of running other tasks that are ready to work.
The Command Based model provided by WPILib is really simulating the behavior of the operating system's scheduler. It does so by using a single task to call the execute() method of any command that is scheduled to run. Those execute() methods must be non-blocking (execute quickly) so that the scheduler can all the other commands that are waiting to run in that cycle.
Example: You want to run a motor until a limit switch is pressed. The execute() method of the Command should set the motor output to some speed then return immediately. The isFinished() method of the Command should return true when the limit switch is pressed. You may also want to drive the robot during the time this first operation is occuring. In the execute() your drive Command (which requires a different subsystem) should read the joystick input and update the drive motors set points and then return immediately. The isFinished() method in the drive command should always return false. The scheduler will run the execute() on both commands every 20 ms until the first command finishes. Then will continue to run the drive command.