New to programming

Hello,
I would like to help out more with programming in the upcoming build season.
I wasn’t able to program much during the past two years. I understand programming in Java well and I have been reading the WIPLibs and looking at my team’s code. But I am still a bit confused on programming.
I don’t understand why. Am I looking at the wrong resources? If you have some resources that you find helpful, please give them to me.

Thank you

Could you be more detailed as to where you’re having trouble so I can better help you? Is it a specific area of programming that you’re struggling in, a problem in your own code, or something else?

Yes please.

And if you’re having issues with your code could you post it for us?

I’m mostly confused on how everything works.
Such has how commands and subsystems interact and such. I have a basic understanding of RobotMap.java, and IO.java. Other than that I am a bit lost.
This is my team’s GitHub for this year’s code if you want to look at it: GitHub - TheHighlanders/RustyComms: 2017 FRC Steamworks

Ah yes. Command-Based programming and its respective hierarchy was one of the things that confused me the most when I first started learning FRC Java.

Put simply, everything in Command-Based starts with Robot.java. In the Robot.java class, you declare Subsystem objects - see lines 56:65 of 1058’s Robot.java. In addition you can call other methods at different robot states, defined by the methods that are automatically created in Robot.java.

Subsystems are where you declare objects for speed controllers, solenoids, and other physical items on your robot, as well as set up methods that can be called from Commands (we’ll get to that in a minute). See 1058’s Climberclass for an example of a simple subsystem. In this class, we declare the two CANTalon speed controller objects that drive our climber in lines 17 & 18, as well as enable brake mode on the initialization of the subsystem in lines 22 & 23. Then, we set up a setClimberOutput() method in lines 28:37, which is called from the ManualClimberDrive command. If you have a good understanding of basic Subsystems, you can explore our GearManipulatorclass for a more complex example.

On to Commands! Commands are the the part of your Java software that activates methods in Subsystems at specific times. To start, commands must declare the subsystems in which they are affiliated to keep things organized and so that multiple commands do not run on a single subsystem simultaneously (unless desired). In line 19 of our ManualClimberDrive command, we declare that it requires the climber subsystem, more specifically, the climber object we created in the Robot class (defined by Robot.climber). Next, when the climber command is initialized, in the initialize() method, we set a boolean to false once (line 25), then edit a value in the Robot class to set our LED state (line 27). In the execute() method, we repeatedly set the output of the climber to the desired speed value in line 38 - this is a method that is found in our Climber class - until the command is ended, when the climber output is set to 0 in line 48. If the command is interrupted, for example when another command requiring the Climber subsystem is called, the same is done - setting the climber output to 0 (line 55) and changing the LED state (line 57).

Commands can be grouped to run at the same time or sequentially with CommandGroups - this is useful in Autonomous. See our AutoShooter class for an example of a simple CommandGroup.

Commands (and CommandGroups) can be called from the OI on Joystick button pushes or during Autonomous - see line 204 of Robot where we fetch and set the Autonomous command, and line 222 when we start it.

tl-dr; Robot.java creates Subsystems which contain methods called by Commands, commands are scheduled by the OI in teleop or by the Robot.java class in Autonomous.

That’s a really good explanation!
Is there anything else other than commands and subsystems that I should know about?

In case you didn’t pick it up yet, it is very important when using command based (or iterative) robot to let the infrastructure do all of the job control and indeterminate iterations. Each of your methods, whether in the subsystems or the commands, should run in a quite short, predictable amount of time. In iterative, you’ll end up creating finite state machines (FSMs), with each iterative call being one step of the machine; in command-based, you can usually (theoretically always) avoid FSMs by creating an appropriate set of commands and command groups.

As an example from our robot this year, our gear hanger pushed the gear onto the peg until an encoder reached a predetermined value, at which point it receded and returned to its “normal” position, which was farther back when no gear was present (we had some proximity sensors to detect gear presence) and in a medium position when a gear was present to hold it securely.

Our original (incorrect) way to do hang the gear was to have a while loop push the gear out until reaching the appropriate angle. Unfortunately, when we were quite close to the airship, the hanger motor was not powerful enough to complete the stroke (it would have required pushing the robot backwards or the airship forwards). The bottom line was that the robot was hung on hanging, and was immobile for the remainder of the match because the method never ended and thus denied the other subsystems (e.g. the drive train) any CPU cycles.

The “correct” way was to have a “default command” which moved the hanger to the appropriate position based on whether a gear was present, and a “Hang” command whose execute() method always drove the hanger outward. The Hang command’s isfinished() method returned true if the angle had been achieved, or upon reaching a one second timeout. Even with appropriate lines containing a single brace, blank lines, and comments, each hanger command fit easily on a single printed page, and the hanger subsystem used less than half of the second page (and would have been shorter if we had not had three independent gear sensors).

Command Groups – this is how you can totally avoid explicitly implementing finite state machines. If you have a complex command, break it down into “atomic” commands, and combine them with the command group. Command groups support both sequential and parallel commands, though the way you build complex command groups isn’t obvious/intuitive (to me, anyway), so you need to read that carefully if you’ll use it.

I think it’s important to understand that commands and command groups are finite state machines. It’s just that the state machine logic has been abstracted away and is handled by the framework.