Go to Post Losing, like criticism, is the only thing that makes you improve. - MooreteP [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 03-01-2014, 11:59
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,567
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
Making more reusable commands

Last year, we used Java with the command framework. I was very happy with how it ended up, our code was the best organized and easiest to modify that it's ever been. We used RobotBuilder, which reduced much of the tediousness of creating subsystems. However, we ended up with over 60 commands.

We did end up with a lot of very similar commands, that could be abstracted to the following:

turning on a motor at a fixed speed
turning off the motor
extending a pneumatic solenoid
retracting a pneumatic solenoid
toggling a pneumatic solenoid.

For each of these, we made methods in the subsystem for a particular motor or a particular solenoid that translated a forward or reverse on the solenoid to an extend or retract (which depended on which way the solenoid was wired and plumbed).

I'd like to be able to reduce the number of very similar commands and subsystem methods

I had a few thoughts, but none of us are very experienced with OO design patterns, so I'm hoping someone has a better way.

1) create generic commands, and make the solenoid/motor in the subsystem public, and pass the solenoid/motor to the command. This is probably the simplest, but I lose the ability to easily translate a forward/reverse to an extend/retract in one place.

2) do #1, but extend the solenoid class to have a parameter to determine whether forward is extend or retract. This solves #1s problem, but then it makes it much harder to use robot builder

3) make a solenoid interface for extend/retract, and have the subsystem implement the interface. Then you could pass the subsystem to a generic command. However, you would be limited to a single solenoid per subsystem.

Does anyone have other ideas? What did your team do?
  #2   Spotlight this post!  
Unread 03-01-2014, 13:09
Kevin Sevcik's Avatar
Kevin Sevcik Kevin Sevcik is offline
(Insert witty comment here)
FRC #0057 (The Leopards)
Team Role: Mentor
 
Join Date: Jun 2001
Rookie Year: 1998
Location: Houston, Texas
Posts: 3,673
Kevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond repute
Send a message via AIM to Kevin Sevcik Send a message via Yahoo to Kevin Sevcik
Re: Making more reusable commands

You can make commands generic-ish by passing parameters to a parameterized constructor, then having that command pass that parameter to a parameterized method of your subsystem. I'll type up a quick c++ example in a bit here and post it.

You might be able to pass a subsystem as a parameter, but i don't know off the top off my head how that would play with the "requires" functionality and all that.
__________________
The difficult we do today; the impossible we do tomorrow. Miracles by appointment only.

Lone Star Regional Troubleshooter
  #3   Spotlight this post!  
Unread 03-01-2014, 13:16
Andrew Lobos Andrew Lobos is offline
Registered User
FRC #0225 (TechFire)
Team Role: Mentor
 
Join Date: Feb 2011
Rookie Year: 2011
Location: Lancaster, PA
Posts: 61
Andrew Lobos is a jewel in the roughAndrew Lobos is a jewel in the roughAndrew Lobos is a jewel in the rough
Re: Making more reusable commands

Quote:
Originally Posted by Kevin Sevcik View Post
You can make commands generic-ish by passing parameters to a parameterized constructor, then having that command pass that parameter to a parameterized method of your subsystem. I'll type up a quick c++ example in a bit here and post it.
This is what we did in Java last year. There where generic commands like "SetFlywheel" that took parameters from the constructor and used them in the calls to the subsystem. These generic commands were implemented in CommandGroups that did specific tasks, like FarShot3 for full court 3pt.

Code is here if you'd like to take a look: https://github.com/FRCTeam225/2013Of...rc/org/team225
  #4   Spotlight this post!  
Unread 03-01-2014, 13:50
Tom Bottiglieri Tom Bottiglieri is offline
Registered User
FRC #0254 (The Cheesy Poofs)
Team Role: Engineer
 
Join Date: Jan 2004
Rookie Year: 2003
Location: San Francisco, CA
Posts: 3,186
Tom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond repute
Re: Making more reusable commands

We (on 254) usually just end up writing a bunch of boiler plate code to do this, but I think #3 is a solid way of solving this. Personally I don't make an abstraction until I have at least 3 things that need it (you know the whole bit about premature optimization...). If I had to, I'd make Subsystems implement Interfaces like "Extendable" or "Controllable" then make commands that handle that.

125 did this last year a little differently by subclassing subsystem, then building Commands that could control those types of subsystems.
https://github.com/kreeve/Nutrons201...Subsystem.java
  #5   Spotlight this post!  
Unread 03-01-2014, 21:40
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,567
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: Making more reusable commands

Quote:
Originally Posted by Tom Bottiglieri View Post
125 did this last year a little differently by subclassing subsystem, then building Commands that could control those types of subsystems.
https://github.com/kreeve/Nutrons201...Subsystem.java
Thanks, that's very similar to what I was thinking about.
  #6   Spotlight this post!  
Unread 04-01-2014, 01:47
Ziv Ziv is offline
Has code to be writing...
FRC #0125 (Nutrons)
Team Role: Alumni
 
Join Date: Mar 2010
Rookie Year: 2009
Location: Boston
Posts: 39
Ziv is a glorious beacon of lightZiv is a glorious beacon of lightZiv is a glorious beacon of lightZiv is a glorious beacon of lightZiv is a glorious beacon of light
Re: Making more reusable commands

Tom already mentioned my favorite approach to the problem . It allows for both abstracting away implementation details (the outside code never sees a solenoid) and easy parametrization (just describe what it means for a subsystem to be on or off and you get a bunch of methods and commands for free). Many shooters in 2013 (including 125's and apparently 330's) were well-suited for this approach, because, unlike shooting baskets or balancing in 2012, shooting frisbees and pyramid pull-ups generally didn't need to be done in more than one or two ways.

It's not frequent that there's such a nice common abstraction for all of a robot's subsystems, but every robot deserves a bit of thought about what code can be shared before throwing the towel in and making it in RobotBuilder. (If you're bored by repetition, don't make the repetition easier without first trying to avoid the repetition altogether. RobotBuilder does the first but not the second.) When designing a set of abstractions, I find the most important thing is to be extremely picky, even if it feels petty. You should *like* the result because you think it's *pretty* (or at least useful, if you don't see how anyone could use that adjective about code ). The 30 minutes of code architecture debate might only save you 30 seconds in the future, but the 30 minutes can be before the robot is ready to test while the 30 seconds will probably be right before a match.
  #7   Spotlight this post!  
Unread 03-01-2014, 13:52
Tom Bottiglieri Tom Bottiglieri is offline
Registered User
FRC #0254 (The Cheesy Poofs)
Team Role: Engineer
 
Join Date: Jan 2004
Rookie Year: 2003
Location: San Francisco, CA
Posts: 3,186
Tom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond reputeTom Bottiglieri has a reputation beyond repute
Re: Making more reusable commands

Quote:
Originally Posted by Joe Ross View Post
3) make a solenoid interface for extend/retract, and have the subsystem implement the interface. Then you could pass the subsystem to a generic command. However, you would be limited to a single solenoid per subsystem.
Build an interface that requires extend() and retract() methods, have the subsystem use it, then do whatever you need in the implementation of those methods
  #8   Spotlight this post!  
Unread 03-01-2014, 14:22
Alan Anderson's Avatar
Alan Anderson Alan Anderson is offline
Software Architect
FRC #0045 (TechnoKats)
Team Role: Mentor
 
Join Date: Feb 2004
Rookie Year: 2004
Location: Kokomo, Indiana
Posts: 9,113
Alan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond repute
Re: Making more reusable commands

If you're worried about writing commands to control individual cylinders, you're probably not at the appropriately high level of abstraction. I suggest that you should be controlling subsystems, not actuators. The subsystem implementation should take care of the details of motor and relay and solenoid control based on commands for speed and state.

Don't extend or retract a cylinder. Instead, engage or disengage a brake, or lock or unlock a latch, or open or close a gripper. It would be appropriate to extend or retract an arm, if that's the motion you've designed it to do.
  #9   Spotlight this post!  
Unread 03-01-2014, 14:57
yash101 yash101 is offline
Curiosity | I have too much of it!
AKA: null
no team
 
Join Date: Oct 2012
Rookie Year: 2012
Location: devnull
Posts: 1,191
yash101 is an unknown quantity at this point
Re: Making more reusable commands

I really think that it would be nice to make some sort of Library to set up everything for you. That way, could have code like:

int main() {
init victor("shooter");
setSpeed("shooter", 127);
return 0;
}

And yes, that was probably incorrect C syntax.
  #10   Spotlight this post!  
Unread 03-01-2014, 15:14
Alan Anderson's Avatar
Alan Anderson Alan Anderson is offline
Software Architect
FRC #0045 (TechnoKats)
Team Role: Mentor
 
Join Date: Feb 2004
Rookie Year: 2004
Location: Kokomo, Indiana
Posts: 9,113
Alan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond repute
Re: Making more reusable commands

Quote:
Originally Posted by yash101 View Post
I really think that it would be nice to make some sort of Library to set up everything for you.
That is what the RobotBuilder tool is for.
  #11   Spotlight this post!  
Unread 03-01-2014, 15:35
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,717
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: Making more reusable commands

Quote:
Originally Posted by Alan Anderson View Post
If you're worried about writing commands to control individual cylinders, you're probably not at the appropriately high level of abstraction. I suggest that you should be controlling subsystems, not actuators. The subsystem implementation should take care of the details of motor and relay and solenoid control based on commands for speed and state.

Don't extend or retract a cylinder. Instead, engage or disengage a brake, or lock or unlock a latch, or open or close a gripper. It would be appropriate to extend or retract an arm, if that's the motion you've designed it to do.
This is the way it should be done. The parts (solenoids, motor controllers, encoders, etc.) should be contained to each of the different subsystems and how you control those different parts should be strictly limited to the methods you make available to the commands. Commands should never have direct access to any of the devices set up in a subsystem.
  #12   Spotlight this post!  
Unread 03-01-2014, 16:20
Kevin Sevcik's Avatar
Kevin Sevcik Kevin Sevcik is offline
(Insert witty comment here)
FRC #0057 (The Leopards)
Team Role: Mentor
 
Join Date: Jun 2001
Rookie Year: 1998
Location: Houston, Texas
Posts: 3,673
Kevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond reputeKevin Sevcik has a reputation beyond repute
Send a message via AIM to Kevin Sevcik Send a message via Yahoo to Kevin Sevcik
Re: Making more reusable commands

Quote:
Originally Posted by notmattlythgoe View Post
This is the way it should be done. The parts (solenoids, motor controllers, encoders, etc.) should be contained to each of the different subsystems and how you control those different parts should be strictly limited to the methods you make available to the commands. Commands should never have direct access to any of the devices set up in a subsystem.
Agreed, but there's still value in parameterized Commands for things like 4ndr3wl is talking about. We did the same last year so we could have a Shoot command that we passed an enum to pick which set of speeds+angle we were firing at. As opposed to having a ShootFar, ShootNear, etc. command. Which means if we needed a new set of speeds+angle, we could just add another element to the array and another constant to the enum. Instead of adding yet another command.
__________________
The difficult we do today; the impossible we do tomorrow. Miracles by appointment only.

Lone Star Regional Troubleshooter
  #13   Spotlight this post!  
Unread 03-01-2014, 16:22
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,717
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: Making more reusable commands

Quote:
Originally Posted by Kevin Sevcik View Post
Agreed, but there's still value in parameterized Commands for things like 4ndr3wl is talking about. We did the same last year so we could have a Shoot command that we passed an enum to pick which set of speeds+angle we were firing at. As opposed to having a ShootFar, ShootNear, etc. command. Which means if we needed a new set of speeds+angle, we could just add another element to the array and another constant to the enum. Instead of adding yet another command.
Completely agree, we use a drive straight command that takes a power and a distance so we can reuse it.
  #14   Spotlight this post!  
Unread 03-01-2014, 17:20
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: Making more reusable commands

We were fully command-based last year except for solenoids. The vast majority of the time, we extend/retract solenoids based on a single button push making simple if/else statements in the TeleopPeriodic function the easiest to implement and modify.
  #15   Spotlight this post!  
Unread 03-01-2014, 17:26
Fifthparallel Fifthparallel is offline
Registered User
AKA: Sam Chen
FRC #1410
 
Join Date: Dec 2012
Rookie Year: 2011
Location: Denver, CO
Posts: 65
Fifthparallel is an unknown quantity at this point
Re: Making more reusable commands

You need to abstract business logic (interactions between subsystems, etc) away from functionality -- i.e. have business logic executed inside your commands and actually functionality (like extend/retract for a piston) be part of an API that gets thrown into that subsystem. Our 2013 C++ code isn't the best example, but it does have some examples -- https://github.com/FRC-Team-1410/UA2013-FRC1410-Robot
__________________
sudo chmod u+x helloworld.sh
gotta start somewhere.
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 03:11.

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