Other threads have touched on this topic a bit, and the User’s Guide makes an attempt, but I have yet to see a definitive list of reasons for why I should choose IterativeRobot over SimpleRobot (or vice versa). Do you have any?
For the purposes of this exercise, let’s assume that my programming team is very comfortable in C++ and would have no trouble understanding the complexities of the IterativeRobot paradigm. However, we also have very little programming experience invested in the prior seasons, so we’re not necessarily more comfortable with one model over the other.
Let’s also assume that our robot will want to do some standard but fairly complex tasks: employ a variable-speed turret shooter using a camera to automatically track and fire at opponent’s trailer(s) while the robot simultaneously moves around the field collecting balls and keeping a ball inventory for the shooter. These tasks would take place in both teleop and autonomous.
Is there anything that would be very hard or impossible to do in this scenario using SimpleRobot? Anything that mandates Iterative over Simple? How about SimpleRobot combined with the judicious use of Tasks?
It would appear that one might get finer programmatic control by using IterativeRobot however SimpleRobot has all the main virtuals needed for a decent robot control (IMHO). The big plus for IterativeRobot would be the ability to programmatically set the periodic loop delay. This could be very helpful if you’re using PID loops or other time-domain controls. Keep in mind, however, that you don’t have to use all the virtual functions if you don’t need them. This could simplify the code a great deal. You could also subclass your own IterativeRobot class and “hide” your virtuals.
I don’t think my team has decided yet which one they’ll use, but here are my opinions:
Simple robot is just that - simple. The structure of the code allows you absolute freedom in your design. Of course, with that freedom comes a little responsibility - you have to make sure you don’t screw it up :p. I haven’t looked terribly deeply into multithreading (or tasks, as they call it) yet, but we’ll probably be using it this year. From past experience, you have to be pretty careful about launching threads in loops, or you might end up with a hundred threads all trying to do the same thing. With the simple robot, you don’t have to worry as much about that, as there are no built in loops - you create them yourself!
The Iterative robot is the same type of set up we’ve had in previous years - an init, a fast loop, and a slow loop. For teams that have a lot of experience with those, it’s a great thing to use. for teams that don’t know what they’re doing, the built in looping structure can be a great way to ensure that your inputs and outputs are persistent throughout the competition period. Of course, launching new threads inside one of the loops could be very problematic…
Personally, i don’t like having a lot of structure imposed on me by code. I would rather do (sudo code with made up values):
It really is the case that the SimpleRobot class is designed to have a very straightforward model of the robot. One method for all your autonomous code and another for the teleop code. The Iterative robot was designed to model the older code from previous years.
With SimpleRobot the idea is to write straight-line code to do whatever is needed during the Autonomous period. You are completely in control during that time. One important note: the Autonomous method will keep running at the the end of the autonomous period in the game. It will not stop when the teleop period begins. So it is the programmers responsibility to make sure the Autonomous method returns by the end of the autonomous period. There are methods like IsAutonomous() that you can call or you can use the clock and timers, but be sure to return from the Autonomous method.
IterativeRobot attempts to solve that problem by continuously calling one of its methods over and over again. You write code in the appropriate method that does what it needs to do and returns. When the field (or the switch on your driver station) switches from Autonomous to Teleop, then it will stop calling your AutonomousContinuous() method and start calling your TeleopContinous() method. Your program doesn’t have to worry about keeping track of Autonomous vs. Teleop, but you do have to remember what the robot was doing from one call to the next.
For example, if you wanted to drive in a square pattern at the start of Autonomous it would work like this:
IterativeRobot: Your AutonomousContinuous method would be called over and over again during the autonomous period. So you write code that uses some variables to remember from call to call which side of the square it’s currently driving or if it’s turning. Using those variables the program would set the wheels to either be driving straight or turning. Remembering what the robot is doing is called its state, and this type of program is called a state machine.
SimpleRobot: Your Autonomous function is called once. You write a program that loops 4 times, driving each side of the square, then turning. You should check in the loop if the autonomous period is over by calling the IsAutonomous() method and returning from the Autonomous() method if it is.