Saturday, March 1, 2014

Periodic Tasks

This post looks at periodic tasks. The environment this applies to is the US First Robotics FTC Robot C software running on a Lego NXT brick.

Periodic tasks run at a specific and consistent time interval. For example, a task may be set to run every second or every 50ms. Why are periodic tasks interesting? A periodic task makes filtering signals, counting time, and controlling devices very simple. For example, if I have a periodic task set at 1 second, I can add a simple counter to my task. For example:

int secondsCounter=0;

task Periodic_1_second(){
   secondsCounter += 1;
}

 This will increment the seconds count once each time the task is called. After 60 seconds, I have counted to a minute.

 Periodic tasks make it possible to have signal shaping functions such as a lowPass filter or a rateLimiter. I will talk about these primitive functions in a future blog. For now, here is the Robot C code for the simplest task I can create:


// Periodic Model used to read sensors and control the motors on a NXT brick
//
// As a software programmer, I want my tasks to run at a periodic rate. A periodic rate makes control, filtering,
//    and counting much easier.
//
#pragma DebuggerWindows ("debugStream")// Bring up the debug stream window

int count=0;
int timeLeft=0; // A global variable that sticks around each frame

// ------------------------Foreground Task -----------------------------//
// Run every second
#define FOREGROUND_MS 1000 //I change this to 50 when I control the robot. 1000 is good for testing.
task main(){
 while(true){
  ClearTimer(T1);
  hogCPU(); //Prevent other tasks from running when this one is.

  for(long i=0; i<30000; ++i){} //Add some code to see the time used in the foreground. This takes about 0.5 seconds

  writeDebugStreamLine("Foreground\n"); //Let me know when the foreground runs

   count=count+1; // Count the number of times the foreground runs.

   timeLeft=FOREGROUND_MS-time1[T1]; // Calculate the time used in the foreground
   releaseCPU(); // Let other tasks run now.
   wait1Msec(timeLeft);// The time other tasks have to run before foreground takes control.
   writeDebugStreamLine("Count=[%2i] Time Left = %i\n",count,timeLeft);

   }// While Loop
}// Foreground Task

The next set of code is similar to this one. It has a background task with a low execution priority and a foreground task with a high execution priority.
// Periodic Model used to read sensors and control the motors on a NXT brick
//
// As a software programmer, I want my tasks to run at a periodic rate. A periodic rate makes control, filtering,
//    and counting much easier.
//
#pragma DebuggerWindows ("debugStream")// Bring up the debug stream window

int count=0;
int timeLeft=0;

// ------------------------Foreground Task -----------------------------//
// Run every second
#define FOREGROUND_MS 1000 //I change this to 50 when I control the robot. 1000 is good for testing.
task Foreground(){
 while(true){
  ClearTimer(T1);
  hogCPU(); //Prevent other tasks from running when this one is.

  for(long i=0; i<30000; ++i){} //Add some code to see the time used in the foreground.

  writeDebugStreamLine("Foreground\n"); //Let me know when the foreground runs

   count=count+1; // Count the number of times the foreground runs.

   timeLeft=FOREGROUND_MS-time1[T1]; // Calculate the time used in the foreground
   releaseCPU(); // Let other tasks run now.
   wait1Msec(timeLeft);// The time other tasks have to run before foreground takes control.
 }// While Loop
}// Foreground Task

// -------------------------Main Task----------------------------------//
task main(){
 count=0; //How many

 // Put initilization code here. This code will only run one time

 // Start the forground task with the highest priority
 StartTask(Foreground, 255);

 // This code runs in time left after the foreground task runs
  while(1==1){
   wait1Msec(1000); // This slows the background task down to the same speed as the foreground. Try different numbers.
   writeDebugStreamLine("Count=[%2i] Time Left = %i\n",count,timeLeft);
  }// While Background
}//Main Background
Try changing the wait1Msec statement in the background to 500 or 250. Why does the same number get printed out many times? Try changing the FOREGROUND_MS number to 500 or 250 when the background stays at 10000. Why does the counter count up more than one time? In the next posting, I will show you a simple state machine that moves the robot around in a square. Please give me a shout out if you find this software helpful.

Sunday, February 23, 2014

Why Geek My Bot

Welcome to Geek My Bot or advanced Geeky Robotics solutions for the US First FTC Robotics competition. In this blog I will examine how a US First Robotics team solves some of the stickier mechanical, software, and team collaboration issues. As an engineer I am passionate about developing talented and enthusiastic new engineers to solve some of the worlds toughest issues. Along the journey, I hope to show you some tools and techniques you can add to your FTC robotics toolbox. In a spirit of gracious professionalism, please give a shout out if you read something you like and share back if you find new and better tools and techniques.