Continuous vs. Autonomous in Iterative Robot

So I’ve decided to use Iterative Robot over Simple Robot. I’m editing the BuiltinDefaultCode project. I notice they use the autonomous and teleoperated periodic functions but not the continuous. I was wondering what the relationship is between the periodic and continuous. If you put code in both, how do they run relative to one another? Also, what specifically is the difference? And I guess, all this leads to the question, what should I use (or based on what should I decide?)

Also, I’ve found the code I need for getting data from the sensors, but I’m not very familiar with C++ and object oriented programming so I’m not really sure of where to put what.

I’ve got this for the camera. Which parts go wherever I decide to refresh my sensors? For that matter, where is it a good idea for me to refresh my sensors? Also, is there other necessary camera configuration stuff I need to put in somewhere in my code?
double timestamp; // timestamp of image returned
Image
cameraImage = frcCreateImage(IMAQ_IMAGE_RGB);
if (!cameraImage) { printf(“error: %s”, GetErrorText(GetLastError()) };

if ( !GetImage(cameraImage, &timestamp) ) {
printf(“error: %s”, GetErrorText(GetLastError()) }; *

And then there’s this, which I assume will go right after I get my image:
imaqImageToArray(const Image image, Rect rect, int* columns, int* rows);*

And finally there’s this: basically, I’m not sure what parts of this (if any) set up the sensors, and which parts just get the data.

  • Ultrasonic ultra(ULTRASONIC_PING, ULTRASONIC_ECHO);
    ultra.SetAutomaticMode(true);
    double range = ultra.GetRangeInches();*

Any help would be appreciated…there isn’t much programming experience on my team. Thanks!

A “periodic” function is one that is run only at a certain interal–if you look in the c++ reference, you’ll see there’s actually a function to set how often it runs.

A “continuous” function is called as fast as the robot is able to–there’s no way to explicity specify when it should be called.

As for how they interact—the system considers them two functions of the same class. This means they can both use global variables in your file, call each other, etc.

So–if I have code in autonomous and periodic, what happens? Does continuous loop as fast as it can, but is interrupted by periodic every time the time interval specified has past?

And so, should I put my sensor refresh code in the periodic loop, depending on how fast it refreshes, and the rest of my code in continuous? Or could I set the periodic time interval to 0, and then just stick the sensor refreshes in the *if ((m_telePeriodicLoops % n) == 0)*statements that run enclosed code only on every nth iteration?

Finally, in all cases does the code wait for data to return (ie, for the ultrasonic ping to come back) before moving on? Because in that case, whether I ran it every nth loop or every loop, technically it would still hold up my robot’s reaction rate? (Say then that my robot just sets drive speed and turn depending on data, and the calculations are simple, it would act the same in the following situations: 1) if it were stuck waiting on sensor data to return and the motors were still running on info from the old command, and 2) if it were looping through the code and making new drive commands based on old data. Right? I may have very probably confused myself by now.)

The function that sets the rate for the Periodic loop has been depreciated in Update 3. Periodic functions are now synchronized to run when the robot receives new data from the Driver Station, similar to the old “slow loop” on the IFI platform.

The Continuous functions will run as fast as they can, and they’re not interrupted by the Periodic functions.

This is the sequence of events for IterativeRobot, in pseudocode:


call RobotInit()

while (1)
{
    if current mode has not been initialized:
          call Init() for current mode (eg TeleopInit)

    if there has been new data from DS:
          call Periodic() for current mode

    call Continuous() for current mode
}

Any code that depends on new information from the Driver Station really should be in a Periodic function.

Code that sets up joysticks, speed controllers, sensors, etc should be in your robot class constructor or in RobotInit(). The variables for these objects should be declared in the robot class, outside of any functions. Anything else that needs to continuously run should be in a continuous function.

Regarding the example with the Ultrasonic class, this part would be for initialization:

Ultrasonic ultra(ULTRASONIC_PING, ULTRASONIC_ECHO);
ultra.SetAutomaticMode(true); 

You’d need to declare the Ultrasonic object somewhere in your class as a member variable, and initialize it in RobotInit() or the constructor.


class MyRobot : public IterativeRobot
{
   Ultrasonic *m_ultra;
   // other declarations...

   void RobotInit()
   {
          m_ultra = new Ultrasonic(pingchannel, echochannel);
          m_ultra.SetAutomaticMode(true);
   }

   void AutonomousPeriodic()
   {
       // Do something with m_ultra->GetRangeInches();
   }
}

The Ultrasonic::GetRangeInches() function is non-blocking and will return 0 if no measurements have completed. Also, when you use Automatic Mode with the Ultrasonic class the pinging will be done automatically in the background. You won’t have to do anything except ask it for range information wherever you need it.

Thanks! I understand the setup a lot better now.