This program uses ArActionKeydrive and ArActionJoydrive to allow teleoperation with the keyboard or joystick, and displays gyro data. Additional keys (numbers 0-9 and letters q, w, e, r, t, y, u, i, o, p) activate preset rotation velocities.
00001 /* 00002 MobileRobots Advanced Robotics Interface for Applications (ARIA) 00003 Copyright (C) 2004,2005 ActivMedia Robotics LLC 00004 Copyright (C) 2006 MobileRobots, Inc. 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 00020 If you wish to redistribute ARIA under different terms, contact 00021 MobileRobots for information about a commercial version of ARIA at 00022 robots@mobilerobots.com or 00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481 00024 */ 00025 00034 #include "Aria.h" 00035 #include "ArAnalogGyro.h" 00036 00037 00038 class GyroTask 00039 { 00040 public: 00041 // the constructor, it must use constructor chaining to intialize its base 00042 // class ArSimpleUserTask 00043 GyroTask(ArRobot *robot); 00044 // empty destructor 00045 ~GyroTask(void) {} 00046 00047 // the task we want to do 00048 void doTask(void); 00049 protected: 00050 //double myHeading; 00051 ArAnalogGyro *myGyro; 00052 ArRobot *myRobot; 00053 ArFunctorC<GyroTask> myTaskCB; 00054 }; 00055 00056 00057 // the constructor, note how it uses chaining to initialize the myTaskCB 00058 GyroTask::GyroTask(ArRobot *robot) : 00059 myTaskCB(this, &GyroTask::doTask) 00060 { 00061 ArKeyHandler *keyHandler; 00062 myRobot = robot; 00063 // just add it to the robot 00064 myRobot->addUserTask("GyroTask", 50, &myTaskCB); 00065 myGyro = new ArAnalogGyro(myRobot); 00066 if ((keyHandler = Aria::getKeyHandler()) == NULL) 00067 { 00068 keyHandler = new ArKeyHandler; 00069 Aria::setKeyHandler(keyHandler); 00070 if (myRobot != NULL) 00071 myRobot->attachKeyHandler(keyHandler); 00072 else 00073 ArLog::log(ArLog::Terse, "GyroTask: No robot to attach a keyHandler to, keyHandling won't work... either make your own keyHandler and drive it yourself, make a keyhandler and attach it to a robot, or give this a robot to attach to."); 00074 } 00075 keyHandler->addKeyHandler('1', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, 10)); 00076 keyHandler->addKeyHandler('2', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, 20)); 00077 keyHandler->addKeyHandler('3', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, 30)); 00078 keyHandler->addKeyHandler('4', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, 40)); 00079 keyHandler->addKeyHandler('5', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, 50)); 00080 keyHandler->addKeyHandler('6', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, 60)); 00081 keyHandler->addKeyHandler('7', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, 70)); 00082 keyHandler->addKeyHandler('8', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, 80)); 00083 keyHandler->addKeyHandler('9', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, 90)); 00084 keyHandler->addKeyHandler('0', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, 100)); 00085 00086 keyHandler->addKeyHandler(ArKeyHandler::SPACE, new ArFunctorC<ArRobot>(myRobot,&ArRobot::stop)); 00087 00088 keyHandler->addKeyHandler('q', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, -10)); 00089 keyHandler->addKeyHandler('w', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, -20)); 00090 keyHandler->addKeyHandler('e', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, -30)); 00091 keyHandler->addKeyHandler('r', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, -40)); 00092 keyHandler->addKeyHandler('t', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, -50)); 00093 keyHandler->addKeyHandler('y', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, -60)); 00094 keyHandler->addKeyHandler('u', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, -70)); 00095 keyHandler->addKeyHandler('i', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, -80)); 00096 keyHandler->addKeyHandler('o', new ArFunctor1C<ArRobot, double>(myRobot,&ArRobot::setRotVel, -90)); 00097 keyHandler->addKeyHandler('p', new ArFunctor1C<ArRobot, double>(myRobot, &ArRobot::setRotVel, -100)); 00098 00099 keyHandler->addKeyHandler('a', new ArFunctor1C<ArRobot, double>(myRobot, &ArRobot::setHeading, 0)); 00100 keyHandler->addKeyHandler('s', new ArFunctor1C<ArRobot, double>(myRobot, &ArRobot::setHeading, 90)); 00101 keyHandler->addKeyHandler('d', new ArFunctor1C<ArRobot, double>(myRobot, &ArRobot::setHeading, 180)); 00102 keyHandler->addKeyHandler('f', new ArFunctor1C<ArRobot, double>(myRobot, &ArRobot::setHeading, 270)); 00103 00104 } 00105 00106 void GyroTask::doTask(void) 00107 { 00108 /* 00109 double degrees = -((myRobot->getAnalog() * 5.0 / 255) - 2.509) * 150 / 2.5 * 1.265; 00110 if (fabs(degrees) < 2) 00111 degrees = 0; 00112 myHeading += degrees * .025; 00113 printf("%10f %10f %10f %10f\n", myRobot->getAnalog() * 5.0 / 255, degrees, 00114 myRobot->getRotVel(), myHeading); 00115 fflush(stdout); 00116 */ 00117 printf("gyro %10f robot %10f mixed %10f temp %d ave %g\n", myGyro->getHeading(), myRobot->getRawEncoderPose().getTh(), myRobot->getTh(), myGyro->getTemperature(), myGyro->getAverage()); 00118 } 00119 00120 00121 00122 int main(int argc, char **argv) 00123 { 00124 // robot 00125 ArRobot robot; 00126 00127 // the joydrive action 00128 ArActionJoydrive joydriveAct; 00129 // the keydrive action 00130 ArActionKeydrive keydriveAct; 00131 00132 GyroTask gyro(&robot); 00133 00134 // sonar device, so the limiter will work, this must be added to the robot 00135 ArSonarDevice sonar; 00136 00137 ArSimpleConnector connector(&argc, argv); 00138 if (!connector.parseArgs() || argc > 1) 00139 { 00140 connector.logOptions(); 00141 exit(1); 00142 } 00143 00144 // mandatory init 00145 Aria::init(); 00146 00147 printf("This program will allow you to use a joystick or keyboard to control the robot.\nYou can use the arrow keys to drive, and the spacebar to stop.\nFor joystick control press the trigger button and then drive.\nPress escape to exit.\n"); 00148 00149 // if we don't have a joystick, let 'em know 00150 if (!joydriveAct.joystickInited()) 00151 printf("Do not have a joystick, only the arrow keys on the keyboard will work.\n"); 00152 00153 // set the joystick so it won't do anything if the button isn't pressed 00154 joydriveAct.setStopIfNoButtonPressed(false); 00155 00156 // add the sonar to the robot 00157 robot.addRangeDevice(&sonar); 00158 00159 // try to connect, if we fail exit 00160 if (!connector.connectRobot(&robot)) 00161 { 00162 printf("Could not connect to robot... exiting\n"); 00163 Aria::shutdown(); 00164 return 1; 00165 } 00166 00167 robot.comInt(ArCommands::ENABLE, 1); 00168 00169 robot.addAction(&joydriveAct, 50); 00170 robot.addAction(&keydriveAct, 45); 00171 00172 // set the joydrive action so it'll let the keydrive action fire if 00173 // there is no button pressed 00174 joydriveAct.setStopIfNoButtonPressed(false); 00175 00176 00177 // run the robot, true here so that the run will exit if connection lost 00178 robot.run(true); 00179 00180 // now exit 00181 Aria::shutdown(); 00182 return 0; 00183 }
1.4.7