Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages | Examples

robotSyncTaskExample.cpp

Shows how to add a task callback to ArRobot's synchronization/processing cycle

This program will just have the robot wander around, it uses some avoidance routines, then just has a constant velocity. A sensor interpretation task callback is invoked by the ArRobot object every cycle as it runs, which records the robot's current pose and velocity.

Note that tasks must take a small amount of time to execute, to avoid delaying the robot cycle.

#include "Aria.h"

class PrintingTask
{
public:
  // Constructor. Adds our 'user task' to the given robot object.
  PrintingTask(ArRobot *robot);

  // Destructor. Does nothing.
  ~PrintingTask(void) {}
  
  // This method will be called by the callback functor
  void doTask(void);
protected:
  ArRobot *myRobot;

  // The functor to add to the robot for our 'user task'.
  ArFunctorC<PrintingTask> myTaskCB;
};


// the constructor (note how it uses chaining to initialize myTaskCB)
PrintingTask::PrintingTask(ArRobot *robot) :
  myTaskCB(this, &PrintingTask::doTask)
{
  myRobot = robot;
  // just add it to the robot
  myRobot->addSensorInterpTask("PrintingTask", 50, &myTaskCB);
}

void PrintingTask::doTask(void)
{
  // print out some info about the robot
  printf("\rx %6.1f  y %6.1f  th  %6.1f vel %7.1f mpacs %3d", myRobot->getX(),
     myRobot->getY(), myRobot->getTh(), myRobot->getVel(), 
     myRobot->getMotorPacCount());
  fflush(stdout);

  // Need sensor readings? Try myRobot->getRangeDevices() to get all 
  // range devices, then for each device in the list, call lockDevice(), 
  // getCurrentBuffer() to get a list of recent sensor reading positions, then
  // unlockDevice().
}

int main(int argc, char** argv)
{
  // the connection
  ArSimpleConnector con(&argc, argv);
  if(!con.parseArgs())
  {
    con.logOptions();
    return 1;
  }

  // robot
  ArRobot robot;

  // sonar array range device
  ArSonarDevice sonar;

  // This object encapsulates the task we want to do every cycle. 
  // Upon creation, it puts a callback functor in the ArRobot object
  // as a 'user task'.
  PrintingTask pt(&robot);

  // the actions we will use to wander
  ArActionStallRecover recover;
  ArActionAvoidFront avoidFront;
  ArActionConstantVelocity constantVelocity("Constant Velocity", 400);

  // initialize aria
  Aria::init();

  // add the sonar object to the robot
  robot.addRangeDevice(&sonar);

  // open the connection to the robot; if this fails exit
  if(!con.connectRobot(&robot))
  {
    printf("Could not connect to the robot.\n");
    return 2;
  }
  printf("Connected to the robot. (Press Ctrl-C to exit)\n");
  
  
  // turn on the motors, turn off amigobot sounds
  robot.comInt(ArCommands::ENABLE, 1);
  robot.comInt(ArCommands::SOUNDTOG, 0);

  // add the wander actions
  robot.addAction(&recover, 100);
  robot.addAction(&avoidFront, 50);
  robot.addAction(&constantVelocity, 25);
  
  // Start the robot process cycle running. Each cycle, it calls the robot's
  // tasks. When the PrintingTask was created above, it added a new
  // task to the robot. 'true' means that if the robot connection
  // is lost, then ArRobot's processing cycle ends and this call returns.
  robot.run(true);

  printf("Disconnected. Goodbye.\n");
  
  return 0;
}

Generated on Thu Jan 7 10:34:38 2010 for Aria by  doxygen 1.4.2