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.

00001 #include "Aria.h"
00002 
00014 class PrintingTask
00015 {
00016 public:
00017   // Constructor. Adds our 'user task' to the given robot object.
00018   PrintingTask(ArRobot *robot);
00019 
00020   // Destructor. Does nothing.
00021   ~PrintingTask(void) {}
00022   
00023   // This method will be called by the callback functor
00024   void doTask(void);
00025 protected:
00026   ArRobot *myRobot;
00027 
00028   // The functor to add to the robot for our 'user task'.
00029   ArFunctorC<PrintingTask> myTaskCB;
00030 };
00031 
00032 
00033 // the constructor (note how it uses chaining to initialize myTaskCB)
00034 PrintingTask::PrintingTask(ArRobot *robot) :
00035   myTaskCB(this, &PrintingTask::doTask)
00036 {
00037   myRobot = robot;
00038   // just add it to the robot
00039   myRobot->addSensorInterpTask("PrintingTask", 50, &myTaskCB);
00040 }
00041 
00042 void PrintingTask::doTask(void)
00043 {
00044   // print out some info about the robot
00045   printf("\rx %6.1f  y %6.1f  th  %6.1f vel %7.1f mpacs %3d", myRobot->getX(),
00046      myRobot->getY(), myRobot->getTh(), myRobot->getVel(), 
00047      myRobot->getMotorPacCount());
00048   fflush(stdout);
00049 
00050   // Need sensor readings? Try myRobot->getRangeDevices() to get all 
00051   // range devices, then for each device in the list, call lockDevice(), 
00052   // getCurrentBuffer() to get a list of recent sensor reading positions, then
00053   // unlockDevice().
00054 }
00055 
00056 int main(int argc, char** argv)
00057 {
00058   // the connection
00059   ArSimpleConnector con(&argc, argv);
00060   if(!con.parseArgs())
00061   {
00062     con.logOptions();
00063     return 1;
00064   }
00065 
00066   // robot
00067   ArRobot robot;
00068 
00069   // sonar array range device
00070   ArSonarDevice sonar;
00071 
00072   // This object encapsulates the task we want to do every cycle. 
00073   // Upon creation, it puts a callback functor in the ArRobot object
00074   // as a 'user task'.
00075   PrintingTask pt(&robot);
00076 
00077   // the actions we will use to wander
00078   ArActionStallRecover recover;
00079   ArActionAvoidFront avoidFront;
00080   ArActionConstantVelocity constantVelocity("Constant Velocity", 400);
00081 
00082   // initialize aria
00083   Aria::init();
00084 
00085   // add the sonar object to the robot
00086   robot.addRangeDevice(&sonar);
00087 
00088   // open the connection to the robot; if this fails exit
00089   if(!con.connectRobot(&robot))
00090   {
00091     printf("Could not connect to the robot.\n");
00092     return 2;
00093   }
00094   printf("Connected to the robot. (Press Ctrl-C to exit)\n");
00095   
00096   
00097   // turn on the motors, turn off amigobot sounds
00098   robot.comInt(ArCommands::ENABLE, 1);
00099   robot.comInt(ArCommands::SOUNDTOG, 0);
00100 
00101   // add the wander actions
00102   robot.addAction(&recover, 100);
00103   robot.addAction(&avoidFront, 50);
00104   robot.addAction(&constantVelocity, 25);
00105   
00106   // Start the robot process cycle running. Each cycle, it calls the robot's
00107   // tasks. When the PrintingTask was created above, it added a new
00108   // task to the robot. 'true' means that if the robot connection
00109   // is lost, then ArRobot's processing cycle ends and this call returns.
00110   robot.run(true);
00111 
00112   printf("Disconnected. Goodbye.\n");
00113   
00114   return 0;
00115 }

Generated on Fri Jul 31 12:36:37 2009 for Aria by  doxygen 1.4.7