Go to Post Baker, you're making my head hurt and it's only August!!!! - Rich Kressly [more]
Home
Go Back   Chief Delphi > Technical > Programming > C/C++
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 22-06-2013, 22:42
ekapalka's Avatar
ekapalka ekapalka is offline
Registered User
FRC #3216
 
Join Date: Dec 2012
Location: Bermuda
Posts: 277
ekapalka has a spectacular aura aboutekapalka has a spectacular aura about
Switching to Iterative

Hey! I've been working on some code that seems a bit too elaborate for the SimpleRobot template, so I wanted to try out Iterative. I looked for a template, and didn't find one, so then I searched the forum here, and found that the "BuiltinDefaultCode" is essentially the template, with a lot of code I'd probably never use mixed in. I realized that I actually know very little about FRC programming (or at least feel like it). Could someone please help explain a the different methods in the BuiltinDefaultCode (and some of the other things they threw into the code for kicks)? I've removed most of the "actual code" that I'm pretty sure isn't necessary (but I still have questions about), and this is what I was left with (in case it helps).
Code:
#include "WPILib.h"
class BuiltinDefaultCode : public IterativeRobot{
	UINT32 m_autoPeriodicLoops;
	UINT32 m_disabledPeriodicLoops;
	UINT32 m_telePeriodicLoops;
		
public:
	BuiltinDefaultCode(void){
		m_autoPeriodicLoops = 0;
		m_disabledPeriodicLoops = 0;
		m_telePeriodicLoops = 0;
	}	
	
	////Init Routines///
	
	void RobotInit(void) {
		/* Actions which would be performed once (and only once) 
		 *upon initialization of the robot would be put here  */
	}
	
	void DisabledInit(void) {
		m_disabledPeriodicLoops = 0;			// Reset the loop counter for disabled mode
		/**/
	}

	void AutonomousInit(void) {
		m_autoPeriodicLoops = 0;				// Reset the loop counter for autonomous mode
		/**/
	}

	void TeleopInit(void) {
		m_telePeriodicLoops = 0;
		/**/
	}

	////Periodic Routines////
	
	void DisabledPeriodic(void)  {
		/**/
	}

	void AutonomousPeriodic(void) {
		/**/
	}
	
	void TeleopPeriodic(void) {
		/**/
	} 

	////Continuous Routines////

	void DisabledContinuous(void) {
		/**/
	}

	void AutonomousContinuous(void)	{
		/**/
	}

	void TeleopContinuous(void) {
		/**/
	}		
};

START_ROBOT_CLASS(BuiltinDefaultCode);
Thanks!
Reply With Quote
  #2   Spotlight this post!  
Unread 01-07-2013, 15:01
Billy_B Billy_B is offline
Registered User
FRC #2704 (Order 2 Chaos)
Team Role: Programmer
 
Join Date: Jul 2013
Rookie Year: 2010
Location: United States
Posts: 6
Billy_B is an unknown quantity at this point
Re: Switching to Iterative

I can't help too much with that code, but if you want a simpler Iterative Robot to play with team 2704 made a custom iterative robot this year, you can get a PDF copy of our code at http://www.firstplusplus.com/samplerobot-code.html

Our iterative robot is in our O2C class, if you just want the code it should be:
The .h
Code:
#ifndef O2C_H	// If not Defined
#define O2C_H	// Define
				// Assures that it does not define multiple times.

// This is our field class. It recieves inputs from the field and determines whether the robot should be in
// Autonomous, Teleoperated or test. It also ascertains whether or not an Initialization is needed for the
// Controller that it posesses.
#include "RobotBase.h"
#include "Timer.h"
#include "Watchdog.h"

#include "O2CDEF.h"

#include "O2CCONTROLLER.h"

class O2C : public RobotBase	// O2C is derived from RobotBase
{
public:
	O2C();	// Constructor
	virtual void StartCompetition();	// Is ran once at the start of the competition

private:
	// For the purposes of telling when initialization is needed.
	int autoiterations;
	int teleiterations;
	int testiterations;
	int disablediterations;
	int enablediterations;
	int firsttime;
	double currenttime;
	
	Timer O2CTimer;
	O2CCONTROLLER O2CController;	// O2C HAS a O2CController
	// For the purposes of telling when initialization is needed.
};

#endif //End O2C_H
and the .cpp:
Code:
#include "O2C.h"


O2C :: O2C()	// Constructor
{
	autoiterations = 0;
	teleiterations = 0;
	testiterations = 0;
	disablediterations = 0;
	enablediterations = 0;
	firsttime = 0;
	GetWatchdog().Feed();	// Need to feed Watchdog at start.
}

void O2C :: StartCompetition()
{
	O2CTimer.Start();
	while (1)
	{
		currenttime = O2CTimer.Get();
		O2CDatabuffer.Time = currenttime;
		GetWatchdog().Feed();	// Feed watchdog at the start of every iteration
		if (firsttime == 0)
		{
			// Put Robot Initialization here
			O2CController.Init();	// O2CController initialization.
			firsttime = 1;
			O2CTimer.Reset();
			currenttime = O2CTimer.Get();
			O2CDatabuffer.Time = currenttime;
		}
		if (IsEnabled())	// If any mode is enabled.
		{
			if (enablediterations == 0)
			{
				O2CTimer.Reset();
				currenttime = O2CTimer.Get();
				O2CDatabuffer.Time = currenttime;
				enablediterations = 1;
				// Enabled Initialization here
			}
			else
			{
				if (IsAutonomous())	// Autonomous Mode is enabled
				{
					if (autoiterations == 0)
					{
						// Auto Initialization goes here
						O2CController.AutoInit();
						O2CTimer.Reset();
						currenttime = O2CTimer.Get();
						O2CDatabuffer.Time = currenttime;
					}
					else
					{
						// Auto goes here
						O2CController.Autonomous();
					}
					autoiterations = autoiterations + 1; // Don't Touch
				}
				else if (IsOperatorControl()) // Teleoperated Mode is enabled
				{
					if (teleiterations == 0)
					{
						// Teleoperated Initializations
						
					}
					else
					{
						// Teleoperated goes here
						O2CController.Teleoperated();
					}
					teleiterations = teleiterations + 1; // Don't Touch
				}
				else if (IsTest())	// Test mode, for testing specific pieces of code.
				{
					if (testiterations == 0)
					{
						// Test Initialization goes here
						
					}
					else
					{
						// Test goes here
						
					}
					testiterations = testiterations + 1; // Don't Touch
				}
				else
				{
					// THIS SHOULD REALLY NEVER HAPPEN!
					// Only would happen if it was enabled and not in any mode.
					
				}
				// Enabled Stuff goes in here
				enablediterations = enablediterations + 1; // Don't Touch
															// Would also  work as enablediterations++;
			}
		}
		else if (IsDisabled())
		{
			if (disablediterations == 0)
			{
				// Disabled Init goes here.
			}
			else
			{
				//Disabled goes here.
			}
			disablediterations = disablediterations + 1;
		}
		else
		{
			// If you get here there is a problem.
			// It isn't ours though.
		}
		Wait(WAITTIME);
	} 
}

START_ROBOT_CLASS(O2C) // MACRO needed to show where the entry point is.
The stuff inside of the ifs is where the code would go for your robot.

Edit: If you want to learn how to do Object Oriented Coding for FRC and if you have an NXT our website FirstPlusPlus.com has a full tutorial that can teach you how we do Iterative, Event Driven Coding

Last edited by Billy_B : 01-07-2013 at 15:05. Reason: Adding more resources
Reply With Quote
  #3   Spotlight this post!  
Unread 01-07-2013, 15:18
Jon Stratis's Avatar
Jon Stratis Jon Stratis is online now
Electrical/Programming Mentor
FRC #2177 (The Robettes)
Team Role: Mentor
 
Join Date: Feb 2007
Rookie Year: 2006
Location: Minnesota
Posts: 3,784
Jon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond repute
Re: Switching to Iterative

Check out http://users.wpi.edu/~bamiller/WPIRo...ive_robot.html

Quote:
Init() functions -- each of the following functions is called once when the appropriate mode is entered:

DisabledInit() -- called only when first disabled
AutonomousInit() -- called each and every time autonomous is entered from another mode
TeleopInit() -- called each and every time teleop is entered from another mode
Periodic() functions -- each of these functions is called iteratively at the appropriate periodic rate (aka the "slow loop"). The default period of the iterative robot is 10,000 microseconds, giving a periodic frequency of 100Hz (100 times per second).

DisabledPeriodic()
AutonomousPeriodic()
TeleopPeriodic()
Continuous() functions -- each of these functions is called repeatedly as fast as possible:

DisabledContinuous()
AutonomousContinuous()
TeleopContinuous()
The basic idea is you have the ability to initialize something (call it once) when starting each mode. Then you have the ability to do stuff in a repeated fashion, without putting in your own loops - using while or for loops in this type of robot structure is something best to be avoided!

They provide two different types of loops. The basic idea here being that there's stuff that you need to update periodically, like the values you send to your drive motors, but that doesn't have to be done as quickly as possible (waiting 1/100 of a second is OK). But there are other things that you need to do as frequently as possible, like try to detect state changes on a limit switch. You can rely on these functions being called for you repeatedly for as long as the robot is in that state (teleop, auto, disabled).
__________________
2007 - Present: Mentor, 2177 The Robettes
LRI: North Star 2012-2016; Lake Superior 2013-2014; MN State Tournament 2013-2014, 2016; Galileo 2016; Iowa 2017
2015: North Star Regional Volunteer of the Year
2016: Lake Superior WFFA
Reply With Quote
  #4   Spotlight this post!  
Unread 01-07-2013, 16:05
Joe Ross's Avatar Unsung FIRST Hero
Joe Ross Joe Ross is offline
Registered User
FRC #0330 (Beachbots)
Team Role: Engineer
 
Join Date: Jun 2001
Rookie Year: 1997
Location: Los Angeles, CA
Posts: 8,572
Joe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond repute
Re: Switching to Iterative

Quote:
Originally Posted by Jon Stratis View Post
This resource is out of date. It was last updated for the beta code in 2008. The up to date version is installed with the C++ update and can be found at C:\windriver\docs\extensions\FRC\WPILib C++ Reference.chm

In particular, the continuous methods no long exist, periodic rate has changed, and there are now test methods.

Quote:
RobotInit() -- provide for initialization at robot power-on

Init() functions -- each of the following functions is called once when the appropriate mode is entered:

DisabledInit() -- called only when first disabled
AutonomousInit() -- called each and every time autonomous is entered from another mode
TeleopInit() -- called each and every time teleop is entered from another mode
TestInit() -- called each and every time test is entered from another mode

Periodic() functions -- each of these functions is called iteratively at the appropriate periodic rate (aka the "slow loop"). The default period of the iterative robot is synced to the driver station control packets, giving a periodic frequency of about 50Hz (50 times per second).

DisabledPeriodic()
AutonomousPeriodic()
TeleopPeriodic()
TestPeriodic()
Reply With Quote
  #5   Spotlight this post!  
Unread 01-07-2013, 16:12
Joe Ross's Avatar Unsung FIRST Hero
Joe Ross Joe Ross is offline
Registered User
FRC #0330 (Beachbots)
Team Role: Engineer
 
Join Date: Jun 2001
Rookie Year: 1997
Location: Los Angeles, CA
Posts: 8,572
Joe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond repute
Re: Switching to Iterative

Here is what the java iterative template looks like. C++ should be similar.
Attached Files
File Type: java RobotTemplate.java (1.5 KB, 12 views)
Reply With Quote
  #6   Spotlight this post!  
Unread 01-07-2013, 16:42
Jon Stratis's Avatar
Jon Stratis Jon Stratis is online now
Electrical/Programming Mentor
FRC #2177 (The Robettes)
Team Role: Mentor
 
Join Date: Feb 2007
Rookie Year: 2006
Location: Minnesota
Posts: 3,784
Jon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond reputeJon Stratis has a reputation beyond repute
Re: Switching to Iterative

Quote:
Originally Posted by Joe Ross View Post
This resource is out of date. It was last updated for the beta code in 2008. The up to date version is installed with the C++ update and can be found at C:\windriver\docs\extensions\FRC\WPILib C++ Reference.chm
That's what I get for following google's first search results (which are usually accurate enough when I need to look wpilib stuff up and don't have access to one of the team's development laptops)

Also, if you look at what was originally posted, it contains the continuous functions, so it's possible the OP is not using the latest revision of the base code.
__________________
2007 - Present: Mentor, 2177 The Robettes
LRI: North Star 2012-2016; Lake Superior 2013-2014; MN State Tournament 2013-2014, 2016; Galileo 2016; Iowa 2017
2015: North Star Regional Volunteer of the Year
2016: Lake Superior WFFA
Reply With Quote
  #7   Spotlight this post!  
Unread 01-07-2013, 19:41
ekapalka's Avatar
ekapalka ekapalka is offline
Registered User
FRC #3216
 
Join Date: Dec 2012
Location: Bermuda
Posts: 277
ekapalka has a spectacular aura aboutekapalka has a spectacular aura about
Re: Switching to Iterative

I'm using the base code we had at the end of the season this year. One of the volunteers gave us the "latest" update on a flash drive at the competition (thanks, whoever that was!). The original code had these comments, though:
Code:
/**
 * This "BuiltinDefaultCode" provides the "default code" functionality as used in the "Benchtop Test."
 * 
 * The BuiltinDefaultCode extends the IterativeRobot base class to provide the "default code"
 * functionality to confirm the operation and usage of the core control system components, as 
 * used in the "Benchtop Test" described in Chapter 2 of the 2009 FRC Control System Manual.
[...]**/
So is there some replacement for the continuous functions?
Attached Files
File Type: cpp BuiltinDefaultCode.cpp (15.9 KB, 8 views)
Reply With Quote
  #8   Spotlight this post!  
Unread 01-07-2013, 20:45
Joe Ross's Avatar Unsung FIRST Hero
Joe Ross Joe Ross is offline
Registered User
FRC #0330 (Beachbots)
Team Role: Engineer
 
Join Date: Jun 2001
Rookie Year: 1997
Location: Los Angeles, CA
Posts: 8,572
Joe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond repute
Re: Switching to Iterative

Quote:
Originally Posted by ekapalka View Post
So is there some replacement for the continuous functions?
The continuous methods were easy to mis-use, so they were removed. From http://wpilib.screenstepslive.com/s/...software-notes
Quote:
Iterative robot templates no longer have the continuous methods. That is AutonomousContinuous, TeleopContinuous and DisabledContinuous methods are no longer included in the library. If you are looking for similar functionality threads is a possible alternative.
I filed a bug since I think the BuiltinDefaultCode sample should not have any reference to the continuous methods, even if they were commented out previously.
Reply With Quote
  #9   Spotlight this post!  
Unread 02-07-2013, 00:42
ekapalka's Avatar
ekapalka ekapalka is offline
Registered User
FRC #3216
 
Join Date: Dec 2012
Location: Bermuda
Posts: 277
ekapalka has a spectacular aura aboutekapalka has a spectacular aura about
Re: Switching to Iterative

Thanks all! So what should have gone into continuous? Is it like the all-encompassing "while isEnabled()" of SimpleRobot? How do teams that use iterative know how often something needs to be called, and on that matter, how do you set how often something gets called (in Periodic)?
Reply With Quote
  #10   Spotlight this post!  
Unread 02-07-2013, 11:43
Billy_B Billy_B is offline
Registered User
FRC #2704 (Order 2 Chaos)
Team Role: Programmer
 
Join Date: Jul 2013
Rookie Year: 2010
Location: United States
Posts: 6
Billy_B is an unknown quantity at this point
Re: Switching to Iterative

How 2704 does our code (and it's different than most teams) is we program entirely with Event Driven State Machines, so our code is written as a lot of reactions to what is happening instead of like a script. Then if we want to run it we pretty much just tell the code to go.

Edit:
So in periodic the code only gets called as often as you call it, in our code it is called every iteration and figures out what needs to do from that. In 2704's paradigm we assume that our code is called every single iteration, even if it does nothing that iteration.

Edit #2:
In Periodic it runs through the entire code every iteration, every 50ms all of teleop will run, or all of autonomous will run; wheras in SimpleRobot you write it more like a script, loop here loop there, in Iterative you write it in a lot of State Machines

Last edited by Billy_B : 02-07-2013 at 11:46. Reason: Didn't answer his question
Reply With Quote
  #11   Spotlight this post!  
Unread 24-07-2013, 00:19
ekapalka's Avatar
ekapalka ekapalka is offline
Registered User
FRC #3216
 
Join Date: Dec 2012
Location: Bermuda
Posts: 277
ekapalka has a spectacular aura aboutekapalka has a spectacular aura about
Re: Switching to Iterative

That seems like a pretty solid way to do things. Since I started I did some work programming LED patterns with state machines, but am still a bit confused with how to set the rate at which commands happen, and the rate at which each command needs to be executed. Is there some documentation somewhere about this? Like how often you need to query sensors or read joystick values or send motors commands? I still don't understand Periodic(). I thought you put stuff inside it like this:
Code:
UINT16 numloop_within_second = numloops % (UINT32)GetLoopsPerSec();
if (numloop_within_second == GetLoopsPerSec/2){ //do something }
Is there some other way to set timed events?
Reply With Quote
  #12   Spotlight this post!  
Unread 28-07-2013, 00:18
Billy_B Billy_B is offline
Registered User
FRC #2704 (Order 2 Chaos)
Team Role: Programmer
 
Join Date: Jul 2013
Rookie Year: 2010
Location: United States
Posts: 6
Billy_B is an unknown quantity at this point
Re: Switching to Iterative

How we would do that type of thing would be like this:
Code:
// in .h:
int led_state;
int pled_state;

double starttime;

// in .cpp
void LED_FLASHER::Init()
{
     starttime = clock.Now();
}

void LED_FLASHER::Run()
{
     switch(led_state)
     {
     case RED:
          // Output Red
          if((clock.Now - starttime)>TIME_TO_SWITCH)
          {
               starttime = clock.Now;
               led_state = NEXT_COLOR;
          }
     break;
     // ect.
     }
     pled_state = led_state;
}
Instead of using the "commands" (which is more of a Java type thing) we actually program our classes ourselves, it requires quite a bit more setup, but that means that we can have more control.

The idea is that you have full control over what runs every iteration, and the entire code runs each iteration. So maybe you only call LED_FLASHER.Run() every time (clock.Now()%5) == 0 (every five miliseconds), but you have full control over what is going on.

Last edited by Billy_B : 28-07-2013 at 00:24. Reason: Clarification
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 14:17.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi