Go to Post We only ask that, when able, you too help other teams as we have helped you. It is this mentality of passing it forward that makes teams and FIRST great. - E. Wood [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 26-02-2014, 14:34
DjScribbles DjScribbles is offline
Programming Mentor
AKA: Joe S
FRC #2474 (Team Excel)
Team Role: Mentor
 
Join Date: Oct 2011
Rookie Year: 2012
Location: Niles MI
Posts: 284
DjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to behold
Impressions: Command Based Robot

So, this year I decided to climb out of my familiar cave and try something new with our robot coding by switching to the (C++) Command Based pattern (this decision was helped by the great presentation from Brad Miller at CMP last year), rather than using my usual home-brewed iterative robot (still C++).

Overall, I am glad I made the switch, because our robot this year is much more complex than past years, and I know I would have struggled with tuning various systems using the 5 analog inputs on the Driver Station dash board; but I've also caught myself longing to just ditch the commands and just code a bunch of GetRawButtons in TeleopPeriodic and an Iterative switch case in AutonomousPeriodic (which I know I can do without wholly ditching the command based pattern). A lot of the problems I've had can be attributed to unfamiliarity with the pattern, but there are a lot of cases where the pattern simply feels to restrictive or requires a lot of added complexity to implement something fairly simple.

To the point, I thought it might be helpful/interesting to share what I perceived to be the pros and cons of the command based pattern:


Pros:

• If you build your commands correctly, simple to moderately complex Autonomous routines (and other chained actions) are very easy to build.

• If written correctly, commands can serve as unit tests.

• Commands are very, very useful for building test methods (along with SmartDashboard) that can be enabled without downloading special code.

• The pattern encourage the use of tools, such as RobotBuilder, SmartDashboard, and Test mode, which has been a life saver this season.

• The code is implemented in small chunks, often the patterns are pretty repeatable, and the commands are generally fairly simple.
Cons:

• Concurrent commands that have complex interactions between each other get complicated fast, to the point that it seems easier to 'cheat'

• When a command finishes, if you assign a default command, it takes over immediately, which can get tricky when you build a sequence of commands (where each must finish for the next to execute)

• For us, in order to spin the shooter wheels and fire, you need them both to be different subsystems (without cheating in your commands, or making a goofy "KeepSpinningAndShoot" command), even though they are functionally tightly coupled; because a command that requires a subsystem will interupt the current command that is executing on that subsystem when it runs.

• The syntax is much more complicated than iterative robots tend to be, I typically try to avoid pointers and static members in our robot code because they are syntactically and conceptually complex for beginners, however they are pretty much mandatory in commands. Switching to Command Based was intended to help the students become more independent in the development of the robot, however the huge jump in syntax complexity became a stumbling block.

• If not properly written, a command can work well in isolation, but hang an autonomous routine because it never ends, or never execute because it ends immediately.

• To do commands right, you end up having a ton of them, all the added files tend to create very long compile times in C++ (I've heard Java is better about this); also, either Windriver tends to be overzealous about recompiling, or there are some weird circular dependencies, but generally if a header file changes, most of the code gets recompiled.

• Tons of commands leads to a lot of small, similar files. Sometimes updating the boiler plate in all instances can be quite cumbersome.

• Figuring out the right way to do things when a necessary feature isn't supported by robot builder can be interesting. For example adding a Camera subsytem as an empty subsystem in RobotBuilder, then manually adding the camera outside the auto-generated regions; or to create a Counter class, adding digital inputs to robot builder, then using those to initialize the counter class rather than using the channels directly.
I think next season (assuming I am still with my team), I am certainly going to use RobotBuilder, SmartDashboard, and LiveWindow, however I don't know if I'm a fan of the Command system as a universal pattern, it certainly works great for special modes and cases, but for general robot operation it seems like it overcomplicates things; and in autonomous, simple sequences are very easy to build, however the command structure starts to feel burdensome when we begin trying to coordinate multiple actions to be time efficient.
  #2   Spotlight this post!  
Unread 26-02-2014, 14:41
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,729
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: Impressions: Command Based Robot

One thing that will help with having a ton of similar commands is to try to make your commands as reusable as possible.

We have a DeployArmCommand this year that pretty much covers all of the uses we need. We pass in a boolean if the arm should be deployed or not and a speed at which the rollers should spin. This command can then be used for any situation we need it for.

One of the biggest cons so far IMHO with the command based structure is the lack of conditionals for command groups. What we did to get around this was save the state that we need from a previous command in that command and pass the command in to the next command through the constructor. That way we can access the state of the first command after it has finished executing.

Overall we have very much enjoyed using the command based structure as I believe it is a great tool to teach OOD.
  #3   Spotlight this post!  
Unread 26-02-2014, 14:55
BigJ BigJ is offline
Registered User
AKA: Josh P.
FRC #1675 (Ultimate Protection Squad)
Team Role: Engineer
 
Join Date: Jan 2007
Rookie Year: 2007
Location: Milwaukee, WI
Posts: 947
BigJ has a reputation beyond reputeBigJ has a reputation beyond reputeBigJ has a reputation beyond reputeBigJ has a reputation beyond reputeBigJ has a reputation beyond reputeBigJ has a reputation beyond reputeBigJ has a reputation beyond reputeBigJ has a reputation beyond reputeBigJ has a reputation beyond reputeBigJ has a reputation beyond reputeBigJ has a reputation beyond repute
Re: Impressions: Command Based Robot

One of the things we have realized that help cut down on the "weird and goofy commands" or commands that rely on each other is that a command only needs to "require" Subsystems that it intends to write to or change. If you're using a Subsystem in a read-only capacity you should be able to use it anywhere you want anytime you want.
  #4   Spotlight this post!  
Unread 26-02-2014, 15:16
DjScribbles DjScribbles is offline
Programming Mentor
AKA: Joe S
FRC #2474 (Team Excel)
Team Role: Mentor
 
Join Date: Oct 2011
Rookie Year: 2012
Location: Niles MI
Posts: 284
DjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to behold
Re: Impressions: Command Based Robot

Quote:
Originally Posted by notmattlythgoe View Post
One thing that will help with having a ton of similar commands is to try to make your commands as reusable as possible.

We have a DeployArmCommand this year that pretty much covers all of the uses we need. We pass in a boolean if the arm should be deployed or not and a speed at which the rollers should spin. This command can then be used for any situation we need it for.
To me, what you've described sounds more like the role of a subsystem than a command; and I feel like that is one of the hangups I've got with the system, I believe the subsystem as a model makes is a more proper place to put business logic (such as a state machine that determines when to activate the roller while lowering the arm), but doing so reduces commands to such a trivial role that they just get in the way.

If you build this functionality into your command, then does that simply leave your subsystem as container classes for actuators and sensors?
  #5   Spotlight this post!  
Unread 26-02-2014, 15:24
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,729
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: Impressions: Command Based Robot

Quote:
Originally Posted by DjScribbles View Post
To me, what you've described sounds more like the role of a subsystem than a command; and I feel like that is one of the hangups I've got with the system, I believe the subsystem as a model makes is a more proper place to put business logic (such as a state machine that determines when to activate the roller while lowering the arm), but doing so reduces commands to such a trivial role that they just get in the way.

If you build this functionality into your command, then does that simply leave your subsystem as container classes for actuators and sensors?
I've always treated Subsystems as systems that describe the very basic functionality of the robot and the Commands are where the logic goes to control those subsystems. This allows you to have extremely basic commands that you can group together into command groups, or write more complex commands. I think it gives you a little more flexibility this way.

If you'd like I can send you a presentation that our team did for Command Based programming, it's for Java, but a lot of the concepts should be the same. It is very basic though, so most of it is probably going to be at a lower level than you'd like.
  #6   Spotlight this post!  
Unread 26-02-2014, 15:31
Andrew Schreiber Andrew Schreiber is offline
Joining the 900 Meme Team
FRC #0079
 
Join Date: Jan 2005
Rookie Year: 2000
Location: Misplaced Michigander
Posts: 4,080
Andrew Schreiber has a reputation beyond reputeAndrew Schreiber has a reputation beyond reputeAndrew Schreiber has a reputation beyond reputeAndrew Schreiber has a reputation beyond reputeAndrew Schreiber has a reputation beyond reputeAndrew Schreiber has a reputation beyond reputeAndrew Schreiber has a reputation beyond reputeAndrew Schreiber has a reputation beyond reputeAndrew Schreiber has a reputation beyond reputeAndrew Schreiber has a reputation beyond reputeAndrew Schreiber has a reputation beyond repute
Re: Impressions: Command Based Robot

Quote:
Originally Posted by DjScribbles View Post
To me, what you've described sounds more like the role of a subsystem than a command; and I feel like that is one of the hangups I've got with the system, I believe the subsystem as a model makes is a more proper place to put business logic (such as a state machine that determines when to activate the roller while lowering the arm), but doing so reduces commands to such a trivial role that they just get in the way.

If you build this functionality into your command, then does that simply leave your subsystem as container classes for actuators and sensors?
Nearly all of our logic for a given subsystem is in the commands. When logic incorporates multiple subsystems we utilize CommandGroups. For example, our intake must be in a certain position to fire. Thus we have a CommandGroup that does:

Code:
addSequential(new DropIntakeCmd());
addSequential(new FireShooterCmd());
Because DropIntakeCmd isn't marked as finished until the sensor reads that the intake is in the proper position the logic works out.

This sort of construction allowed us to write our sequences and autons via flowcharting on a chalkboard.

However, after attempting CommandBase last year with C++ I can say that it was a bit more of a pain. Java is much much cleaner in my opinion.

Codebase for reference: https://github.com/FRC125/NU14
__________________




.
  #7   Spotlight this post!  
Unread 26-02-2014, 15:48
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,600
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: Impressions: Command Based Robot

Quote:
Originally Posted by notmattlythgoe View Post
We have a DeployArmCommand this year that pretty much covers all of the uses we need. We pass in a boolean if the arm should be deployed or not and a speed at which the rollers should spin. This command can then be used for any situation we need it for.
We find it nice to have simple commands that don't need any outside input (so they can be run from SmartDashboard for debugging. Because of this, we make a complicated command (like your DeployArmCommand) and then make a bunch of commands that extend the complicated command and pass the appropriate data.

We've ended up putting Safety logic in the subsystem, so that everyone is guaranteed to use it, but put Business logic in the command.
  #8   Spotlight this post!  
Unread 26-02-2014, 15:51
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,600
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: Impressions: Command Based Robot

Quote:
Originally Posted by DjScribbles View Post
• When a command finishes, if you assign a default command, it takes over immediately, which can get tricky when you build a sequence of commands (where each must finish for the next to execute)
If you use CommandGroups, the default command won't run until the CommandGroup finishes. However, you do have to think about your end and interrupted methods to make sure they don't do something you don't want when run in a sequence.
  #9   Spotlight this post!  
Unread 26-02-2014, 15:53
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,729
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: Impressions: Command Based Robot

Quote:
Originally Posted by Joe Ross View Post
We find it nice to have simple commands that don't need any outside input (so they can be run from SmartDashboard for debugging. Because of this, we make a complicated command (like your DeployArmCommand) and then make a bunch of commands that extend the complicated command and pass the appropriate data.

We've ended up putting Safety logic in the subsystem, so that everyone is guaranteed to use it, but put Business logic in the command.
I like this strategy also. But couldn't you just send the command to the smart dashboard with the parameters included? We decided to use Network Tables this year instead of the SmartDashboard, so I could be mistaken.

Also, I cannot wait until next year when we can use ENUMs to send in different states to subsystems and commands.
  #10   Spotlight this post!  
Unread 26-02-2014, 16:15
DjScribbles DjScribbles is offline
Programming Mentor
AKA: Joe S
FRC #2474 (Team Excel)
Team Role: Mentor
 
Join Date: Oct 2011
Rookie Year: 2012
Location: Niles MI
Posts: 284
DjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to behold
Re: Impressions: Command Based Robot

As an example of what I mean by business logic, here is the bulk of code from our collector:

We need to know the state of the collector when we control our arm (the two can collide while the collector is up). So having the collector subsystem know it's state seems like the appropriate way to manage this.

Code:
void Collector::MoveCollector(bool extend)
{
	if (extend == true)
	{
		if (collectorLifter->Get() != DoubleSolenoid::kForward)
		{
			timeTravel.Reset();
			timeTravel.Start();
		}
		collectorLifter->Set(DoubleSolenoid::kForward);
	}
	else
	{
		if (collectorLifter->Get() != DoubleSolenoid::kReverse)
		{
			timeTravel.Reset();
			timeTravel.Start();
		}
		collectorLifter->Set(DoubleSolenoid::kReverse);
	}
}

Collector::CollectorState Collector::GetState()
{
	if ((timeTravel.Get() >= TIME_TRAVELING_UP) && (collectorLifter->Get() == DoubleSolenoid::kReverse))
	{
		return UP;
	}
	if ((timeTravel.Get() < TIME_TRAVELING_UP) && (collectorLifter->Get() == DoubleSolenoid::kReverse))
	{
		return TRAVELING_UP;
	}
	if ((timeTravel.Get() >= TIME_TRAVELING_DOWN) && (collectorLifter->Get() == DoubleSolenoid::kForward))
	{
		return DOWN;
	}
	if ((timeTravel.Get() < TIME_TRAVELING_DOWN) && (collectorLifter->Get() == DoubleSolenoid::kForward))
	{
		return TRAVELING_DOWN;
	}
	return IDLE;
}
It doesn't seem appropriate to tuck the state into a command somewhere. I could see setting the currentState on the End of command though; however the logic of how long it takes to actuate still seems more appropriate in the subsystem, because it is an attribute of that subsystem, not of the command that triggered the action.

Last edited by DjScribbles : 26-02-2014 at 16:21.
  #11   Spotlight this post!  
Unread 26-02-2014, 17:01
DjScribbles DjScribbles is offline
Programming Mentor
AKA: Joe S
FRC #2474 (Team Excel)
Team Role: Mentor
 
Join Date: Oct 2011
Rookie Year: 2012
Location: Niles MI
Posts: 284
DjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to beholdDjScribbles is a splendid one to behold
Re: Impressions: Command Based Robot

Quote:
Originally Posted by Joe Ross View Post
We find it nice to have simple commands that don't need any outside input (so they can be run from SmartDashboard for debugging. Because of this, we make a complicated command (like your DeployArmCommand) and then make a bunch of commands that extend the complicated command and pass the appropriate data.
This would definitely help with our boiler-plate problem, we have a command for each of our arm positions, each is identical save for a single parameter; this would be a huge improvement there.

Quote:
Originally Posted by Joe Ross View Post
If you use CommandGroups, the default command won't run until the CommandGroup finishes. However, you do have to think about your end and interrupted methods to make sure they don't do something you don't want when run in a sequence.
This is really one of the biggest annoyances I've had with adopting the pattern. For our shooter (wheel driven with a piston to fire), we have a spin-up command that sets the target RPM while the command is running, and stops the wheels when the command completes. In order to make this work, the shooter subsystem needed to be broken into two subsystem, one for the wheel motors and one for the piston, so that the Fire command did not interrupt the Spin-Up command. (Alternatives would have been having the spin up command interrupt/end without stopping the wheels, but then the default command or an on release command would have to pick up the slop)

This became a problem in autonomous as well, since the spin-up routine didn't end, a seperate command needed to be created to do the same thing, but with a different life-span. (I've since realized that adding this in parallel would have been the better solution, however the nuances of the parallel/sequential weren't clear at the time)
  #12   Spotlight this post!  
Unread 26-02-2014, 17:13
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: Impressions: Command Based Robot

Quote:
Originally Posted by DjScribbles View Post
• Concurrent commands that have complex interactions between each other get complicated fast, to the point that it seems easier to 'cheat'
I think this is an issue of Command design, not of the overall model. If there are two Commands that interact in weird ways if used improperly, I try to contain their use cases in CommandGroups that can guarantee that they will interact as desired. This isn't always feasible, but it can be much more readable than a complex redesign to handle the weirdness.

Quote:
Originally Posted by DjScribbles View Post
• When a command finishes, if you assign a default command, it takes over immediately, which can get tricky when you build a sequence of commands (where each must finish for the next to execute)
If you're using a CommandGroup, this isn't a problem. CommandGroups implicitly require() all subsystems that the Commands in them require. This year our launcher requires some pretty complex sequences, but by using CommandGroups and setting one as the default command, we were able to automate all but a very small part of it.

Quote:
Originally Posted by DjScribbles View Post
• For us, in order to spin the shooter wheels and fire, you need them both to be different subsystems (without cheating in your commands, or making a goofy "KeepSpinningAndShoot" command), even though they are functionally tightly coupled; because a command that requires a subsystem will interupt the current command that is executing on that subsystem when it runs.
This is a situation where running the wheel control in a different thread (eg. through a PIDController/PIDSubsystem) would be helpful. Last year, our Shoot command looked like this:
Code:
addSequential(new SpinUp(speed));
addSequential(new DeployDisk());
While this ran, even after SpinUp ended, the wheel kept spinning. Using a PIDSubsystem also let us add a safety feature: the default command waited 5 seconds, then spun the wheel down, in case it hadn't been done manually.

Quote:
Originally Posted by DjScribbles View Post
• Tons of commands leads to a lot of small, similar files. Sometimes updating the boiler plate in all instances can be quite cumbersome.
If you are suffering from a lot of boiler-plate, make some classes to inherit from! For example, our code-base includes this class:
Code:
// Does nothing, and keeps doing it forever
public class DoNothing extends Command {
    public DoNothing() {}
    protected void initialize() {}
    protected void execute() {}
    protected boolean isFinished() {
        return false;
    }
    protected void end() {}
    protected void interrupted() {}
}
Quote:
Originally Posted by DjScribbles View Post
• Figuring out the right way to do things when a necessary feature isn't supported by robot builder can be interesting. For example adding a Camera subsytem as an empty subsystem in RobotBuilder, then manually adding the camera outside the auto-generated regions; or to create a Counter class, adding digital inputs to robot builder, then using those to initialize the counter class rather than using the channels directly.
This is one of the reasons my team does not use RobotBuilder. It's very good for getting some example code or a base to start from, but as soon as you try to modify anything in a way that the template's writer didn't think of, you're somewhat screwed. Creating the subsystems and declaring all the hardware by hand is not an arduous task, and reduces barriers to any necessary changes.
__________________
I code stuff.
  #13   Spotlight this post!  
Unread 26-02-2014, 17:47
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,729
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: Impressions: Command Based Robot

Quote:
Originally Posted by Ginto8 View Post
I think this is an issue of Command design, not of the overall model. If there are two Commands that interact in weird ways if used improperly, I try to contain their use cases in CommandGroups that can guarantee that they will interact as desired. This isn't always feasible, but it can be much more readable than a complex redesign to handle the weirdness.


If you're using a CommandGroup, this isn't a problem. CommandGroups implicitly require() all subsystems that the Commands in them require. This year our launcher requires some pretty complex sequences, but by using CommandGroups and setting one as the default command, we were able to automate all but a very small part of it.


This is a situation where running the wheel control in a different thread (eg. through a PIDController/PIDSubsystem) would be helpful. Last year, our Shoot command looked like this:
Code:
addSequential(new SpinUp(speed));
addSequential(new DeployDisk());
While this ran, even after SpinUp ended, the wheel kept spinning. Using a PIDSubsystem also let us add a safety feature: the default command waited 5 seconds, then spun the wheel down, in case it hadn't been done manually.


If you are suffering from a lot of boiler-plate, make some classes to inherit from! For example, our code-base includes this class:
Code:
// Does nothing, and keeps doing it forever
public class DoNothing extends Command {
    public DoNothing() {}
    protected void initialize() {}
    protected void execute() {}
    protected boolean isFinished() {
        return false;
    }
    protected void end() {}
    protected void interrupted() {}
}

This is one of the reasons my team does not use RobotBuilder. It's very good for getting some example code or a base to start from, but as soon as you try to modify anything in a way that the template's writer didn't think of, you're somewhat screwed. Creating the subsystems and declaring all the hardware by hand is not an arduous task, and reduces barriers to any necessary changes.
I don't know if they updated RobotBuilder to fix this or not but I also don't like how it declares all of the devices in the OI class. That was my biggest complaint with it.
  #14   Spotlight this post!  
Unread 26-02-2014, 18:01
Jefferson Jefferson is offline
Registered User
AKA: Jeff Clements
FRC #0016 (Bomb Squad)
Team Role: Mentor
 
Join Date: Jan 2011
Rookie Year: 2010
Location: Mountain Home, AR
Posts: 258
Jefferson has a reputation beyond reputeJefferson has a reputation beyond reputeJefferson has a reputation beyond reputeJefferson has a reputation beyond reputeJefferson has a reputation beyond reputeJefferson has a reputation beyond reputeJefferson has a reputation beyond reputeJefferson has a reputation beyond reputeJefferson has a reputation beyond reputeJefferson has a reputation beyond reputeJefferson has a reputation beyond repute
Re: Impressions: Command Based Robot

Quote:
Originally Posted by DjScribbles View Post
So, this year I decided to climb out of my familiar cave and try something new with our robot coding by switching to the (C++) Command Based pattern (this decision was helped by the great presentation from Brad Miller at CMP last year), rather than using my usual home-brewed iterative robot (still C++).

[snip]

I think next season (assuming I am still with my team), I am certainly going to use RobotBuilder, SmartDashboard, and LiveWindow, however I don't know if I'm a fan of the Command system as a universal pattern, it certainly works great for special modes and cases, but for general robot operation it seems like it overcomplicates things; and in autonomous, simple sequences are very easy to build, however the command structure starts to feel burdensome when we begin trying to coordinate multiple actions to be time efficient.
This is exactly how I felt last year and why we didn't build the robot around commands this year. Thanks for making the post I meant to make all off-season.
I really like RobotBuilder as a tool and have used it extensively since beta testing last year. I've come to appreciate the structure it builds. In fact, I start all my rookie programming sessions with it and every student who shows a mild interest in programming.
Our commands this year are limited to a few items we need to do infrequently. I don't see us going back to commands unless a student shows a very strong interest.
  #15   Spotlight this post!  
Unread 27-02-2014, 00:49
Pault's Avatar
Pault Pault is offline
Registered User
FRC #0246 (Overclocked)
Team Role: College Student
 
Join Date: Jan 2013
Rookie Year: 2012
Location: Boston
Posts: 618
Pault has a reputation beyond reputePault has a reputation beyond reputePault has a reputation beyond reputePault has a reputation beyond reputePault has a reputation beyond reputePault has a reputation beyond reputePault has a reputation beyond reputePault has a reputation beyond reputePault has a reputation beyond reputePault has a reputation beyond reputePault has a reputation beyond repute
Re: Impressions: Command Based Robot

As others have mentioned, one of the keys to command-based programming is dividing your robot up into as many different subsystems as possible, not just a few broad ones. When you put 2 actuators which don't always move at the same time in a subsystem, you are going to run into problems. I found this especially true when I was attempting to improve the code that our old programmer made last year. One of the big features I wanted was the ability for the operator to turn on the shooter wheel before we were ready to shoot, that way we wouldn't have to wait as long once we were lined up. Unfortunately, he had put the shooter motor in the same subsystem as our complex indexing system, and so implement such a simple feature as the ability to toggle a motor on/off required a huge restucturing of our code. So I guess this is one con.

Although I am generally a big advocate for command-based. I feel as though the benefits it offers are worth the extra hassle. And honestly, it works perfectly well and can do whatever you need it to do so long as you code it in the "correct" way (although that is much easier said than done).
Closed Thread


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 02:45.

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