I’m trying to write my team’s autonomous code as a “one run and done” sequence of movement functions but I can’t figure out how to make a block of code in AutonomousPeriodic run once. I’ve tried using an if statement to test a boolean that is changed when the autonomous is executed but the variable won’t carry over from AutonomousInit and I don’t know what else I could do. Anyone know how to make it run once?
You should be able to do this:
boolean hasRanYet = false;
public void autonomousPeriodic() {
if(!hasRanYet) {
//Your one-and-done code goes here
}
hasRanYet = true;
}
...
...
...
public void disabledInit() {
hasRanYet = false;
}
You could run it from autonomousInit (and if you don’t have that then extend it from IterativeRobot), then it will only be called once.
Yes. The key is to declare "hasRanYet"as part of the object. If you declare it inside of the periodic method, a new variable is made for each time the method is called.
Others in this thread have mentioned using a boolean to signify when the block of code has been ran, which works, but I have also had success in using an integer move from step to step. As an example:
if(autoCounter == 0){//Step 1 - Move Forward
- if(rightSide.get() < 1500){//Until encoder count is reached
- ourRobot.arcadeDrive(-.45,.25*angleNow);//Use NavX to drive straight
- }
- else{//Once encoder count is reached
- ourRobot.arcadeDrive(0,0);//Stop
- autoCounter = 1;//Next step
- }
- }
- else if(autoCounter == 1){//Step 2 - ...
...
}
This is run in autonomous periodic (we are using iterative), you just have to make sure to set autoCounter to 0 in autonomous init.
@RileyC3826’s method is called a finite state machine, if anybody was wondering. You can do some pretty advanced stuff with them. The command-based design that WPI supplies is actually just an elaborated version of a FSM.
I would suggest, however, that if you start to build complex FSM’s in your own code, you really should check out the Command Based model for writing robot code.
We use a similar setup, but a lot more compartmentalized, and with a separate enumeration in each auto for the states. I can vouch that it works very well, and provides much more flexibility than command-based.
OK, now you have my attention
Do you have code in GitHub or somewhere that I could have a look? I’m all for improving things, if you’ve found something you like!
Does java not have the switch statement?
It does…
You could go to a real control language, LabView, and use a sequence block.
Sorry, I was steamrollered into Java last year and some of my limbs are still flat.
As others have said, use Commands and state machines, with the operations switch in <Command>.execute and the next state switch in IsFinished. Then next year you move on to more complex things in the same structure.
Or, you do the CommandGroup thing and get all of that order stuff out of the way with AddSequential and AddParallel in the constructor.
I know that this is a bit late, but for future reference, if you are using sensors, such as encoders-- or even timers, as a matter of fact-- you can tell the code to, for instance, run forward while the encoders are reading a certain value, or while the timer is under a set number of seconds. I believe this is how a lot of teams go about doing their auton modes.
IIRC from my formal languages course about thirty years ago, an FSM with a tape drive and an infinitely long tape can do anything that any computer can ever do. Any digital computer can be considered an FSM with 2number-of-bits-of-storage possible states. Even so, it is remarkable how much apparent complexity can be fit into an FSM with a few dozen states and a handful of sensors.
Yeah I can share the code soon now that the year is over for us.
That would be great. We’ve been happy so far using the command based framework but I definitely see where we are hitting its limits and I’d be interested to see what other teams have done to get around them.
I’m not a huge fan of the idea of writing our own custom framework (why reinvent the wheel?) or adopting another team’s framework (and making ourselves dependent on them for updates/bug fixes) but if there are significant advantages I would definitely consider it.
Our season is not over yet but here is our code. Our code uses our own framework and does not do command based. It resembles Iterative. It makes writing teleop and autonomous code extremely simple. In addition to providing concurrency, the framework also provides supports for various sensors and complex algorithms. Our autonomous at the high level is very simple but we had over 99% success rate on our autonomous in our District championship. The only one failure was really human error of not setting up the gear correctly. A video showing the accuracy of our autonomous can be found here (https://www.youtube.com/watch?v=zp0El7ETqhY).
https://github.com/trc492/Frc2017FirstSteamWorks/tree/master/src/team492
Something you can add are switch statements, and this is what our team does during autonomous. If you are doing “one run and done”, I am assuming you are using delays and stuff like that. I have attached the code below and if you any questions, feel free to get back to our team.
int currentStep;
public void autonomousInit()
{
currentStep = 1;
}
public void autonomousPeriodic()
{
while(DriverStation.getInstance().isAutonomous() && !DriverStation.getInstance().isDisabled())
{
switch(currentStep)
{
case 1:
//whatever code you want to run once has to be added in here
currentStep = 2;
break;
case 2:
leftTalon.set(0);
rightTalon.set(0);
//in this part of code just set everything to zero
break;
}
}
}