Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Java (http://www.chiefdelphi.com/forums/forumdisplay.php?f=184)
-   -   Multithreading on Java (http://www.chiefdelphi.com/forums/showthread.php?t=126191)

Ether 11-02-2014 13:12

Re: Multithreading on Java
 
Quote:

Originally Posted by BigJ (Post 1341241)
...I'm not sure if I'm interpreting "preemptive time slicing" correctly...

I appreciate your efforts at explanation, but I think the answer I am seeking lies in posts 6, 8, and 11. I'm hoping notmattlythgoe can provide an answer to post 11.

[edit] Just saw Joe's post and am studying it...



notmattlythgoe 11-02-2014 13:46

Re: Multithreading on Java
 
Quote:

Originally Posted by Ether (Post 1341218)
The way you worded that doesn't clearly answer my question.

Let me try re-wording it:

You can create something called a CommandGroup which contains a sequence of commands, intended to be executed one after another. The scheduler will queue the first of those commands, then queue the next command when the previous one has completed, and so on until all the commands in the group have been so queued (and therefore run in sequence). The Command Based API has a WaitCommand. The WaitCommand is not queued. Rather, when the scheduler encounters a WaitCommand in a CommandGroup, the scheduler does not queue the command following the WaitCommand until the specified time has expired.

I have no idea if the above description is an accurate account of what the Command Based implementation actually does, but is that what you meant?




That's a sort of state machine, with time being the state variable.



I'm sorry, I'll try to be more descriptive since I don't think I provided enough information. Btw, I hope the presentation I sent you earlier in the build season was helpful.

The scheduler keeps a list of currently running commands on the system. The execution happens as follows:

1. Gets next command in the list
2. If this is the first time this command is going to run, execute the commands initialize().
3. Execute the command's execute().
4. Execute the command's isFinished(), if the method returns true execute the commands end(), otherwise add the command back onto the list at the end.
5. Repeat steps 1-4.

For the system to work the commands methods need to execute quickly. This means not putting in any waits in the code or the scheduler will not not move onto the next command.

Now, onto the WaitCommand I was talking about before. The CommandGroup allows you to add commands to run in sequence, below is an example that will deploy and arm, wait 5 seconds, then retract the arm.

Code:

addSequential(new DeployArmCommand());
addSequential(new WaitCommand(5));
addSequential(new RetractArmCommand());

How does this work? Good question. The first command DeployArmCommand is added to the scheduler's list for execution. Since the Scheduler is constantly running this will cause the command to start executing in the normal sequence along with any other commands currently running. Once the DeployArmCommand returns a true value from its isFinished() the next command, which is the WaitCommand, will be added to the Scheduler's list. I'm assuming the wait command is set up as a sort of state machine as discussed earlier which will return a true value from its isFinished() once the specified time in seconds has elapsed.

I hope this makes it clearer than I described earlier. If you need any more clarification on anything let me know.

jwakeman 11-02-2014 15:56

Re: Multithreading on Java
 
Quote:

Originally Posted by Ether (Post 1341153)
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.

Jared 11-02-2014 20:09

Re: Multithreading on Java
 
Quote:

Originally Posted by Ether (Post 1341238)
That statement taken at face value would seem to allow the following:
Command A requires only Subsystem B and takes 1ms to complete.

Command X requires only Subsystem Y and takes 3 seconds to complete

Since Command A and Command X don't require writing data to the same Subsystems, they can be running simultaneously
My question is, how does the CommandBased model implement this, if not by preemptive time-slicing.

Posts 6 and 8, and post 10 if I interpreted it correctly, would answer that question.



The commandbased model waits for a command's initialize, execute, or finish method to finish completely before moving on to the next method scheduled. There's no preemptive time slicing or threading going on. If your code for any command takes >20ms to execute, the whole thing falls to pieces.

The provided PID controller does start it's own thread to do PID math, and can update the motor speed from this thread too.

Ether 12-02-2014 12:22

Re: Multithreading on Java
 

Thank you everyone for the responses. I've been carefully reviewing them all and I think I now have a reasonably coherent idea of how command-based works.

There are however a few seeming inconsistencies (or perhaps ambiguities) that I'd like to resolve. Here are two:

Firstly, it is necessary but not sufficient that each individual command in the scheduler's queue complete within 20ms. Rather, the sum total of the individual execution times must be less than 20ms. Correct?

Secondly, the scheduler maintains not only a queue of all the commands to be run, but also the state of each command... and only the method corresponding to each command's state is executed. Correct? (Compare post 15 to post 17 for example of apparent inconsistency).



Joe Ross 12-02-2014 12:49

Re: Multithreading on Java
 
Quote:

Originally Posted by Ether (Post 1341813)
Firstly, it is necessary but not sufficient that each individual command in the scheduler's queue complete within 20ms. Rather, the sum total of the individual execution times must be less than 20ms. Correct?

Correct

Quote:

Originally Posted by Ether (Post 1341813)
Secondly, the scheduler maintains not only a queue of all the commands to be run, but also the state of each command... and only the method corresponding to each command's state is executed. Correct? (Compare post 15 to post 17 for example of apparent inconsistency).

This gets a little bit tricky because of the abstraction. The users creates a "Command" that extends the Command class, which is an abtract class. The Command class implements the state machine, but not the initialize, execute, isFinished, end, and interrupted methods. The user's "Command" implements the initialize, execute, isFinished, end, and interrupted methods. It would be possible for the user to override other methods of the state machine, but I have not seen anyone do it. The scheduler calls the run method of the Command class, which increments through the state machine in the way that notmattlythgoe described. To the casual user, it would appear that the scheduler is doing it because the user doesn't implement any code for the state machine.

notmattlythgoe 12-02-2014 12:52

Re: Multithreading on Java
 
Quote:

Originally Posted by Ether (Post 1341813)

Thank you everyone for the responses. I've been carefully reviewing them all and I think I now have a reasonably coherent idea of how command-based works.

There are however a few seeming inconsistencies (or perhaps ambiguities) that I'd like to resolve. Here are two:

Firstly, it is necessary but not sufficient that each individual command in the scheduler's queue complete within 20ms. Rather, the sum total of the individual execution times must be less than 20ms. Correct?

Secondly, the scheduler maintains not only a queue of all the commands to be run, but also the state of each command... and only the method corresponding to each command's state is executed. Correct? (Compare post 15 to post 17 for example of apparent inconsistency).



Yes to your first point. The goal would be that the sum total of all of the commands be less than the 20ms refresh rate. In general, commands should be pretty simple in their implementation to help with this.

The second point is also correct. The only real state that the scheduler needs to keep track of is which commands are running for their first time. The only thing I'd like to clarify further is that once a command is finished it is removed from the scheduler.


All times are GMT -5. The time now is 11:42.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi