Command Base Programming Tutorials/Help?

Hello Chief Delphi,

Our team’s programming department needs more education in command base robot programming. We all understand programming logic, as we program other types of software, but we are having some trouble understanding command base Java. If anyone has any tutorials or sample code that we can use, we would greatly appreciate it. We especially need help with programming a drivetrain and pneumatics programming.

Thank you.

Let’s see…

Getting Started With Java for FRC
WPILib User Guide
Programming Guide (robot drive can be found on page 29 and pneumatics on page 34)
And here are two examples of team’s java code that I found floating around CD Media: one and two.

Oh my goodness! Opportunity!

If you are interested in learning command-based, I’d look into our base code that we have written. It follows the basic uses that the WPI stuff has, but gives you a way more in-depth look at how it works, lets you change it, and has a ton more features.

I’m currently working on video tutorials that are found here.

All information is available there. I’d love if you’d check it out! It’s fine if you don’t choose to use it, but I’d love some feedback anyways.

Thanks,

Joel

Thank you guys for the information.

I liked your videos and thought that they were very helpful, joelg236. I will definitely be looking out for more videos from you. I would just add some more emphasis on what each package does and an example of programming a robot. For example, make a project and show how to add subsystems and commands, while showing the programming of a simple drivetrain and maybe some pneumatic programming. That way, new teams and/or programmers can know how to program solenoids for gear-shifting, or something like that?

I put our 2012 competition code on our team’s Github page. So, if you guys want to check it out, here is the link: www.github.com/team4element/FRC-Team4-ReboundRumble-2012

Do you guys think that it is too messy? How could we better improve our code, and its organization, in the future?

If anyone has their competition code online, could you please posts links?

Thank you CD! :]

Thanks for the input! I am currently working on some videos about modules, about driving, threading, logging, game periods, and most importantly, how to use it for your code.

I also see the need for some additional tutorials in this area.
I have been trying to figure out how to get the command based java approach to work but I don’t fully comprehend the details.

My goal is to have a presentation that will walk any student thru the basics.

I am currently stuck on how the Commands are called by the autonomousInit, autonomousPeriodic, TeleopInit and TeleopPeriodic.

The cookbook is weak in this area.

I have attached my current presentation and Welcome feedback.

Dave Frederick
Team 1895, Mentor

df20705_Robotics_JAVA_Practice_board_v03.zip (543 KB)


df20705_Robotics_JAVA_Practice_board_v03.zip (543 KB)

That’s an interesting presentation. I don’t have specific notes right now but if I do I’ll post them.

Here is a link to a presentation I gave this summer during our summer workshop series.
http://goo.gl/EjLHM (It looks better if you download it, the online viewer messes with the fonts).

Also here is the demo program I had students work with the next day.
https://github.com/Spectrum3847/SpectrumWorkshop

Update to the draft. About 40% complete.
Lots more to learn.

Dave Frederick, Mentor
Team 1895, Manassas, VA

df20705_Robotics_JAVA_Practice_board_v04.zip (611 KB)


df20705_Robotics_JAVA_Practice_board_v04.zip (611 KB)

I’ve been looking through your presentation, and it seems pretty good. I have some constructive criticism:

  • On slide 11 (talking about the RobotTemplate class), you talk about the “IterativeRobot” approach as something entirely separate from the Command approach. IterativeRobot is actually part of the Command-based approach, and can be used exactly like a typical IterativeRobot. The big difference between using IterativeRobot normally (putting all robot logic in either the periodic() or continuous() functions) and using Commands is that the periodic() functions MUST call
Scheduler.getInstance().run();

This call handles all the details of executing and stopping Commands. In fact, you could simultaneously use the normal IterativeRobot approach and the Command approach… it would just be a terrible headache :stuck_out_tongue:

  • This is more of a design concern than anything being wrong, but having two different Commands (LED_Off and LED_On) for a single idea (setting the LED’s state) seems unnecessary and a bit cumbersome. Having a LED_Set Command that takes a boolean in the constructor would require less code, and would only change
button4.whenPressed(new LED_Off());
button5.whenPressed(new LED_On());

to

button4.whenPressed(new LED_Set(false));
button5.whenPressed(new LED_Set(true));

To make this easier, IndicatorLED could have a set() method that looked like this:

public void set(boolean state) {
    LED_one.set(!state); // since false == on for DigitalOutputs, negate state
}
  • In slides 18 and 19 (“Create the commands used on the subsystem”), declaring a local copy of CommandBase’s static variable indicatorLED isn’t necessary. Because LED_On inherits from CommandBase, it can access all protected and public members of CommandBase, so the local version isn’t necessary. The constructor then can become more concise:
requires(indicatorLED);

The Scheduler only allows one running Command to require() a subsystem at a time, so that there isn’t any fighting over resources. Take for example, two commands, TankDrive and ArcadeDrive. Both would require() the driveTrain Subsystem. If both were running at once, the results would be… surprising, to say the least. But since they both require() driveTrain, when one starts the other is automatically stopped so they don’t cause trouble.

A full example implementation of LED_Set (assuming IndicatorLED has a set() method as suggested before) would be:

public class LED_Set extends CommandBase {
    private boolean chosenState;
    public LED_Set(boolean state) {
        requires(indicatorLED);
        chosenState = state;
    }

    protected void initialize() {
        indicatorLED.set(chosenState);
    }

    protected void execute() {}

    protected boolean isFinished() {
        return true;
    }

    protected void end() {}
    
    protected void interrupted() {}
}
  • On slide 22 (“Bind a joystick action to the command (within the OI Class)”), you say you don’t understand what the static “instance” variable is for. This variable allows OI to be a lazy singleton, or more correctly a singleton with lazy initizialization. The basic pattern is this:
public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

This fulfills two requirements: 1) that only one instance of the class exists, and 2) that the instance isn’t initialized until it’s used.

  • On slide 24 (“Final configuration of commands”), the idea of the two Commands autonomousCommand and teleopCommand is that you can easily start and stop all autonomous/teleop activity by simply start()ing and cancel()ing the corresponding command. To make a single command perform multiple actions, just inherit from CommandGroup, like this:
public class TeleopTemplate extends CommandGroup {
    public TeleopTemplate() {
        addSequential(new FirstCommand()); // sequential commands run one after the other
        addParallel(new ParallelCommand()); // this command will run at the same time as SecondCommand and ThirdCommand
        addSequential(new SecondCommand());
        addSequential(new ThirdCommand());
        addSequential(new WaitForChildren()); // wait for ParallelCommand to finish
        addSequential(new FourthCommand()); // Will only run after both ThirdCommand and ParallelCommand have completed
    }
}

WaitForChildren is a Command provided by WPILib, the rest can be any command you create.

  • On slide 36 (when implementing the DynamicServoAngle command), I’m not sure why you say you need to instantiate the joystick on each execute()… To me it seems that it shouldn’t work, as I’m under the impression that multiple instances of the same Joystick would cause errors. Joysticks are typically supposed to remain in the OI class; in my code I don’t even expose them directly, instead having functions like getDriveRightAxis() and getDriveLeftAxis(). eg:
public class OI {
    // ... other stuff ...
    private Joystick joyServo = new Joystick(SERVO_JOYSTICK_PORT);
    public getServoAxis() {
        return joyServo.getRawAxis(1);
    }
}

Thank you for the feedback. I will review your comments in detail this weekend and update the presentation accordingly.

I posted an updated version a couple of days ago on a similar thread.

I’m fairly new to Object Oriented programming and struggle with JAVA. It took me about two weeks to get the first example to work. I have a much better understanding now but miles to go.

While looking for help to learn this command based programming, I saw a lot of questions and few answers. I hoped to fill some of the void.

Thank you again,
Dave Frederick