00001
00007 #include "Aria.h"
00008
00009
00010
00011
00012
00013 class Chase : public ArAction
00014 {
00015
00016 public:
00017
00018
00019 enum State {
00020 NO_TARGET,
00021 TARGET,
00022 };
00023
00024
00025 Chase(ArACTS_1_2 *acts, ArVCC4 *camera);
00026
00027
00028 ~Chase(void);
00029
00030
00031 ArActionDesired *fire(ArActionDesired currentDesired);
00032
00033
00034 bool setChannel(int channel);
00035
00036
00037 State getState(void) { return myState; }
00038
00039
00040 enum {
00041 WIDTH = 160,
00042 HEIGHT = 120
00043 };
00044
00045 protected:
00046 ArActionDesired myDesired;
00047 ArACTS_1_2 *myActs;
00048 ArVCC4 *myCamera;
00049 ArTime myLastSeen;
00050 State myState;
00051 int myChannel;
00052 int myMaxTime;
00053 };
00054
00055
00056
00057 Chase::Chase(ArACTS_1_2 *acts, ArVCC4 *camera) :
00058 ArAction("Chase", "Chases the largest blob.")
00059 {
00060 myActs = acts;
00061 myCamera = camera;
00062 myChannel = 0;
00063 myState = NO_TARGET;
00064 setChannel(1);
00065 myLastSeen.setToNow();
00066 myMaxTime = 1000;
00067 }
00068
00069
00070 Chase::~Chase(void) {}
00071
00072
00073
00074 ArActionDesired *Chase::fire(ArActionDesired currentDesired)
00075 {
00076 ArACTSBlob blob;
00077 ArACTSBlob largestBlob;
00078
00079 bool flag = false;
00080
00081 int numberOfBlobs;
00082 int blobArea = 10;
00083
00084 double xRel, yRel;
00085
00086
00087 myDesired.reset();
00088
00089 numberOfBlobs = myActs->getNumBlobs(myChannel);
00090
00091
00092 if(numberOfBlobs != 0)
00093 {
00094 for(int i = 0; i < numberOfBlobs; i++)
00095 {
00096 myActs->getBlob(myChannel, i + 1, &blob);
00097 if(blob.getArea() > blobArea)
00098 {
00099 flag = true;
00100 blobArea = blob.getArea();
00101 largestBlob = blob;
00102 }
00103 }
00104
00105 myLastSeen.setToNow();
00106 }
00107
00108
00109 if (myLastSeen.mSecSince() > myMaxTime)
00110 {
00111 if(myState != NO_TARGET) ArLog::log(ArLog::Normal, "Target Lost");
00112 myState = NO_TARGET;
00113 }
00114 else
00115 {
00116
00117 if(myState != TARGET) {
00118 ArLog::log(ArLog::Normal, "Target Aquired");
00119 ArLog::log(ArLog::Normal, "(Using channel %d with %d blobs)", myChannel, numberOfBlobs);
00120 }
00121 myState = TARGET;
00122 }
00123
00124 if(myState == TARGET && flag == true)
00125 {
00126
00127
00128 xRel = (double)(largestBlob.getXCG() - WIDTH/2.0) / (double)WIDTH;
00129 yRel = (double)(largestBlob.getYCG() - HEIGHT/2.0) / (double)HEIGHT;
00130
00131
00132 if(!(ArMath::fabs(yRel) < .20))
00133 {
00134 if (-yRel > 0)
00135 myCamera->tiltRel(1);
00136 else
00137 myCamera->tiltRel(-1);
00138 }
00139
00140
00141 if (ArMath::fabs(xRel) < .10)
00142 {
00143 myDesired.setDeltaHeading(0);
00144 }
00145 else
00146 {
00147 if (ArMath::fabs(-xRel * 10) <= 10)
00148 myDesired.setDeltaHeading(-xRel * 10);
00149 else if (-xRel > 0)
00150 myDesired.setDeltaHeading(10);
00151 else
00152 myDesired.setDeltaHeading(-10);
00153
00154 }
00155
00156 myDesired.setVel(200);
00157 return &myDesired;
00158 }
00159
00160
00161
00162 return &myDesired;
00163 }
00164
00165
00166 bool Chase::setChannel(int channel)
00167 {
00168 if (channel >= 1 && channel <= ArACTS_1_2::NUM_CHANNELS)
00169 {
00170 myChannel = channel;
00171 return true;
00172 }
00173 else
00174 return false;
00175 }
00176
00177
00178
00179
00180
00181 void toggleAction(ArAction* action)
00182 {
00183 if(action->isActive()) {
00184 action->deactivate();
00185 ArLog::log(ArLog::Normal, "%s action is now deactivated.", action->getName());
00186 }
00187 else {
00188 action->activate();
00189 ArLog::log(ArLog::Normal, "%s action is now activated.", action->getName());
00190 }
00191 }
00192
00193
00194
00195
00196 int main(int argc, char** argv)
00197 {
00198 Aria::init();
00199
00200
00201 ArRobot robot;
00202
00203
00204 ArKeyHandler keyHandler;
00205 Aria::setKeyHandler(&keyHandler);
00206
00207
00208 ArSonarDevice sonar;
00209
00210
00211 ArVCC4 vcc4 (&robot);
00212
00213
00214 ArACTS_1_2 acts;
00215
00216
00217 ArArgumentParser argParser(&argc, argv);
00218 argParser.loadDefaultArguments();
00219
00220
00221 ArSimpleConnector simpleConnector(&argParser);
00222
00223
00224 if (!Aria::parseArgs())
00225 {
00226 Aria::logOptions();
00227 keyHandler.restore();
00228 Aria::shutdown();
00229 return 1;
00230 }
00231
00232
00233 ArActionLimiterForwards limiter("speed limiter near", 350, 800, 200);
00234 ArActionLimiterForwards limiterFar("speed limiter far", 400, 1250, 300);
00235 ArActionLimiterBackwards backwardsLimiter;
00236 ArActionConstantVelocity stop("stop", 0);
00237
00238
00239
00240
00241 Chase chase(&acts, &vcc4);
00242
00243
00244 ArActionKeydrive keydriveAction;
00245
00246
00247 keyHandler.addKeyHandler('a', new ArGlobalFunctor1<ArAction*>(&toggleAction, &keydriveAction));
00248
00249
00250 Aria::setKeyHandler(&keyHandler);
00251
00252
00253 robot.attachKeyHandler(&keyHandler);
00254
00255
00256 robot.addRangeDevice(&sonar);
00257
00258
00259 if (!simpleConnector.connectRobot(&robot))
00260 {
00261 ArLog::log(ArLog::Terse, "Error: Could not connect to robot... exiting\n");
00262 keyHandler.restore();
00263 Aria::exit(1);
00264 }
00265
00266
00267 if(!acts.openPort(&robot))
00268 {
00269 ArLog::log(ArLog::Terse, "Error: Could not connect to ACTS... exiting.");
00270 keyHandler.restore();
00271 Aria::exit(2);
00272 }
00273
00274
00275 vcc4.init();
00276
00277
00278 ArUtil::sleep(1000);
00279
00280
00281 robot.setAbsoluteMaxTransVel(400);
00282
00283
00284 robot.comInt(ArCommands::ENABLE, 1);
00285
00286
00287 robot.comInt(ArCommands::SOUNDTOG, 0);
00288
00289
00290 ArUtil::sleep(200);
00291
00292
00293 robot.addAction(&limiter, 7);
00294 robot.addAction(&limiterFar, 6);
00295 robot.addAction(&backwardsLimiter, 5);
00296 robot.addAction(&keydriveAction, 4);
00297 robot.addAction(&chase, 3);
00298 robot.addAction(&stop, 1);
00299
00300
00301 keydriveAction.deactivate();
00302
00303
00304 ArLog::log(ArLog::Normal, "Running. Train ACTS to detect a color to drive towards an object, or use 'a' key to switch to keyboard driving mode.");
00305 robot.run(true);
00306
00307 Aria::shutdown();
00308 return 0;
00309 }
00310