Subsystem / Command style code

Anyone have Python (RobotPy) code written in the new Subsystem /
Command style to post as an example?

Does that just add unnecessary complexity, or is it actually a useful
way of writing code?

I have found that this way just bloats code. my old team switched to java this year from C++ and ended up with ~50 classes for what would have been ~10 in c++. I am however creating a scheduler for python. there is a thread around here called “need some feedback” with a link to the github. it still has yet to be tested on a robot but preliminary testing seems very promising.

I’m not really sure how that “bloats” code. Many small classes is better than few large classes.

maybe bloat is not the right word. why I had a hard time using it was that to do one thing like drive, you had to have one system that represented the drive, one command to drive and had to register the command in a diffrent place.

Correct, but I think that it does a good job of breaking up the subsystems away from the tasks. I think it also does a good job of (if programmed correctly) separating subsystems so you don’t run into issues of multiple systems using the same devices. Our team has been nothing but happy with our switch to Java, mainly because of the command based design. It creates a very intuitive process for students to learn from.

The Command style is good for some things, but it can also be limiting. We had our climbing routine working for Lake Superior, but did a code review between LS and North Star. We found that there were some additional features we would have liked to add, but the fact that the routine was Command based, adding in each step of the climb as a sequential task, created a rather huge hurdle to what we wanted to accomplish. In the end, we determined that it would have been too much time/effort for the gain. If we had just done it programatically without sequential commands, it would have been much simpler to add our new features.

Why could it not have been accomplished through a CommandGroup adding commands in series?

It was set up as a command group with a number of commands set up sequentially (you can have sequential and parallel commands) - the idea being that to climb we wanted the arm to go to position 1, then position 2, then position 3, etc. Doing this with the command group and sequential commands utilizing a PID loop was pretty easy - each command would call the PID controller until we hit the target point, then return true (in fact, we only really had 1 command that was passed in different target values).

Now, for the hard part… how do we reset the command group in the middle (either between commands, or in the middle of a command)? As we looked at it, it quickly grew extremely messy to get the type of interrupted behavior we wanted - the option to restart completely, or simply “back up” one or more commands. This was driven mostly by a couple of runs where the climb got messed up and we missed the next bar. We ended up solving that issue a different way, but it still would have been real nice to have a “back up one step” ability in the command group.

Ahh, I see what you are saying. I’d have to think through that one.

We ended up having an issue with how things were scheduled, when they execute and what happened once they were finished. We implemented our own CommandGroupBase. https://github.com/Team3574/Alastair/blob/master/src/edu/wpi/first/wpilibj/templates/commands/CommandGroup2Base.java. I hope it helps some other teams that want to continue to dabble in the command / subsystem style code.

This shows an implementation of a drive with my proposed system. There is a DriveTeleop method that drives with joysticks and a DriveForTime that is scheduled here. I believe this (for me atleast) is a much more readable and easier to maintain system than the current command base used in java.

I’m curious, could you elaborate on the issues you were having? Maybe we are having the same issues and haven’t noticed it yet. I apologize for derailing this thread from it’s original topic.

I was not mentoring robot coding this year, I was helping with the vision code. One thing I remember though had to do with the scheduling and how/when they execute. Sample

addParallel(new HopActuate());
addParallel(new FlingerInfield());
addSequential(new Wait(3.0));

If we were to schedule these commands the order of execution is Wait(3.0), HopActuate(), FlingerInfield(). To us that was just screwball.

The link to the CommandGroup2Base makes it so that as soon as the parallel is reached it starts and does not wait on a sequential to be started. the new order of execution would be HopActuate(), FlingerInfield(), Wait(3.0). That seems more straight forward doesn’t it?