00001 /*!@file SeaBee/SeaBee-AUVcompetition-master.C main 2007 competition code 00002 Run seabee-AUVcompetition-master at CPU_A 00003 Run seabee-AUVcompetition at CPU_B */ 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00006 // University of Southern California (USC) and the iLab at USC. // 00007 // See http://iLab.usc.edu for information about this project. // 00008 // //////////////////////////////////////////////////////////////////// // 00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00011 // in Visual Environments, and Applications'' by Christof Koch and // 00012 // Laurent Itti, California Institute of Technology, 2001 (patent // 00013 // pending; application number 09/912,225 filed July 23, 2001; see // 00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00017 // // 00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00019 // redistribute it and/or modify it under the terms of the GNU General // 00020 // Public License as published by the Free Software Foundation; either // 00021 // version 2 of the License, or (at your option) any later version. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00026 // PURPOSE. See the GNU General Public License for more details. // 00027 // // 00028 // You should have received a copy of the GNU General Public License // 00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00031 // Boston, MA 02111-1307 USA. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // 00034 // Primary maintainer for this file: Michael Montalbo <montalbo@usc.edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/SeaBee/SeaBee-AUVcompetition-master.C $ 00036 // $Id: SeaBee-AUVcompetition-master.C 10794 2009-02-08 06:21:09Z itti $ 00037 // 00038 ////////////////////////////////////////////////////////////////////////// 00039 00040 #include "Beowulf/Beowulf.H" 00041 #include "Component/ModelManager.H" 00042 #include "Media/FrameSeries.H" 00043 #include "Transport/FrameIstream.H" 00044 #include "Raster/Raster.H" 00045 #include "Image/Image.H" 00046 #include "Image/Pixels.H" 00047 #include "GUI/XWinManaged.H" 00048 00049 #include "Media/MediaOpts.H" 00050 #include "Devices/DeviceOpts.H" 00051 #include "Raster/GenericFrame.H" 00052 00053 #include "Image/CutPaste.H" 00054 00055 #include "AgentManagerA.H" 00056 #include "SubGUI.H" 00057 #include "Globals.H" 00058 #include "SubController.H" 00059 00060 #include <signal.h> 00061 00062 #define SIM_MODE false 00063 00064 volatile bool goforever = false; 00065 00066 // gets the messages from COM_B and relay it to the agent manager 00067 void checkInMessages 00068 ( nub::soft_ref<Beowulf> beo, 00069 nub::ref<AgentManagerA> agentManager); 00070 00071 // gets the out messages from the agent manager and send it to COM_B 00072 void checkOutMessages 00073 ( nub::ref<AgentManagerA> agentManager, 00074 nub::soft_ref<Beowulf> beo); 00075 00076 // package an agent manager command to a TCP message to send 00077 void packageAgentManagerCommand 00078 (nub::ref<AgentManagerA> agentManager, 00079 rutz::shared_ptr<AgentManagerCommand> agentManagerCommand, 00080 TCPmessage &smsg); 00081 00082 // unpackage an ocean object to a TCP message 00083 rutz::shared_ptr<SensorResult> unpackageToSensorResult 00084 ( TCPmessage rmsg ); 00085 00086 // send new image to COM_B if in simMode 00087 void sendImageUpdate 00088 ( Image<PixRGB<byte> > img, nub::soft_ref<Beowulf> beo ); 00089 00090 // ###################################################################### 00091 //! Signal handler (e.g., for control-C) 00092 void terminate(int s) 00093 { 00094 LERROR("*** INTERRUPT ***"); 00095 goforever = false; 00096 exit(1); 00097 } 00098 00099 // ###################################################################### 00100 int main( int argc, const char* argv[] ) 00101 { 00102 MYLOGVERB = LOG_INFO; 00103 00104 // instantiate a model manager: 00105 ModelManager manager("SeaBee 2008 Competition Master"); 00106 00107 // Instantiate our various ModelComponents: 00108 nub::soft_ref<Beowulf> 00109 beo(new Beowulf(manager, "Beowulf Master", "BeowulfMaster", true)); 00110 manager.addSubComponent(beo); 00111 00112 #if SIM_MODE == false 00113 nub::soft_ref<InputFrameSeries> ifs; 00114 00115 ifs.reset(new InputFrameSeries(manager)); 00116 manager.addSubComponent(ifs); 00117 #endif 00118 00119 nub::soft_ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager)); 00120 manager.addSubComponent(ofs); 00121 00122 nub::soft_ref<SubGUI> subGUI(new SubGUI(manager)); 00123 manager.addSubComponent(subGUI); 00124 00125 nub::soft_ref<SubController> subController(new SubController(manager, "SubController", "SubController", SIM_MODE)); 00126 manager.addSubComponent(subController); 00127 00128 // create an Agent Manager 00129 nub::ref<AgentManagerA> agentManager(new AgentManagerA(subController,manager)); 00130 manager.addSubComponent(agentManager); 00131 00132 manager.exportOptions(MC_RECURSE); 00133 00134 manager.setOptionValString(&OPT_InputFrameSource, "V4L2"); 00135 manager.setOptionValString(&OPT_FrameGrabberMode, "YUYV"); 00136 manager.setOptionValString(&OPT_FrameGrabberDims, "1024x576"); 00137 manager.setOptionValString(&OPT_FrameGrabberByteSwap, "no"); 00138 manager.setOptionValString(&OPT_FrameGrabberFPS, "30"); 00139 00140 // Parse command-line: 00141 if (manager.parseCommandLine(argc, argv, "", 0, 0) == false) return(1); 00142 00143 int w, h; 00144 00145 #if SIM_MODE == false 00146 w = ifs->getWidth(); 00147 h = ifs->getHeight(); 00148 #else 00149 w = 320; 00150 h = 240; 00151 #endif 00152 00153 std::string dims = convertToString(Dims(w, h)); 00154 00155 manager.setOptionValString(&OPT_InputFrameDims, dims); 00156 00157 manager.setModelParamVal("InputFrameDims", Dims(w, h), 00158 MC_RECURSE | MC_IGNORE_MISSING); 00159 00160 TCPmessage rmsg; // buffer to receive messages 00161 TCPmessage smsg; // buffer to send messages 00162 00163 int32 rframe = 0, raction = 0, rnode = 0; 00164 00165 // catch signals and redirect them to terminate for clean exit: 00166 signal(SIGHUP, terminate); signal(SIGINT, terminate); 00167 signal(SIGQUIT, terminate); signal(SIGTERM, terminate); 00168 signal(SIGALRM, terminate); 00169 00170 // let's do it! 00171 manager.start(); 00172 00173 // send init params to COM B to initialize contact 00174 smsg.reset(0, INIT_COMM); 00175 smsg.addInt32(int32(2008)); 00176 beo->send(COM_B_NODE, smsg); 00177 00178 // SYNCHRONIZATION: wait until COM B is ready 00179 LINFO("Waiting for COM_B..."); 00180 rnode = COM_B_NODE; 00181 00182 while(!beo->receive(rnode, rmsg, rframe, raction, 5)); 00183 00184 rmsg.reset(rframe, raction); 00185 LINFO("COM_B(%d) is ready", rnode); 00186 00187 //eventually make this a command-line param 00188 bool competitionMode = false; 00189 00190 // Setup GUI if not in competition mode 00191 if(!competitionMode) 00192 { 00193 subGUI->startThread(ofs); 00194 subGUI->setupGUI(subController.get(), true); 00195 subGUI->addMeter(subController->getIntPressurePtr(), 00196 "Int Pressure", 500, PixRGB<byte>(255, 0, 0)); 00197 subGUI->addMeter(subController->getHeadingPtr(), 00198 "Heading", 360, PixRGB<byte>(192, 255, 0)); 00199 subGUI->addMeter(subController->getPitchPtr(), 00200 "Pitch", 256, PixRGB<byte>(192, 255, 0)); 00201 subGUI->addMeter(subController->getRollPtr(), 00202 "Roll", 256, PixRGB<byte>(192, 255, 0)); 00203 subGUI->addMeter(subController->getDepthPtr(), 00204 "Depth", 300, PixRGB<byte>(192, 255, 0)); 00205 subGUI->addMeter(subController->getThruster_Up_Left_Ptr(), 00206 "Motor_Up_Left", -100, PixRGB<byte>(0, 255, 0)); 00207 subGUI->addMeter(subController->getThruster_Up_Right_Ptr(), 00208 "Motor_Up_Right", -100, PixRGB<byte>(0, 255, 0)); 00209 subGUI->addMeter(subController->getThruster_Up_Back_Ptr(), 00210 "Motor_Up_Back", -100, PixRGB<byte>(0, 255, 0)); 00211 subGUI->addMeter(subController->getThruster_Fwd_Left_Ptr(), 00212 "Motor_Fwd_Left", -100, PixRGB<byte>(0, 255, 0)); 00213 subGUI->addMeter(subController->getThruster_Fwd_Right_Ptr(), 00214 "Motor_Fwd_Right", -100, PixRGB<byte>(0, 255, 0)); 00215 00216 subGUI->addImage(subController->getSubImagePtr()); 00217 subGUI->addImage(subController->getPIDImagePtr()); 00218 } 00219 00220 #if SIM_MODE == false 00221 //start streaming input frames 00222 ifs->startStream(); 00223 #endif 00224 00225 00226 agentManager->startRun(); 00227 goforever = true; uint fnum = 0; 00228 00229 Image< PixRGB<byte> > img(w,h, ZEROS); 00230 00231 while(goforever) 00232 { 00233 #if SIM_MODE == false 00234 ifs->updateNext(); img = ifs->readRGB(); 00235 if(!img.initialized()) {Raster::waitForKey(); break; } 00236 #else 00237 //get sim image from bottom camera 00238 img = subController->getImage(1); 00239 sendImageUpdate(subController->getImage(2),beo); 00240 #endif 00241 00242 agentManager->setCurrentImage(img, fnum); 00243 fnum++; 00244 00245 // check COM_B for in message 00246 checkInMessages(beo, agentManager); 00247 00248 // check out_messages 00249 // to send to COM_B 00250 checkOutMessages(agentManager, beo); 00251 } 00252 00253 // send abort to COM_B 00254 smsg.reset(0, ABORT); 00255 beo->send(COM_B_NODE, smsg); 00256 00257 // we are done 00258 manager.stop(); 00259 return 0; 00260 } 00261 00262 // ###################################################################### 00263 void checkInMessages 00264 ( nub::soft_ref<Beowulf> beo, 00265 nub::ref<AgentManagerA> agentManager) 00266 { 00267 int32 rframe = 0, raction = 0, rnode = 0; 00268 TCPmessage rmsg; // buffer to receive messages 00269 00270 // get all the messages sent in 00271 if(beo->receive(rnode, rmsg, rframe, raction, 5)) 00272 { 00273 // check the purpose of the message 00274 switch(raction) 00275 { 00276 case SENSOR_RESULT: 00277 { 00278 // unpackage message to a sensor result 00279 rutz::shared_ptr<SensorResult> sensorResult = 00280 unpackageToSensorResult(rmsg); 00281 00282 // update it in the agent manager 00283 agentManager->updateSensorResult(sensorResult); 00284 00285 break; 00286 } 00287 00288 default: 00289 LERROR("Unknown purpose"); 00290 } 00291 } 00292 } 00293 00294 // send new image to COM_B if in simMode 00295 void sendImageUpdate(Image<PixRGB<byte> > img, 00296 nub::soft_ref<Beowulf> beo) 00297 { 00298 int32 rnode = 0; 00299 TCPmessage smsg; 00300 00301 int32 sframe = 0; 00302 int32 saction = IMAGE_UPDATE; 00303 00304 smsg.reset(sframe, saction); 00305 00306 smsg.addImage(img); 00307 00308 // send the message to COM_B 00309 beo->send(rnode, smsg); 00310 } 00311 00312 // ###################################################################### 00313 void checkOutMessages 00314 ( nub::ref<AgentManagerA> agentManager, 00315 nub::soft_ref<Beowulf> beo) 00316 { 00317 int32 rnode = 0; 00318 TCPmessage smsg; // buffer to send messages 00319 00320 // while there is a message that needs sending 00321 if(agentManager->getNumCommands() > 0) 00322 { 00323 LINFO("COM_A: sending out a command"); 00324 // pop the top of the queue 00325 // and packet the message properly 00326 packageAgentManagerCommand(agentManager, 00327 agentManager->popCommand(), 00328 smsg); 00329 00330 // send the message to COM_B 00331 beo->send(rnode, smsg); 00332 } 00333 } 00334 00335 // ###################################################################### 00336 void packageAgentManagerCommand 00337 (nub::ref<AgentManagerA> agentManager, 00338 rutz::shared_ptr<AgentManagerCommand> agentManagerCommand, 00339 TCPmessage &smsg) 00340 { 00341 int32 sframe = 0; 00342 int32 saction = agentManagerCommand->itsCommandType; 00343 00344 smsg.reset(sframe, saction); 00345 00346 switch(agentManagerCommand->itsCommandType) 00347 { 00348 00349 case UPDATE_MISSION: 00350 agentManager->updateAgentsMission(agentManagerCommand->itsMission); 00351 smsg.addInt32(int32(agentManagerCommand->itsMission.missionName)); 00352 smsg.addInt32(int32(agentManagerCommand->itsMission.timeForMission)); 00353 smsg.addInt32(int32(agentManagerCommand->itsMission.missionState)); 00354 break; 00355 default: 00356 LINFO("Unknown command type"); 00357 } 00358 } 00359 00360 // ###################################################################### 00361 rutz::shared_ptr<SensorResult> unpackageToSensorResult 00362 (TCPmessage rmsg) 00363 { 00364 00365 SensorResult::SensorResultType type = 00366 (SensorResult::SensorResultType)(rmsg.getElementInt32()); 00367 00368 SensorResult::SensorResultStatus status = 00369 (SensorResult::SensorResultStatus)(rmsg.getElementInt32()); 00370 00371 rutz::shared_ptr<SensorResult> sensorResult(new SensorResult(type)); 00372 00373 sensorResult->setStatus(status); 00374 00375 switch(type) 00376 { 00377 case SensorResult::BUOY: 00378 { 00379 int x = int(rmsg.getElementInt32()); 00380 int y = int(rmsg.getElementInt32()); 00381 int z = int(rmsg.getElementInt32()); 00382 sensorResult->setPosition(Point3D(x,y,z)); 00383 break; 00384 } 00385 case SensorResult::PIPE: 00386 { 00387 int x = int(rmsg.getElementInt32()); 00388 int y = int(rmsg.getElementInt32()); 00389 int z = int(rmsg.getElementInt32()); 00390 sensorResult->setPosition(Point3D(x,y,z)); 00391 // LINFO("PIPE: %d,%d",x,z); 00392 double angle = rmsg.getElementDouble(); 00393 sensorResult->setOrientation(Angle(angle)); 00394 uint fnum = int(rmsg.getElementInt32()); 00395 sensorResult->setFrameNum(fnum); 00396 break; 00397 } 00398 case SensorResult::BIN: 00399 { 00400 int x = int(rmsg.getElementInt32()); 00401 int y = int(rmsg.getElementInt32()); 00402 int z = int(rmsg.getElementInt32()); 00403 sensorResult->setPosition(Point3D(x,y,z)); 00404 break; 00405 } 00406 case SensorResult::PINGER: 00407 { 00408 00409 double angle = rmsg.getElementDouble(); 00410 sensorResult->setOrientation(Angle(angle)); 00411 break; 00412 } 00413 case SensorResult::SALIENCY: 00414 { 00415 int x = int(rmsg.getElementInt32()); 00416 int y = int(rmsg.getElementInt32()); 00417 int z = int(rmsg.getElementInt32()); 00418 sensorResult->setPosition(Point3D(x,y,z)); 00419 break; 00420 } 00421 default: LINFO("Unknown sensor result type: %d.", type); 00422 } 00423 00424 return sensorResult; 00425 } 00426 00427 // ###################################################################### 00428 /* So things look consistent in everyone's emacs... */ 00429 /* Local Variables: */ 00430 /* indent-tabs-mode: nil */ 00431 /* End: */