Go to Post It is very difficult for a large, inexperienced, impatient group to create order from chaos. - Wayne TenBrink [more]
Home
Go Back   Chief Delphi > Technical > Programming > Java
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 13-02-2014, 08:40
pblankenbaker pblankenbaker is offline
Registered User
FRC #0868
 
Join Date: Feb 2012
Location: Carmel, IN, USA
Posts: 108
pblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of light
CommandGroup questions

I have a couple of questions regarding how command groups are processed.

As an example, lets assume that I want to:
  • Run CommandA first and wait for it to complete.
  • Then run CommandB and CommandC at the same time.
  • After CommandB and CommandC complete I then want to run CommandD.

I'm assuming the following would generate this sequence:

Code:
public static Command buildMyCommand() {
  CommandGroup bc = new CommandGroup();
  bc.addParallel(new CommandB());
  bc.addParallel(new CommandC());

  CommandGroup cmd = new CommandGroup();
  cmd.addSequential(new CommandA());
  cmd.addSequential(bc);
  cmd.addSequential(new CommandD());

  return cmd;
}
From my understanding of how addParallel() and addSequential() work, the above could also be written as:

Code:
public static Command buildMyCommand() {
  CommandGroup cmd = new CommandGroup();
  cmd.addSequential(new CommandA());
  // Start of first command to run in parallel
  cmd.addParallel(new CommandB());
  // End of commands to run in parallel (runs in parallel with CommandB)
  cmd.addSequential(new CommandC());
  cmd.addSequential(new CommandD());

  return cmd;
}
So, my first question is: Would the two versions of buildMyCommand() shown above produce the same results when run?

My next questions have to do with what happens to a command group when things don't complete nicely:
  • If CommandA from the example command group above was interrupted, would the entire command group be interrupted? For example, let's assume CommandA was waiting for something to move into position and CommandB performed a firing action. If CommandA was interrupted, would CommandB still run, or would the interruption stop CommandB from ever being run?
  • Secondly, Assume CommandA has used the setTimeout() method or was added to the group with a timeout option to indicate that it has 2 seconds to complete. If the timeout is reached, will the rest of the commands complete in the sequence?

Thanks,
Paul
Reply With Quote
  #2   Spotlight this post!  
Unread 13-02-2014, 08:42
notmattlythgoe's Avatar
notmattlythgoe notmattlythgoe is offline
Flywheel Police
AKA: Matthew Lythgoe
FRC #2363 (Triple Helix)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: Newport News, VA
Posts: 1,728
notmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond repute
Re: CommandGroup questions

Quote:
Originally Posted by pblankenbaker View Post
I have a couple of questions regarding how command groups are processed.

As an example, lets assume that I want to:
  • Run CommandA first and wait for it to complete.
  • Then run CommandB and CommandC at the same time.
  • After CommandB and CommandC complete I then want to run CommandD.

I'm assuming the following would generate this sequence:

Code:
public static Command buildMyCommand() {
  CommandGroup bc = new CommandGroup();
  bc.addParallel(new CommandB());
  bc.addParallel(new CommandC());

  CommandGroup cmd = new CommandGroup();
  cmd.addSequential(new CommandA());
  cmd.addSequential(bc);
  cmd.addSequential(new CommandD());

  return cmd;
}
From my understanding of how addParallel() and addSequential() work, the above could also be written as:

Code:
public static Command buildMyCommand() {
  CommandGroup cmd = new CommandGroup();
  cmd.addSequential(new CommandA());
  // Start of first command to run in parallel
  cmd.addParallel(new CommandB());
  // End of commands to run in parallel (runs in parallel with CommandB)
  cmd.addSequential(new CommandC());
  cmd.addSequential(new CommandD());

  return cmd;
}
So, my first question is: Would the two versions of buildMyCommand() shown above produce the same results when run?

My next questions have to do with what happens to a command group when things don't complete nicely:
  • If CommandA from the example command group above was interrupted, would the entire command group be interrupted? For example, let's assume CommandA was waiting for something to move into position and CommandB performed a firing action. If CommandA was interrupted, would CommandB still run, or would the interruption stop CommandB from ever being run?
  • Secondly, Assume CommandA has used the setTimeout() method or was added to the group with a timeout option to indicate that it has 2 seconds to complete. If the timeout is reached, will the rest of the commands complete in the sequence?

Thanks,
Paul
I can only answer the last question for sure, yes the rest of the commands will complete after the one times out. We are doing this for our hot goal detection so we don't end up waiting the entire auto period if we don't see a hot goal for any reason.
Reply With Quote
  #3   Spotlight this post!  
Unread 13-02-2014, 11:34
Ginto8's Avatar
Ginto8 Ginto8 is offline
Programming Lead
AKA: Joe Doyle
FRC #2729 (Storm)
Team Role: Programmer
 
Join Date: Oct 2010
Rookie Year: 2010
Location: Marlton, NJ
Posts: 174
Ginto8 is a glorious beacon of lightGinto8 is a glorious beacon of lightGinto8 is a glorious beacon of lightGinto8 is a glorious beacon of lightGinto8 is a glorious beacon of light
Re: CommandGroup questions

Given this expectation:
Quote:
Originally Posted by pblankenbaker View Post
  • Run CommandA first and wait for it to complete.
  • Then run CommandB and CommandC at the same time.
  • After CommandB and CommandC complete I then want to run CommandD.
This will not work:
Quote:
Originally Posted by pblankenbaker View Post
Code:
public static Command buildMyCommand() {
  CommandGroup cmd = new CommandGroup();
  cmd.addSequential(new CommandA());
  // Start of first command to run in parallel
  cmd.addParallel(new CommandB());
  // End of commands to run in parallel (runs in parallel with CommandB)
  cmd.addSequential(new CommandC());
  cmd.addSequential(new CommandD());

  return cmd;
}
A command added in parallel to a command group has no effect on when the commands after it run. CommandD will run when CommandC finishes, with no regard for whether or not CommandB is running. To fix this, add this line before CommandD:
Code:
cmd.addSequential(new WaitForChildren());
This will wait until all parallel commands have completed before moving on.

Quote:
Originally Posted by pblankenbaker View Post
My next questions have to do with what happens to a command group when things don't complete nicely:
  • If CommandA from the example command group above was interrupted, would the entire command group be interrupted? For example, let's assume CommandA was waiting for something to move into position and CommandB performed a firing action. If CommandA was interrupted, would CommandB still run, or would the interruption stop CommandB from ever being run?
If you directly cancelled CommandA, the CommandGroup would continue to the next Command in line, per lines 217-230 in CommandGroup.java:
Code:
            if (cmd != null) {
                if (entry.isTimedOut()) {
                    cmd._cancel();
                }
                if (cmd.run()) {
                    break;
                } else {
                    cmd.removed();
                    m_currentCommandIndex++;
                    firstRun = true;
                    cmd = null;
                    continue;
                }
            }
However, if the interruption is due to another command that requires() the same subsystem, the whole CommandGroup will be cancelled. A CommandGroup absorbs the requirements of all Commands within it.

Quote:
Originally Posted by pblankenbaker View Post
  • Secondly, Assume CommandA has used the setTimeout() method or was added to the group with a timeout option to indicate that it has 2 seconds to complete. If the timeout is reached, will the rest of the commands complete in the sequence?
If the timeout is reached, the command will not even terminate, unless you have an isFinished() method like this (from WaitCommand.java):
Code:
    protected boolean isFinished() {
        return isTimedOut();
    }
However, there is a way to add a timeout within a CommandGroup. addSequential and addParallel are both overloaded so that you can specify a timeout after which the Command will be cancelled and the next Command in the group will begin, like so:
Code:
addSequential(new CommandA(),2.0); // times out after 2 seconds
__________________
I code stuff.
Reply With Quote
  #4   Spotlight this post!  
Unread 13-02-2014, 13:50
pblankenbaker pblankenbaker is offline
Registered User
FRC #0868
 
Join Date: Feb 2012
Location: Carmel, IN, USA
Posts: 108
pblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of light
Re: CommandGroup questions

Thanks for the explanations. If I understand things correctly, when the goal is to build a command group that has the following pattern:
  • Runs CommandA first and wait for it to complete.
  • Then runs CommandB and CommandC at the same time.
  • After CommandB and CommandC complete CommandD is run.

There are at least two ways to code this:

Option A: Don't mix addParallel() and addSequential() (use nested CommandGroup objects instead):

Code:
public static Command buildMyCommand() {
  CommandGroup bc = new CommandGroup();
  bc.addParallel(new CommandB());
  bc.addParallel(new CommandC());

  CommandGroup cmd = new CommandGroup();
  cmd.addSequential(new CommandA());
  cmd.addSequential(bc);
  cmd.addSequential(new CommandD());

  return cmd;
}
Option B: Mix addParallel() and addSequential(), but only if you fully understand how CommandGroups work:

Code:
public static Command buildMyCommand() {
  CommandGroup cmd = new CommandGroup();

  // CommandA is the first command to run
  cmd.addSequential(new CommandA());

  // Start a command in parallel after CommandA finishes
  cmd.addParallel(new CommandB());

  // Start a sequential command (also starts after CommandA finishes
  // runs at the same time as CommandB)
  cmd.addSequential(new CommandC());

  // Wait for CommandB and CommandC to finish
  cmd.addSequential(new WaitForChildren());

  // Now it is OK to run CommandD (both CommandB and CommandC are done)
  cmd.addSequential(new CommandD());

  return cmd;
}

Option C: Mix addParallel() and addSequential(), similar to Option B, but uses addParallel() for CommandB and CommandC (which might be slightly more intuitive to look at):

Code:
public static Command buildMyCommand() {
  CommandGroup cmd = new CommandGroup();

  // CommandA is the first command to run
  cmd.addSequential(new CommandA());

  // Start a command in parallel after CommandA finishes
  cmd.addParallel(new CommandB());

  // Start a parallel command (also starts after CommandA finishes
  // runs at the same time as CommandB)
  cmd.addParallel(new CommandC());

  // Wait for CommandB and CommandC to finish
  cmd.addSequential(new WaitForChildren());

  // Now it is OK to run CommandD (both CommandB and CommandC are done)
  cmd.addSequential(new CommandD());

  return cmd;
}
Please let me know if the three above fragments won't yield the same results as I'm going to try to explain this to our programming leads today (I suspect we will be reviewing and refactoring a lot of command groups).

I think I prefer the nested command groups (Option A) for readability (human comprehension). Unless someone tells me this won't work, I will encourage this general rule of thumb when we introduce CommandGroups to new programmers joining the team (at least to get them started).

We will also need to review our command groups and think about the different behaviors between timeouts and interrupted situations. I suspect we have some commands that need to be coded a little more defensively so we don't break things on the robot for certain time outs (if CommandA times out, we may not want to run CommandB in the sequence).

Thanks again for the information,
Paul

Last edited by pblankenbaker : 13-02-2014 at 13:54.
Reply With Quote
  #5   Spotlight this post!  
Unread 13-02-2014, 13:55
notmattlythgoe's Avatar
notmattlythgoe notmattlythgoe is offline
Flywheel Police
AKA: Matthew Lythgoe
FRC #2363 (Triple Helix)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: Newport News, VA
Posts: 1,728
notmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond repute
Re: CommandGroup questions

Quote:
Originally Posted by pblankenbaker View Post
Thanks for the explanations. If I understand things correctly, when the goal is to build a command group that has the following pattern:
  • Runs CommandA first and wait for it to complete.
  • Then runs CommandB and CommandC at the same time.
  • After CommandB and CommandC complete CommandD is run.

There are at least two ways to code this:

Option A: Don't mix addParallel() and addSequential() (use nested CommandGroup objects instead):

Code:
public static Command buildMyCommand() {
  CommandGroup bc = new CommandGroup();
  bc.addParallel(new CommandB());
  bc.addParallel(new CommandC());

  CommandGroup cmd = new CommandGroup();
  cmd.addSequential(new CommandA());
  cmd.addSequential(bc);
  cmd.addSequential(new CommandD());

  return cmd;
}
Option B: Mix addParallel() and addSequential(), but only if you fully understand how CommandGroups work:

Code:
public static Command buildMyCommand() {
  CommandGroup cmd = new CommandGroup();

  // CommandA is the first command to run
  cmd.addSequential(new CommandA());

  // Start a command in parallel after CommandA finishes
  cmd.addParallel(new CommandB());

  // Start a sequential command (also starts after CommandA finishes
  // runs at the same time as CommandB)
  cmd.addSequential(new CommandC());

  // Wait for CommandB and CommandC to finish
  cmd.addSequential(new WaitForChildren());

  // Now it is OK to run CommandD (both CommandB and CommandC are done)
  cmd.addSequential(new CommandD());

  return cmd;
}

Option C: Mix addParallel() and addSequential(), similar to Option B, but uses addParallel() for CommandB and CommandC (which might be slightly more intuitive to look at):

Code:
public static Command buildMyCommand() {
  CommandGroup cmd = new CommandGroup();

  // CommandA is the first command to run
  cmd.addSequential(new CommandA());

  // Start a command in parallel after CommandA finishes
  cmd.addParallel(new CommandB());

  // Start a parallel command (also starts after CommandA finishes
  // runs at the same time as CommandB)
  cmd.addParallel(new CommandC());

  // Wait for CommandB and CommandC to finish
  cmd.addSequential(new WaitForChildren());

  // Now it is OK to run CommandD (both CommandB and CommandC are done)
  cmd.addSequential(new CommandD());

  return cmd;
}
Please let me know if the two above fragments won't yield the same results as I'm going to try to explain this to our programming leads today (I suspect we will be reviewing and refactoring a lot of command groups).

I think I prefer the nested command groups (Option A) for readability (human comprehension). Unless someone tells me this won't work, I will encourage this general rule of thumb when we introduce CommandGroups to new programmers joining the team (at least to get them started).

We will also need to review our command groups and think about the different behaviors between timeouts and interrupted situations. I suspect we have some commands that need to be coded a little more defensively so we don't break things on the robot for certain time outs (if CommandA times out, we may not want to run CommandB in the sequence).

Thanks again for the information,
Paul
I agree, I like option A the best and it will be the most readable and should be the easiest to understand.
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


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

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


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