Go to Post I truly love zipties. They're so elegant - permanent, yet disposable. Strong, yet flexible. Ubiquitous, yet somehow.... special. - Kris Verdeyen [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 12-02-2014, 11:28
aziobro aziobro is offline
Registered User
FRC #4475 (Terrier Byte Bots)
Team Role: Leadership
 
Join Date: Nov 2008
Rookie Year: 2009
Location: Newark,NJ
Posts: 7
aziobro will become famous soon enough
Using Coniditionals to Build Custom Command Groups

What is the proper way to build a custom command group based on a runtime change?

Example:
Program will look at smartdashboard and get the number of blobs seen.
Based on the number it will either drive straight and shot or
turn, drive straight and shoot.

I tied the following code in the command group constructor.

Code:
if (blobs < 2.0) {
            addSequential(new DriveToLeftAndPrepareShot());
            addSequential(new ShortDelay());
            addSequential(new TossBall3QPower());
            addSequential(new TossBallResetPosition());
            
        }
        else
        {
            addSequential(new DriveToRightAndPrepareShot());
            addSequential(new ShortDelay());
            addSequential(new TossBall3QPower());
            addSequential(new TossBallResetPosition());
        }
But it gets run during program load when the command group is constructed.
I want it to run After autonomous is started.
Reply With Quote
  #2   Spotlight this post!  
Unread 12-02-2014, 12:02
Joe Ross's Avatar Unsung FIRST Hero
Joe Ross Joe Ross is offline
Registered User
FRC #0330 (Beachbots)
Team Role: Engineer
 
Join Date: Jun 2001
Rookie Year: 1997
Location: Los Angeles, CA
Posts: 8,590
Joe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond repute
Re: Using Coniditionals to Build Custom Command Groups

Why not have two command groups built, and then decide which to run at the beginning of Autonomous? This is what we've done in the past.

Alternately, you would build the Command Group in your autonomousInit, rather then in the constructor of the Command Group.
Reply With Quote
  #3   Spotlight this post!  
Unread 12-02-2014, 12:22
aziobro aziobro is offline
Registered User
FRC #4475 (Terrier Byte Bots)
Team Role: Leadership
 
Join Date: Nov 2008
Rookie Year: 2009
Location: Newark,NJ
Posts: 7
aziobro will become famous soon enough
Re: Using Coniditionals to Build Custom Command Groups

The addsequential method does not work in a command for me?

It says that it is not defined.

I think that only works in a command group?
Reply With Quote
  #4   Spotlight this post!  
Unread 12-02-2014, 12:34
Joe Ross's Avatar Unsung FIRST Hero
Joe Ross Joe Ross is offline
Registered User
FRC #0330 (Beachbots)
Team Role: Engineer
 
Join Date: Jun 2001
Rookie Year: 1997
Location: Los Angeles, CA
Posts: 8,590
Joe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond repute
Re: Using Coniditionals to Build Custom Command Groups

Quote:
Originally Posted by aziobro View Post
The addsequential method does not work in a command for me?

It says that it is not defined.

I think that only works in a command group?
That's correct.
Reply With Quote
  #5   Spotlight this post!  
Unread 12-02-2014, 15:15
mwtidd's Avatar
mwtidd mwtidd is offline
Registered User
AKA: mike
FRC #0319 (Big Bad Bob)
Team Role: Mentor
 
Join Date: Feb 2005
Rookie Year: 2003
Location: Boston, MA
Posts: 714
mwtidd has a reputation beyond reputemwtidd has a reputation beyond reputemwtidd has a reputation beyond reputemwtidd has a reputation beyond reputemwtidd has a reputation beyond reputemwtidd has a reputation beyond reputemwtidd has a reputation beyond reputemwtidd has a reputation beyond reputemwtidd has a reputation beyond reputemwtidd has a reputation beyond reputemwtidd has a reputation beyond repute
Re: Using Coniditionals to Build Custom Command Groups

One thing we did, was stored the hot value in the Robot variable to reference later.

Here is an example of how we did that:

DriveForwardAndWatch:
-drives forward for n seconds
-watches while doing it
-if it determines the goal is hot, writes to the Robot hot variable.

WaitForShot:
-checks to see whether or not the first command saw hot through the Robot hot variable
-if it saw hot, finish
-if it didn't wait for n seconds

Shoot:
-

Not exactly what you were looking for, but may be good enough.

I for one wish there was a better way to do conditional commands, to support more complex state machines (i.e. firing different commands on success, failure, and timeout). However, I've never really been able to get this to work with the wpilib command structure.
__________________
"Never let your schooling interfere with your education" -Mark Twain
Reply With Quote
  #6   Spotlight this post!  
Unread 13-02-2014, 00:12
otherguy's Avatar
otherguy otherguy is offline
sparkE
AKA: James
FRC #2168 (The Aluminum Falcons)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: CT
Posts: 434
otherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to behold
Re: Using Coniditionals to Build Custom Command Groups

Quote:
Originally Posted by aziobro View Post
But it gets run during program load when the command group is constructed.
I want it to run After autonomous is started.
Move where you're instantiating the auto command. I think the default project creates the auto command in robotInit(). I'll assume that's where you're instantiating the command in your program.

If you move this statement down into autoInit() you should get what you're asking for, no?

Code:
public void autonomousInit() {
    	// instantiate and schedule the command used for the autonomous period
        autonomousCommand = new YourAutoCommand();
        autonomousCommand.start();

...
__________________
http://team2168.org
Reply With Quote
  #7   Spotlight this post!  
Unread 13-02-2014, 01:48
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: Using Coniditionals to Build Custom Command Groups

My team created a class just for this purpose here. To use it:
Code:
addSequential(new Conditional(<Command for true>,<Command for false>) {
    protected boolean condition() {
        return <condition>;
    }
});
<Command for true> and <Command for false> can be any command, or null if you want nothing to run in that case.
__________________
I code stuff.
Reply With Quote
  #8   Spotlight this post!  
Unread 13-02-2014, 06:25
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: Using Coniditionals to Build Custom Command Groups

Quote:
Originally Posted by Ginto8 View Post
My team created a class just for this purpose here. To use it:
Code:
addSequential(new Conditional(<Command for true>,<Command for false>) {
    protected boolean condition() {
        return <condition>;
    }
});
<Command for true> and <Command for false> can be any command, or null if you want nothing to run in that case.
Hey, just wanted to say thanks for posting your Conditional class - that is an awesome solution to dealing with building conditional command groups! I will be forwarding this to our programmers as they were just recently asking about conditional commands.
Reply With Quote
  #9   Spotlight this post!  
Unread 13-02-2014, 20:00
irvingc irvingc is offline
Registered User
FRC #0948 (Newport Robotics Group)
Team Role: Leadership
 
Join Date: Jan 2014
Rookie Year: 2011
Location: Bellevue, WA
Posts: 31
irvingc is on a distinguished road
Re: Using Coniditionals to Build Custom Command Groups

Quote:
Originally Posted by Ginto8 View Post
My team created a class just for this purpose here. To use it:
Code:
addSequential(new Conditional(<Command for true>,<Command for false>) {
    protected boolean condition() {
        return <condition>;
    }
});
<Command for true> and <Command for false> can be any command, or null if you want nothing to run in that case.
Have you tested your full autonomous sequence to be working using this Conditional command? My experience is that this pattern (a Command that instantiates and then .start()s another Command) does not work as intended.
Reply With Quote
  #10   Spotlight this post!  
Unread 13-02-2014, 20:55
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: Using Coniditionals to Build Custom Command Groups

Quote:
Originally Posted by irvingc View Post
Have you tested your full autonomous sequence to be working using this Conditional command? My experience is that this pattern (a Command that instantiates and then .start()s another Command) does not work as intended.
We haven't had a chance to thoroughly test it, but initial tests seem successful. The key aspect of this implementation is that it does not just start the Command, but also waits for the Command to finish. There may be an issue with the internal Command killing the CommandGroup it is called from because they each require() the same Subsystem. I will see what I can do to mitigate that.
__________________
I code stuff.
Reply With Quote
  #11   Spotlight this post!  
Unread 14-02-2014, 01:33
irvingc irvingc is offline
Registered User
FRC #0948 (Newport Robotics Group)
Team Role: Leadership
 
Join Date: Jan 2014
Rookie Year: 2011
Location: Bellevue, WA
Posts: 31
irvingc is on a distinguished road
Re: Using Coniditionals to Build Custom Command Groups

Quote:
Originally Posted by Ginto8 View Post
<snip> There may be an issue with the internal Command killing the CommandGroup it is called from because they each require() the same Subsystem. I will see what I can do to mitigate that.
Yeah, that's exactly the issue we ran into last year. Another drawback we found is that if you put a button on the SmartDashboard for this kind of nested command, you can't click on the button again to cancel the command like usual, because the original command already finished execution, it's the newly instantiated command that's making the robot move.

Anyway, I'll be interested to see what solution you come up with!
Reply With Quote
  #12   Spotlight this post!  
Unread 15-02-2014, 04:50
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: Using Coniditionals to Build Custom Command Groups

We will not be testing this until later today, but I wanted to share my expected solution to Conditional cancelling itself. It requires an extra class, edu.wpi.first.wpilibj.command.PublicCommand, which just exposes a number of Command's methods that are protected or package-private normally:
Code:
package edu.wpi.first.wpilibj.command;

import java.util.Enumeration;

/** A Command that exposes more internals to the world. */
public class PublicCommand extends Command {
    private final Command _c;

    public PublicCommand(Command c) {
        _c = c;
        for(Enumeration e = c.getRequirements();e.hasMoreElements();) {
            requires((Subsystem) e.nextElement());
        }
    }
    public Enumeration getRequirements() {
        return _c.getRequirements();
    }

    public void initialize() {
        if(_c != null) {
            _c.initialize();
        }
    }
    public void _initialize() {
        if(_c != null) {
            _c._initialize();
        }
    }

    public void execute() {
        if(_c != null) {
            _c.execute();
        }
    }
    public void _execute() {
        if(_c != null) {
            _c._execute();
        }
    }

    public boolean isFinished() {
        return _c == null || _c.isFinished();
    }

    public void end() {
        if(_c != null) {
            _c.end();
        }
    }
    public void _end() {
        if(_c != null) {
            _c._end();
        }
    }

    public void interrupted() {
        if(_c != null) {
            _c.interrupted();
        }
    }
    public void _interrupted() {
        if(_c != null) {
            _c._interrupted();
        }
    }
    
}
Then, Conditional becomes:
Code:
package storm2014.commands.control;

import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.command.PublicCommand;
import edu.wpi.first.wpilibj.command.Subsystem;
import java.util.Enumeration;

public abstract class Conditional extends Command {
    private final PublicCommand _ifTrue,_ifFalse;
    private PublicCommand _running = null;

    public Conditional(final Command ifTrue,final Command ifFalse) {
        // Wrap the Commands to expose protected methods
        if(ifTrue != null) {
            _ifTrue  = new PublicCommand(ifTrue);
            for(Enumeration e = _ifTrue.getRequirements();e.hasMoreElements();) {
                requires((Subsystem) e.nextElement());
            }
        } else {
            _ifTrue = null;
        }
        if(ifFalse != null) {
            _ifFalse  = new PublicCommand(ifFalse);
            for(Enumeration e = _ifFalse.getRequirements();e.hasMoreElements();) {
                requires((Subsystem) e.nextElement());
            }
        } else {
            _ifFalse = null;
        }
    }
    
    protected abstract boolean condition();

    protected void initialize() {
        if(condition()) {
            _running = _ifTrue;
        } else {
            _running = _ifFalse;
        }
        if(_running != null) {
            _running._initialize();
            _running.initialize();
        }
    }

    protected void execute() {
        if(_running != null) {
            _running._execute();
            _running.execute();
        }
    }

    protected boolean isFinished() {
        return _running == null || _running.isFinished();
    }

    protected void end() {
        if(_running != null) {
            _running._end();
            _running.end();
        }
    }

    protected void interrupted() {
        if(_running != null) {
            _running._interrupted();
            _running.interrupted();
        }
    }
}
Instead of start()ing the Commands, it wraps them entirely. The Conditional has all the combined requirements of ifTrue and ifFalse, and each of initialize(), execute(), isFinished(), end(), and interrupted() call the corresponding method in the selected Command. Because of that, running it should have the same effect as start()ing, except that it will not cancel a CommandGroup it is in.
__________________
I code stuff.

Last edited by Ginto8 : 15-02-2014 at 05:00.
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 13:19.

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