IterativeRobot, CommandRobot, or SampleRobot for brand new programmers?

Hello all :slight_smile:

I’m a programming mentor for a team with a lot of students with very, very little programming experience at all. To me, it looks clear that SampleRobot is by far the most straight forward way to go - honestly, if I’m understanding right, SampleRobot is much more “write out what you want it to do in what order,” as opposed to having to keep track of a state machine in Iterative. I have mixed feelings about CommandBased - as a programmer (who’s made a few robots), it seems VERY overly complex, especially for brand new programmers, to require entirely separate classes for every single thing you want the robot to do, especially when every command class is a single function.

SampleRobot really seems like the most straightforward and traditional way. But I do have a couple of quick questions - if using SampleRobot, do I have to check periodically if the robot has been disabled (IsAutonomous() && IsEnabled()), or will this be caught in Timer.Delay() pauses? I’ve mentored for FTC previously, and the autonomous thread would be killed if you disabled it when the main thread got control for a bit, i.e., when you delayed the Autonomous thread for a few milliseconds at least.

The WPILIB documentation makes it sound like the SampleRobot class is a lot harder to use, but I don’t really understand why. What am I missing?

Thanks as always for any input and advice everyone can offer :slight_smile:

This is precisely the problem with SampleRobot. :slight_smile: SampleRobot tends to encourage creation of loops and other constructs that don’t allow the robot to do more than one thing at a time, or can potentially loop infinitely.

Constructs such as this: Imagine a naive implementation of making an arm move:


while arm.isNotInPosition():
    arm.moveToPosition()

As I’m sure you’re aware, there are several obvious problems with this:

  • The arm may never be in position (the sensor broke), so your robot keeps moving the arm and does nothing else
  • The robot can’t drive while this loop is executing

By using state-based techniques that IterativeRobot encourages, you can avoid these problems.

I have mixed feelings about CommandBased - as a programmer (who’s made a few robots), it seems VERY overly complex, especially for brand new programmers, to require entirely separate classes for every single thing you want the robot to do, especially when every command class is a single function.

I dislike Command-based for the same reason, but I’ve heard RobotBuilder can take the edge off this.

if using SampleRobot, do I have to check periodically if the robot has been disabled (IsAutonomous() && IsEnabled()), or will this be caught in Timer.Delay() pauses? I’ve mentored for FTC previously, and the autonomous thread would be killed if you disabled it when the main thread got control for a bit, i.e., when you delayed the Autonomous thread for a few milliseconds at least.

In FRC there is no thread killing. If you never return from autonomous, you will never return from autonomous. Timer.delay only sleeps, it does no extra checking.

I tend to encourage an IterativeRobot/asynchronous “style” of programming, though I personally don’t like IterativeRobot itself because I would rather have a stable loop period instead of looping when the DS packet arrives.

Oh, I agree completely there. I’ve taught my kids around the whole “while this button is pressed keep doing whatever that button does” thing already. Handling more complex scenarios (going to a position automatically on a single button press) isn’t too difficult either (I personally don’t feel, anyway.)

In FRC there is no thread killing. If you never return from autonomous, you will never return from autonomous. Timer.delay only sleeps, it does no extra checking.

That is very good to know. I think that’s currently my only real issue with SampleRobot, then. Easy to catch in Teleop, as you’re going to be in a loop by definition, but requires throwing a lot of “did I get disabled?” in your code to be able to respond to getting disabled / end of autonomous quickly. Hmm.

If your robot is going to do
one
thing
at
a
time,
Then yes, Sample robot is probably the easiest way to get those things working sequentially. Iterative and command based take a bit more work to get set up to do the first thing. However, robots generally are expected to drive, sense, and manipulate all at the same time, making it very easy to get into states that you did not expect. Unless you already have experience implementing real-time systems on sequential processors, and want to teach this to your new programmers, I cannot recommend this paradigm.

Iterative and Command based are a bit more work to start (though not if you start with a good template), and they are much easier to add additional, simultaneous functions which potentially operate on different time scales. Command based is really object-oriented (to the point where it’s difficult to see where things start), so if you are not comfortable in that environment, I can certainly see why you would not want to use Command Based.

Iterative should give you a good bit of the real-time being behind the scenes without getting wrapped around object orientation too tightly - it’s pretty much that someone else has written the high level main loops, and the low level hardware libraries, and you’re writing subroutines do do a single pass of the different subtasks.

Disclosure: I did not set up our programming sub-team, but we use command-based, and intend to stick with it.

Hello, my team uses SampleRobot and I definitely agree that I think it is a lot more intuitive than Iterative. Being able to control how frequently it looped rather than waiting for a packet was more logical for our programmers. We never really got involved with CommandBased because we did not like all of the boilerplate code and thought that it was rather confusing with so many different classes.

But I do have a couple of quick questions - if using SampleRobot, do I have to check periodically if the robot has been disabled (IsAutonomous() && IsEnabled()), or will this be caught in Timer.Delay() pauses? I’ve mentored for FTC previously, and the autonomous thread would be killed if you disabled it when the main thread got control for a bit, i.e., when you delayed the Autonomous thread for a few milliseconds at least.

We have never had problems with our autonomous ever accidentally being disabled and, as a result, have not had to check during auto if the robot is enabled. This includes running Wait() to pause the robot (for C++, Timer.delay() for Java is comparable). In addition, we found that SampleRobot made more sense in this instance because running autonomous code every 20 ms or so did not seem to make sense.

The WPILIB documentation makes it sound like the SampleRobot class is a lot harder to use, but I don’t really understand why. What am I missing?

Honestly, the only part that might be a little confusing for new programmers is handling the looping within SampleRobot, but with some experience, I think it is more straight forward.

In case it helps out, here is my team’s code for this past year’s robot: 2016-ManOWar/src at master · CAPS-Robotics/2016-ManOWar · GitHub

We did use C++ for this and it seems that you use Java, but the same basic idea is present (just ignore all of the pointer fun). We used SampleRobot for this code and you can see that the autonomous does not actually check if it is still enabled. We ran this code in competition and never had any problems with the autonomous disabling during a match.
Disclaimer: I wrote some of this code, so it is not necessarily very good, but I hope it at least helps with the basic ideas.

Just because you can do something and it doesn’t break does not mean one should do so.

A great example of why loops are dangerous are these two bits of code in your autonomous: https://github.com/CAPS-Robotics/2016-ManOWar/blob/master/src/ManOWar.cpp#L89


while (!aligned) {
   ... do things
}

If your gyro breaks (maybe the wire gets messed up on accident), your robot will never enter teleoperated mode and that match is over for you.

Same thing here:


do {
... fire = someSensor > some_value
} while (!fire)

If your encoder breaks/gets disconnected, same business. You’re done.

Maybe you have magic hardware that never breaks, but I wouldn’t put my trust in that.

I’ve recently joined an FRC team as the programming mentor and went through a similar exercise.

The big appeal of command based approach for me is that it is its support for testing. By placing each robot function/feature into a command class then it’s possible to wire up a Smart Dashboard button to each command and allow that single function/feature to be executed and tested separately.

I ended up having more problems trying to customise Smart Dashboard buttons than writing a command based robot example but that’s a different story. In the end I got it sorted out and being able to test each command by pressing a button seems like a much better approach compared to large blocks of code in a loop.

I also prefer the iterative robot to Command Based since a lot of the important functionality of the Command Based system can be written using the Runnable interface and the ScheduledExecutor in Java. This provides both the benefit of reducing the number of black boxes in your code, as well as being a valuable learning experience. (There might also be some features that Command based doesn’t have that you can bake into your own solution.)

Wait that is a thing? This is my first year as the head robot programmer for the team and I never realized that it was possible that the robot could get stuck in autonomous and never enter teleop. I thought that the FCS changed modes automatically and that any residual problems from the autonomous would not affect the teleop.

That is incorrect.

Use the source, Luke. :wink:

As you can see from the source of SampleRobot, if you never return from the Autonomous function, OperatorControl will never be called. No magic here.

I have been working with our programmers for a while now and have been working with the WPILIBJ since the beginning in 2010.

Our team uses the command based framework. We like the way we can modularize the code: Break apart functionality into Subsystems, Define commands that operate on those subsystems and then connect the overall system together in the Robot.java code segment while abstracting the harward connections away in the RobotMap layer.

you can get a better look at this methodology by reviewing the Gearsbot code and if you look on Youtube there are videos on this system as well that explain it quite well.

I have looked at he RobotBuilder and in some places it can work reasonably. However, it does make it more difficult to understand your code and our programmers are not a fan of placing all the constructors in the RobotMap file. I use it VERY early in the development to help understand the connections and plan the structure of the code. I can also use it to help with quick testing of systems without having to focus on having everything in place; you can define the subsystems with all their sensors and actuators, then use the ‘Testing’ mode on the dashboard to verify system functionality.

I know that these capabilities can be developed using the other programming systems, like IterativeRobot, but we find this way easier.

Enjoy!

Floyd Moore

Yeah, I found that earlier today… if there was a way to break back out of this simply without having to constantly poll, SampleRobot would honestly be perfect. I spent a bit stewing on creating a new extension to RobotBase that would spawn killable threads for autonomous and teleop, but that would require thread.stop(), which has it’s own issues. If it got killed in the middle of an i2c command, it could pick up the device it was talking to.