This program creates two action groups, a teleoperation group and a wander group. Each group contains actions that together effect the desired behavior: in teleoperation mode, input actions allow the robot to be driven by keyboard or joystick, and higher-priority limiter actions help avoid obstacles. In wander mode, a constant-velocity action drives the robot forward, but higher-priority avoidance actions make the robot turn away from obstacles, or back up if an obstacle is hit or the motors stall. Keyboard commands (the T and W keys) are used to switch between the two modes, by activating the action group for the chosen mode.
Actions overview
actionExample.cpp
00001 #include "Aria.h" 00002 00023 ArActionGroup *teleop; 00024 ArActionGroup *wander; 00025 00026 // Activate the teleop action group. activateExlcusive() causes 00027 // all other active action groups to be deactivated. 00028 void teleopMode(void) 00029 { 00030 teleop->activateExclusive(); 00031 printf("\n== Teleoperation Mode ==\n"); 00032 printf(" Use the arrow keys to drive, and the spacebar to stop.\n For joystick control hold the trigger button.\n Press 'w' to switch to wander mode.\n Press escape to exit.\n"); 00033 } 00034 00035 // Activate the wander action group. activateExlcusive() causes 00036 // all other active action groups to be deactivated. 00037 void wanderMode(void) 00038 { 00039 wander->activateExclusive(); 00040 printf("\n== Wander Mode ==\n"); 00041 printf(" The robot will now just wander around avoiding things.\n Press 't' to switch to teleop mode.\n Press escape to exit.\n"); 00042 } 00043 00044 00045 int main(int argc, char** argv) 00046 { 00047 Aria::init(); 00048 ArArgumentParser argParser(&argc, argv); 00049 ArSimpleConnector con(&argParser); 00050 ArRobot robot; 00051 ArSonarDevice sonar; 00052 00053 argParser.loadDefaultArguments(); 00054 if(!Aria::parseArgs() || !argParser.checkHelpAndWarnUnparsed()) 00055 { 00056 Aria::logOptions(); 00057 return 1; 00058 } 00059 00060 /* - the action group for teleoperation actions: */ 00061 teleop = new ArActionGroup(&robot); 00062 00063 // don't hit any tables (if the robot has IR table sensors) 00064 teleop->addAction(new ArActionLimiterTableSensor, 100); 00065 00066 // limiter for close obstacles 00067 teleop->addAction(new ArActionLimiterForwards("speed limiter near", 00068 300, 600, 250), 95); 00069 00070 // limiter for far away obstacles 00071 teleop->addAction(new ArActionLimiterForwards("speed limiter far", 00072 300, 1100, 400), 90); 00073 00074 // limiter so we don't bump things backwards 00075 teleop->addAction(new ArActionLimiterBackwards, 85); 00076 00077 // the joydrive action (drive from joystick) 00078 ArActionJoydrive joydriveAct("joydrive", 400, 15); 00079 teleop->addAction(&joydriveAct, 50); 00080 00081 // the keydrive action (drive from keyboard) 00082 teleop->addAction(new ArActionKeydrive, 45); 00083 00084 00085 00086 /* - the action group for wander actions: */ 00087 wander = new ArActionGroup(&robot); 00088 00089 // if we're stalled we want to back up and recover 00090 wander->addAction(new ArActionStallRecover, 100); 00091 00092 // react to bumpers 00093 wander->addAction(new ArActionBumpers, 75); 00094 00095 // turn to avoid things closer to us 00096 wander->addAction(new ArActionAvoidFront("Avoid Front Near", 225, 0), 50); 00097 00098 // turn avoid things further away 00099 wander->addAction(new ArActionAvoidFront, 45); 00100 00101 // keep moving 00102 wander->addAction(new ArActionConstantVelocity("Constant Velocity", 400), 25); 00103 00104 00105 00106 /* - use key commands to switch modes, and use keyboard 00107 * and joystick as inputs for teleoperation actions. */ 00108 00109 // create key handler if Aria does not already have one 00110 ArKeyHandler *keyHandler = Aria::getKeyHandler(); 00111 if (keyHandler == NULL) 00112 { 00113 keyHandler = new ArKeyHandler; 00114 Aria::setKeyHandler(keyHandler); 00115 robot.attachKeyHandler(keyHandler); 00116 } 00117 00118 // set the callbacks 00119 ArGlobalFunctor teleopCB(&teleopMode); 00120 ArGlobalFunctor wanderCB(&wanderMode); 00121 keyHandler->addKeyHandler('w', &wanderCB); 00122 keyHandler->addKeyHandler('W', &wanderCB); 00123 keyHandler->addKeyHandler('t', &teleopCB); 00124 keyHandler->addKeyHandler('T', &teleopCB); 00125 00126 // if we don't have a joystick, let 'em know 00127 if (!joydriveAct.joystickInited()) 00128 printf("Note: Do not have a joystick, only the arrow keys on the keyboard will work.\n"); 00129 00130 // set the joystick so it won't do anything if the button isn't pressed 00131 joydriveAct.setStopIfNoButtonPressed(false); 00132 00133 00134 /* - connect to the robot, then enter teleoperation mode. */ 00135 00136 robot.addRangeDevice(&sonar); 00137 if(!con.connectRobot(&robot)) 00138 { 00139 ArLog::log(ArLog::Terse, "actionGroupExample: Could not connect to the robot."); 00140 Aria::shutdown(); 00141 return 1; 00142 } 00143 00144 robot.enableMotors(); 00145 teleopMode(); 00146 robot.run(true); 00147 00148 Aria::shutdown(); 00149 return 0; 00150 }
1.4.7