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 }
1.4.7