00001 /*!@file Beosub/BeeBrain/PreFrontalCortex.C 00002 decision maker for strategy to complete missions */ 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Michael Montalbo <montalbo@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/BeoSub/BeeBrain/PreFrontalCortex.C $ 00035 // $Id: PreFrontalCortex.C 8623 2007-07-25 17:57:51Z rjpeters $ 00036 00037 #include "BeoSub/BeeBrain/PreFrontalCortex.H" 00038 00039 // ###################################################################### 00040 PreFrontalCortexAgent::PreFrontalCortexAgent(std::string name) : Agent(name) 00041 { 00042 itsRunTimer.reset(new Timer(1000000)); 00043 itsCurrentMissionTimer.reset(new Timer(1000000)); 00044 } 00045 00046 // ###################################################################### 00047 PreFrontalCortexAgent::PreFrontalCortexAgent 00048 (std::string name, rutz::shared_ptr<AgentManagerA> ama) : 00049 Agent(name), itsAgentManager(ama) 00050 { 00051 itsRunTimer.reset(new Timer(1000000)); 00052 itsCurrentMissionTimer.reset(new Timer(1000000)); 00053 } 00054 00055 // ###################################################################### 00056 PreFrontalCortexAgent::~PreFrontalCortexAgent() 00057 { } 00058 00059 // ###################################################################### 00060 void PreFrontalCortexAgent::start() 00061 { 00062 populateMissions(); 00063 currentMission = itsMissions[0]; 00064 // rutz::shared_ptr<OceanObject> cross(new OceanObject()); 00065 // cross->setType(OceanObject::CROSS); 00066 // itsAgentManager->pushCommand((CommandType)(SEARCH_OCEAN_OBJECT), POSITION, cross); 00067 } 00068 00069 00070 // ###################################################################### 00071 void PreFrontalCortexAgent::populateMissions() 00072 { 00073 LINFO("Populating Missions..."); 00074 00075 // go through gate 00076 rutz::shared_ptr<Mission> gate(new Mission()); 00077 gate->timeForMission = 90; 00078 gate->missionName = GATE; 00079 gate->missionState = NOT_STARTED; 00080 rutz::shared_ptr<OceanObject> cross(new OceanObject(OceanObject::CROSS)); 00081 gate->missionObjects.push_back(cross); 00082 itsMissions.push_back(gate); 00083 00084 // // hit first buoy 00085 // rutz::shared_ptr<Mission> firstBuoy; 00086 // firstBuoy->timeForMission = 210; 00087 // firstBuoy->missionName = HIT_START_BUOY; 00088 // rutz::shared_ptr<OceanObject> buoy(new OceanObject(OceanObject::BUOY)); 00089 // firstBuoy->missionObjects.push_back(buoy); 00090 // itsMissions.push_back(firstBuoy); 00091 00092 // //drop marker in first bin 00093 // rutz::shared_ptr<Mission> firstBin; 00094 // firstBin->timeForMission = 150; 00095 // firstBin->missionName = FIRST_BIN; 00096 // rutz::shared_ptr<OceanObject> firstPipe(new OceanObject(OceanObject::PIPE)); 00097 // rutz::shared_ptr<OceanObject> bin(new OceanObject(OceanObject::BIN)); 00098 // firstBin->missionObjects.push_back(firstPipe); 00099 // firstBin->missionObjects.push_back(bin); 00100 // itsMissions.push_back(firstBin); 00101 00102 // //hit second buoy and drop marker in second bin 00103 // rutz::shared_ptr<Mission> secondBin; 00104 // secondBin->timeForMission = 150; 00105 // secondBin->missionName = SECOND_BIN; 00106 // rutz::shared_ptr<OceanObject> secondPipe(new OceanObject(OceanObject::PIPE)); 00107 // rutz::shared_ptr<OceanObject> secondBuoy(new OceanObject(OceanObject::BUOY)); 00108 // rutz::shared_ptr<OceanObject> coverBin(new OceanObject(OceanObject::BIN)); 00109 // secondBin->missionObjects.push_back(secondPipe); 00110 // secondBin->missionObjects.push_back(secondBuoy); 00111 // secondBin->missionObjects.push_back(coverBin); 00112 // itsMissions.push_back(secondBin); 00113 00114 // //find and recover the cross 00115 // rutz::shared_ptr<Mission> treasure; 00116 // treasure->timeForMission = 300; 00117 // treasure->missionName = GET_TREASURE; 00118 // rutz::shared_ptr<OceanObject> pinger(new OceanObject(OceanObject::PINGER)); 00119 // rutz::shared_ptr<OceanObject> cross(new OceanObject(OceanObject::CROSS)); 00120 // treasure->missionObjects.push_back(pinger); 00121 // treasure->missionObjects.push_back(cross); 00122 // itsMissions.push_back(treasure); 00123 00124 // // initialize all mission status 00125 // for(uint i = 0; i < itsMissions.size(); i++) 00126 // { 00127 // itsMissions[i]->missionState = NOT_STARTED; 00128 // } 00129 00130 stateChanged(); 00131 } 00132 00133 // ###################################################################### 00134 void PreFrontalCortexAgent::lookForObjects 00135 (std::vector<rutz::shared_ptr<OceanObject> > oceanObjects, 00136 bool startLooking) 00137 { 00138 CommandType cmdType = SEARCH_OCEAN_OBJECT_CMD; 00139 00140 if(startLooking == false) 00141 { 00142 cmdType = STOP_SEARCH_OCEAN_OBJECT_CMD; 00143 } 00144 00145 for(uint i = 0; i < oceanObjects.size(); i++) 00146 { 00147 rutz::shared_ptr<OceanObject> o = oceanObjects[i]; 00148 switch(o->getType()) 00149 { 00150 case OceanObject::CROSS: 00151 itsAgentManager->pushCommand 00152 (cmdType, 00153 POSITION, 00154 o); 00155 itsAgentManager->pushCommand 00156 (cmdType, 00157 ORIENTATION, 00158 o); 00159 itsAgentManager->pushCommand 00160 (cmdType, 00161 MASS, 00162 o); 00163 break; 00164 case OceanObject::BIN: 00165 itsAgentManager->pushCommand 00166 (cmdType, 00167 POSITION, 00168 o); 00169 break; 00170 case OceanObject::BUOY: 00171 itsAgentManager->pushCommand 00172 (cmdType, 00173 POSITION, 00174 o); 00175 itsAgentManager->pushCommand 00176 (cmdType, 00177 FREQUENCY, 00178 o); 00179 break; 00180 case OceanObject::PIPE: 00181 itsAgentManager->pushCommand 00182 (cmdType, 00183 POSITION, 00184 o); 00185 itsAgentManager->pushCommand 00186 (cmdType, 00187 ORIENTATION, 00188 o); 00189 break; 00190 case OceanObject::PINGER: 00191 itsAgentManager->pushCommand 00192 (cmdType, 00193 ORIENTATION, 00194 o); 00195 itsAgentManager->pushCommand 00196 (cmdType, 00197 DISTANCE, 00198 o); 00199 break; 00200 default: 00201 LERROR("unknown ocean object type"); 00202 break; 00203 } 00204 } 00205 } 00206 00207 // ###################################################################### 00208 void PreFrontalCortexAgent::msgOceanObjectUpdate() 00209 { 00210 LINFO("Recieved msgOceanObjectUpdate"); 00211 stateChanged(); 00212 } 00213 00214 // ###################################################################### 00215 void PreFrontalCortexAgent::msgMovementComplete() 00216 { 00217 LINFO("Recieved msgMovementComplete"); 00218 stateChanged(); 00219 } 00220 00221 // ###################################################################### 00222 bool PreFrontalCortexAgent::pickAndExecuteAnAction() 00223 { 00224 // if we almost run out of time for the overall run 00225 if(itsRunTimer->get() > AUVSI07_COMPETITION_TIME) 00226 { 00227 // move on to another mission 00228 //currentMission->missionState = FAILED; 00229 //return true; 00230 LINFO("FIX ME - Almost out of time"); 00231 } 00232 00233 // find the next uncompleted mission 00234 currentMission.reset(); 00235 for(uint i = 0; i < itsMissions.size(); i++) 00236 if(itsMissions[i]->missionState != COMPLETED) 00237 { 00238 currentMission = itsMissions[i]; break; 00239 } 00240 00241 if(currentMission.is_invalid()) 00242 { 00243 //unloadKoolAid(); 00244 return false; 00245 } 00246 00247 if(currentMission->missionName == GATE) 00248 return executeGateMission(); 00249 if(currentMission->missionName == HIT_START_BUOY) 00250 return executeBuoyMission(); 00251 if(currentMission->missionName == FIRST_BIN) 00252 return executeFirstBinMission(); 00253 if(currentMission->missionName == SECOND_BIN) 00254 return executeSecondBinMission(); 00255 if(currentMission->missionName == GET_TREASURE) 00256 return executeCrossMission(); 00257 00258 return false; 00259 } 00260 00261 // ###################################################################### 00262 bool PreFrontalCortexAgent::executeGateMission() 00263 { 00264 // if current mission timer is > pre-allocated time 00265 if(currentMission->missionState != NOT_STARTED && 00266 itsCurrentMissionTimer->get() > currentMission->timeForMission) 00267 { 00268 // move on to another mission 00269 currentMission->missionState = FAILED; 00270 return true; 00271 } 00272 00273 // start the mission 00274 if(currentMission->missionState == NOT_STARTED) 00275 { 00276 // set the run and current mission 00277 itsRunTimer->reset(); 00278 itsCurrentMissionTimer->reset(); 00279 00280 LINFO("Starting Mission"); 00281 00282 lookForObjects(currentMission->missionObjects); 00283 00284 rutz::shared_ptr<ComplexMovement> 00285 goThroughGate(new ComplexMovement()); 00286 goThroughGate->addMove(&PreMotorComplex::forward, ONCE, 5.0); 00287 itsPreMotorComplex->run(goThroughGate); 00288 currentMission->missionState = SEARCHING; 00289 return true; 00290 } 00291 // searching 00292 else if(currentMission->missionState == SEARCHING) 00293 { 00294 LINFO("Searching for cross"); 00295 00296 rutz::shared_ptr<OceanObject> theCross; 00297 00298 for(uint i = 0; i < currentMission->missionObjects.size(); i++) 00299 { 00300 if(currentMission->missionObjects[i]->getType() 00301 == OceanObject::CROSS) 00302 { 00303 theCross = currentMission->missionObjects[i]; 00304 break; 00305 } 00306 } 00307 00308 // center on the cross 00309 if(theCross.is_valid() 00310 && theCross->getPosition().isValidY() 00311 && theCross->getPosition().isValidX()) 00312 { 00313 currentMission->missionState = CENTERING; 00314 } 00315 00316 return true; 00317 } 00318 // if currently centering 00319 else if(currentMission->missionState == CENTERING) 00320 { 00321 LINFO("Centering on cross"); 00322 rutz::shared_ptr<OceanObject> theCross; 00323 for(uint i = 0; i < currentMission->missionObjects.size(); i++) 00324 { 00325 if(currentMission->missionObjects[i]->getType() 00326 == OceanObject::CROSS) 00327 { 00328 theCross = currentMission->missionObjects[i]; 00329 break; 00330 } 00331 } 00332 00333 if(theCross.is_valid() 00334 && abs(theCross->getPosition().x - 160) < 20 00335 && abs(theCross->getPosition().y - 120) < 20) 00336 { 00337 itsPreMotorComplex->msgHalt(); 00338 00339 currentMission->missionState = COMPLETED; 00340 } 00341 else if(theCross.is_valid()) 00342 { 00343 rutz::shared_ptr<ComplexMovement> 00344 centerOnCross(new ComplexMovement()); 00345 centerOnCross->addMove(&PreMotorComplex::vis_center, REPEAT, theCross->getPositionPtr()); 00346 itsPreMotorComplex->run(centerOnCross); 00347 } 00348 00349 return true; 00350 } 00351 // mission is completed 00352 else if(currentMission->missionState == COMPLETED) 00353 { 00354 LINFO("Move through gate complete"); 00355 lookForObjects(currentMission->missionObjects, false); 00356 // rutz::shared_ptr<ComplexMovement> 00357 // victoryDance(new ComplexMovement()); 00358 // Angle a(120); 00359 // victoryDance->addOnceMove(&PreMotorComplex::dive, 3.0 , Angle(-1.0)); 00360 // itsPreMotorComplex->run(victoryDance); 00361 return false; 00362 // setNextMission(); 00363 } 00364 00365 return false; 00366 } 00367 00368 // ###################################################################### 00369 bool PreFrontalCortexAgent::executeBuoyMission() 00370 { 00371 // if current mission timer is > pre-allocated time 00372 if(currentMission->missionState != NOT_STARTED && 00373 itsCurrentMissionTimer->get() > currentMission->timeForMission) 00374 { 00375 // move on to another mission 00376 currentMission->missionState = FAILED; 00377 return true; 00378 } 00379 00380 // start the mission 00381 if(currentMission->missionState == NOT_STARTED) 00382 { 00383 LINFO("Starting Buoy Mission"); 00384 // itsCurrentMissionTimer->reset(); 00385 00386 // lookForObjects(currentMission->missionObjects); 00387 // rutz::shared_ptr<ComplexMovement> 00388 // strafe(new ComplexMovement()); 00389 // strafe->addMove(&PreMotorComplex::forward, ONCE, 5.0); 00390 // itsPreMotorComplex->run(goThroughGate); 00391 00392 currentMission->missionState = SEARCHING; 00393 return true; 00394 } 00395 else if(currentMission->missionState == SEARCHING) 00396 { 00397 return true; 00398 } 00399 else if(currentMission->missionState == CENTERING) { 00400 return true; 00401 } 00402 // mission is completed 00403 else if(currentMission->missionState == COMPLETED) 00404 { 00405 return true; 00406 } 00407 return false; 00408 } 00409 00410 // ###################################################################### 00411 bool PreFrontalCortexAgent::executeFirstBinMission() 00412 { 00413 // if current mission timer is > pre-allocated time 00414 if(currentMission->missionState != NOT_STARTED && 00415 itsCurrentMissionTimer->get() > currentMission->timeForMission) 00416 { 00417 // move on to another mission 00418 currentMission->missionState = FAILED; 00419 return true; 00420 } 00421 00422 // start the mission 00423 if(currentMission->missionState == NOT_STARTED) 00424 { 00425 LINFO("Starting First Bin Mission"); 00426 itsCurrentMissionTimer->reset(); 00427 00428 currentMission->missionState = SEARCHING; 00429 return true; 00430 } 00431 else if(currentMission->missionState == SEARCHING) 00432 { 00433 return false; 00434 } 00435 else if(currentMission->missionState == CENTERING) 00436 { 00437 return true; 00438 } 00439 // mission is completed 00440 else if(currentMission->missionState == COMPLETED) 00441 { 00442 return true; 00443 } 00444 return false; 00445 } 00446 00447 // ###################################################################### 00448 bool PreFrontalCortexAgent::executeSecondBinMission() 00449 { 00450 // if current mission timer is > pre-allocated time 00451 if(currentMission->missionState != NOT_STARTED && 00452 itsCurrentMissionTimer->get() > currentMission->timeForMission) 00453 { 00454 // move on to another mission 00455 currentMission->missionState = FAILED; 00456 return true; 00457 } 00458 00459 // start the mission 00460 if(currentMission->missionState == NOT_STARTED) 00461 { 00462 LINFO("Starting Second Bin Mission"); 00463 itsCurrentMissionTimer->reset(); 00464 00465 currentMission->missionState = SEARCHING; 00466 return true; 00467 } 00468 else if(currentMission->missionState == SEARCHING) 00469 { 00470 return false; 00471 } 00472 else if(currentMission->missionState == CENTERING) 00473 { 00474 return true; 00475 } 00476 // mission is completed 00477 else if(currentMission->missionState == COMPLETED) 00478 { 00479 return true; 00480 } 00481 return false; 00482 } 00483 00484 // ###################################################################### 00485 bool PreFrontalCortexAgent::executeCrossMission() 00486 { 00487 // if current mission timer is > pre-allocated time 00488 if(currentMission->missionState != NOT_STARTED && 00489 itsCurrentMissionTimer->get() > currentMission->timeForMission) 00490 { 00491 // move on to another mission 00492 currentMission->missionState = FAILED; 00493 return true; 00494 } 00495 00496 // start the mission 00497 if(currentMission->missionState == NOT_STARTED) 00498 { 00499 LINFO("Starting Cross Mission"); 00500 itsCurrentMissionTimer->reset(); 00501 00502 currentMission->missionState = SEARCHING; 00503 return true; 00504 } 00505 else if(currentMission->missionState == SEARCHING) 00506 { 00507 return false; 00508 } 00509 else if(currentMission->missionState == CENTERING) 00510 { 00511 return true; 00512 } 00513 // mission is completed 00514 else if(currentMission->missionState == COMPLETED) 00515 { 00516 return true; 00517 } 00518 return false; 00519 } 00520 00521 // ###################################################################### 00522 // bool PreFrontalCortexAgent::setNextMission() 00523 // { 00524 00525 // } 00526 00527 // ###################################################################### 00528 /* So things look consistent in everyone's emacs... */ 00529 /* Local Variables: */ 00530 /* indent-tabs-mode: nil */ 00531 /* End: */ 00532