Paul's Tutorials - logo1-2Program Structure



Now that we have reviewed what makes up the robot, we can move on to how the program is structure.

If you still don't understand classes, you NEED to study up on that before you continue.

Part 1 ⚫ Part 2

Introduction

The robot's program is a little different from what you are used to. Instead of using an int main and a lot of functions, you program the robot as a class. And only a class. The int main portion of the program doesn't change, so it is already embedded into the roboRIO for you.

The underlying program on the roboRIO reads the class that you wrote, and applies it to the robot. So, essentially, you are treating the robot as if it were a class.

Getting Started

When you installed the WPI Eclipse extension, you installed a robot class template. In order to get it, go to File > New > Project. In the dialog, select Robot C++ Project, then Iterative Robot, then give your project a name. This will load an empty robot template into the workspace for you. The file you want is in the src directory, Robot.cpp.

Templates since the 2015 controls system upgrade don't have all of the functions that are listed here, but each of these functions are still accessible through the IterativeRobot class. If you wish to use a function that is not present in the template, simply write it in.

Let's examine what it has done for us:

#include "WPILib.h"

This includes the library which, in turn, includes all of the functions of the robot that you could ever want.

class Robot: public IterativeRobot

This creates a new class called Robot that you will program. It inherits the IterativeRobot class, the class the roboRIO treats the robot as. Your class MUST inherit IterativeRobot, otherwise it will not work.

Now, we will look at the structure of the robot class.

Class Members

class Robot: public IterativeRobot
{
  	/*Put the components of your robot here.
  	 *...
  	 */

Here is where you declare everything that your robot has: drive controllers, sensors, etc. You also declare variables that you will use for control here, as well.

There is a specific way in which we declare robot components -- that is, using pointers. But we'll get into that later.

Class Constructor

The default code actually does not include this part, but you should write it in. If you remember from the C++ Guided Tutorial, the constructor is the part of the class where it initializes itself.

Robot::Robot()
{
	//Initialize robot components here
}

The class constructor is used to initialize parts of the robot and to set variables for their initial run. This is called before the RobotInit() method in the program. An example usage of the constructor:

public:
	Robot::Robot()
	{
		m_Victor1 = new Victor(1);
		m_Counter = 0;
	}

Again, how to initialize specific robot components will be reviewed in Lesson 1-3.

You may notice the public: keyword before the class constructor. Everything declared before is private, to avoid memory overflow.

Initialization Routines

Not to be confused with the component initialization in the constructor

The following routines are called once before their corresponding periodic routines are called. Note that RobotInit does not have a periodic routine associated with it.

One important concept to note at this point is that the roboRIO operates in loops. It runs an init routine in one loop, then it switches to the corresponding periodic routine. The periodic routine runs once per loop until the mode is changed, and the process is repeated again for the new mode.

RobotInit()

void RobotInit()
{
  // Actions which would be performed once (and only once) upon initialization of the
  // robot would be put here.
}

The comment says it all -- everything that is not component and variable initialization that you want to do before the robot does anything else (e.g. sending data to the dashboard as part of a disabled routine).

DisabledInit()

void DisabledInit()
{
	// Actions that are to be called as the robot enters disabled mode would be put here
}

Disabled routines, or when Disabled is selected in the driver station, are routines in which you can change variables, but you cannot change the state of the robot (i.e. activate motors). The most common use for this mode is to change between autonomous modes. In the DisabledInit portion of the program, you would put statements that you want run as the robot enters disabled mode.

AutonomousInit()

void AutonomousInit()
{
	// Put actions that should be run as the autonomous period of the match starts here.
}

Autonomous is the part of the match where the robot functions without input from the drivers (with the exception of the Kinect and other video devices). If there are some actions that need to be run as you enter autonomous, put them here.

TeleopInit()

void TeleopInit()
{
	// Put actions that should be run once teleoperated operation starts here.
}

Teleop, short for teleoperated, is when the drivers control the robot through the controls. This initialization routine is important, as it is often used to stop any leftover autonomous commands, should they run past their allocated period. It can also be used to reset the robot to a certain state after autonomous ends.

TestInit()

void TestInit()
{
	// Put setup for diagnostics here
}

Test mode is an important mode: you can use it to test the functionality of your robot. Essentially, it is a diagnostic mode that you can use to determine exactly what is wrong with your robot.

In TestInit, you would set your robot up for diagnostics, if any are needed.

Periodic Routines

These are all routines that are run once the roboRIO has finished the initialization stage for that specific mode (e.g. teleop). These continue to run, once per loop until the robot is disabled (in matches, the robot is disabled for a short period of time after autonomous to switch to teleop). Because they loop automatically, you should never write a loop into these routines.

DisabledPeriodic()

void DisabledPeriodic()
{
	//Put methods to be run while your robot is disabled here
}

Here is where you would program your robot to change autonomous modes, tune in a shot height, etc. Again, you cannot interact with drive controllers or anything that actuates parts of the robot here.

AutonomousPeriodic()

void AutonomousPeriodic()
{
	//Put methods that make up your autonomous routine here.
}

AutonomousPeriodic() is what runs during the autonomous portion of the match. Here, you write the robot's autonomous routine.

Note that, depending on the complexity of your autonomous, this can be the part of your program that requires the most logic.

TeleopPeriodic()

void TeleopPeriodic()
{
	//Put methods that would be run during teleop here.
}

Here is where you put in all of your teleop functionality, which includes but is not limited to:

Because this is easily one of the largest parts of the program (although there are a few exceptions), it is better to organize this, such that all of your teleop functionality is split up amongst organized functions. For example, if you wanted to drive your robot and update the dashboard, your TeleopPeriodic() would look like this:

void TeleopPeriodic()
{
	TeleopDrive();
	TeleopDashboardUpdate();
}

void TeleopDrive()
{
	//Methods for driving the robot here
}

void TeleopDashboardUpdate()
{
	//Update the driver station here
}

Note: This will become even more apparent as the tutorial progresses, but PLEASE name your functions and variables with relevant names. Not doing so will cause a lot of ripped-out hair and shouting voices.

TestPeriodic()

void TestPeriodic()
{
	// Put diagnostic routines here.
}

Here, you would put all of your diagnostics. In the case of this tutorial, you would use game controller buttons to test individual motors and specific robot functions.

Diagnostics are important because they help you determine the exact problem with your robot, should one arise. You should always program a diagnostic mode.

Continuous Routines

These routines don't appear in your class template, but they are still overrideable functions in the IterativeRobot class.

Continuous routines are similar to periodic routines, in that they are called over and over again. However, they can run multiple times per loop, and they take higher priority over periodic routines. Because of this, using these too much can lead to a runaway process thread and memory issues. Use these with caution, if at all.

DisabledContinuous()

void DisabledContinuous()
{
	//...
}

This is the continuous routine that runs in disabled mode.

AutonomousContinuous()

void AutonomousContinuous()
{
	//...
}

This is the continuous routine that runs in autonomous.

TeleopContinuous()

void TeleopContinuous()
{
	//...
}

This is the continuous routine that runs in teleop.

TestContinuous()

void TestContinuous()
{
	//...
}

This is the continuous routine that runs in test mode.

End of the Program

At the end of the program, you may notice the following line:

START_ROBOT_CLASS(Robot);
		

This is a macro that basically tells the roboRIO that the class Robot is the class to load and use on the robot.

Activity

Alone or with a partner, talk to a mentor/veteran team member to get a detailed description of all of the functions of a robot from a previous year (this activity does not require that the robot is available, but it may be useful for your reference).

Below is the class template discussed in this lesson, and in each function is a multi-line comment with an editable text box. Using the description you obtained, fill in the comments so that all of the functions (and any basic logic, if possible) are in the right place.

Click the button below to see a sample function description (of the 2013 HOTBOT)

If you run out of space in the text boxes, you can resize them with the handle in the lower-right corner.

There is no auto-check for this activity. If you want to check your work, talk to a mentor or veteran team member.


#include "WPILib.h"
	
class Lesson2: public IterativeRobot
{
	/*
 	 */
	     
public:
	Lesson2 ()
	{
		/*
		 */
	}

	/** INITIALIZATION ROUTINES **/
		
	void RobotInit ()
	{
		/*
		 */     
	}
		
	void DisabledInit ()
	{
		/*
		 */
	}
		
	void AutonomousInit ()
	{
		/*
		 */
	}
		
	void TestInit ()
	{
		/*
		 */
	}
		
	/** PERIODIC ROUTINES **/
	
	void DisabledPeriodic ()
	{
		/*
	
		 */
	}
		
	void AutonomousPeriodic ()
	{
		/*
	
		 */
	}
		
	void TeleopPeriodic ()
	{
		/*
		 */
	}
		
	void TestPeriodic ()
	{
		/*
		 */
	}
		
	/** CONTINUOUS ROUTINES **/
		
	// **Use these with caution!**
		
	void DisabledContinuous ()
	{
		/*
		 */
	}
		
	void AutonomousContinuous ()
	{
		/*
	
		 */
	}
		
	void TeleopContinuous ()
	{
		/*
		 */
	}
		
	void TestContinuous ()
	{
		/*
		 */
	}
		
	/** MISCELLANEOUS ROUTINES **/
		
	/* Here is where you would put the extra functions that aren't
	 * a part of the class template. (Example: TeleopDrive(), or a
	 * function that does something across both Teleop and Auton,
	 * like printing data). Note that I haven't put the box in a comment -- 
	 * this means that you need to write the function syntax and put 
	 * the comment in there! (Indentation is not necessary FOR THIS ACTIVITY ONLY)
	 */
 
};
START_ROBOT_CLASS(Lesson2);

← 1-1 Parts of the Robot 1-2 Program Structure 1-3 Parts of the Robot: In Code →