View Single Post
  #17   Spotlight this post!  
Unread 08-09-2009, 18:06
garyk garyk is offline
Programming Mentor: 668, 972, 2643
FRC #0668 (Apes of Wrath)
Team Role: Mentor
 
Join Date: Dec 2006
Rookie Year: 2005
Location: Santa Clara (Silicon Valley) Calif.
Posts: 93
garyk is a jewel in the roughgaryk is a jewel in the roughgaryk is a jewel in the roughgaryk is a jewel in the rough
Re: very basic code help

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);
__________________

Silicon Valley Regional 2005, 2006 972
Silicon Valley Regional 2007 668 Xerox Creativity Award
Championship Event 2007 668
Portland Regional 2008 668
Silicon Valley Regional 2008 668, 972
Beta Test Team 2008 668 (with 100 & 254)
Silicon Valley Regional 2009 668 Regional Chairman's Award; 2643
Sacramento Regional 2009 668 Winning Alliance (thanks, 1717 & 2473!), 2010 Winning Alliance 3256
CalGames 2006, 2007, 2008, 2009, 2010, 2011 Field Tech
NorCal FTC Regional 2008, 2009 Inspector
Championship Event 2009
San Diego, Silicon Valley Regionals; Champ. Event 2010 668, 2643, 3256
Silicon Valley, Madera Regional 2012 2643
WRRF Programming Instructor 2006-2016
Regional Woodie Flowers Award 2014 2643 Utah Regional

Reply With Quote