I've reproduced the running-Autonomous-forever problem (and thanks to Gunderson/2643 for the loan of their control system).
The problem is that Autonomous() never exits, it sits in the while(1) loop forever. Autonomous() gets called only once - ref: WPI's
C/C++ Programming Guide for the First Robotics Competition http://first.wpi.edu/FRC/frcupdates.html => C/C++ Programming Guide.
Even removing the while(1) the Auton routine runs 28 seconds: 4*(2+4) and 4 more at the end. I'm sure you know this; the problem is that it's completely blind to Auton mode ending until that 28 seconds is over. In a match, if Teleop mode were to start within that 28 seconds, the 'bot would continue its Auton behaviour until the 28 seconds had lapsed.
I've taken the liberty of fixing this and adding some comments that I hope will explain how, feel free to post questions. It's tested and works. And, congratulations on taking the plunge into C++ programming!
Gary
Code:
#include "WPILib.h"
// if we put the important constants here, they're
// easy to find!
#define WAIT_INTERVAL 0.1 // 0.1 sec = 10 milliseconds
#define DRIVE1_INTERVAL_TENTHS 40 // 40 * 0.1 = 4 seconds
#define DRIVE2_INTERVAL_TENTHS 20 // 2 seconds
#define AUTON_LOOPS 4 // our autonomous loop runs this many times
RobotDrive myRobot(1,2); // motors are driven by PWMs 1 and 2
Joystick leftStick(1); // left joystick is in USB 1 of the Drivers Station
Joystick rightStick(2); // and right JS is in USB 2 of the DS
class RobotDemo : public SimpleRobot
{
public:
RobotDemo(void) // this function is called only once,
// when the 'bot powers on or is reset.
{
GetWatchdog().SetEnabled(false); // disable the WDT
}
void Autonomous(void) // this function is called only once,
// when auton mode is enabled. It's NOT
// called repeatedly.
{ int j; // oldSchool programmers declare variables here :-)
GetWatchdog().SetEnabled(false);
// drive our 'bot four times (AUTON_LOOPS) of two legs each:
for(int i = 0; i < AUTON_LOOPS; i++)
{
myRobot.TankDrive(0.5,-0.5); // start driving, half power (straight? turning?)
/* when we call Wait() the program is "blind" to any changes - eg, if Auton mode ends,
* we can't check this 'till the wait is over. If we were to code Wait(100), for example,
* the program would obligingly hang for 100 seconds. It couldn't interpret the joysticks,
* test if Auton mode had ended, etc. The motors would just keep doing what they were
* doing for those 100 seconds. The only thing that would override this is the disable switch
* or the equivalent of the Field Control System during a match. The FCS is going to kill
* the motors after Auton ends and before Teleop begins, but if Teleop began during that
* 100 second interval, the 'bot would merrily resume doing what it had been doing and ignore
* the joysticks.
*
* Until our code exits Autonomous(), OperatorControl() can't begin.
*
* we're going to handle this problem by decreasing the wait to 100 msec. after
* each 100 msec we're going to check to see if Auton mode is over, or we've looped
* long enough time to allow the motors to drive the time interval we want.
*
* why 100 msec? why not? the worst we're going to loose is the first 0.1 second
* of Teleop mode, and no matter how much sugar, caffeine, and adrenaline the drivers
* are on, it's going to take them that long just to get to the controls.
*
* this isn't a particularly sophisticated way to do this, **but it works**. programmers
* with more experience may want to look into state machines to do this in a more
* structured and flexible manner.
*/
// loop as long as j < DRIVE_INTERVAL_TENTHS *AND* we're in auton mode:
for (j=0; (j < DRIVE1_INTERVAL_TENTHS) && IsAutonomous(); j++)
{
Wait(WAIT_INTERVAL);
}
myRobot.TankDrive(0.5,0.5); // start driving (turning? straight?)
// as above, keep driving 'till our interval is over, or auton ends:
for (j=0; (j < DRIVE2_INTERVAL_TENTHS) && IsAutonomous(); j++)
{
Wait(WAIT_INTERVAL);
}
} // outer for loop
myRobot.TankDrive(0.0,0.0); // done, stop the 'bot
} // Autonomous()
void OperatorControl(void) // this function is called only once,
// when teleop mode begins. It's NOT
// called repeatedly.
{
GetWatchdog().SetEnabled(false);
while (IsOperatorControl()) // keep looping as long as in teleop mode.
{
myRobot.TankDrive(leftStick, rightStick);
Wait(0.005);
} // while operator control is true
} // OperatorControl()
};
START_ROBOT_CLASS(RobotDemo);