00001 /*!@file NeovisionII/MissileLauncher.C */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the 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: Lior Elazary 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/NeovisionII/MissileLauncher.C $ 00035 // $Id: MissileLauncher.C 13901 2010-09-09 15:12:26Z lior $ 00036 // 00037 00038 #include "NeovisionII/MissileLauncher.H" 00039 #include "Util/sformat.H" 00040 #include "Image/DrawOps.H" 00041 00042 using namespace std; 00043 using namespace ImageIceMod; 00044 00045 MissileLauncher::MissileLauncher(ModelManager& mgr, 00046 nub::ref<OutputFrameSeries> ofs, 00047 const std::string& descrName, 00048 const std::string& tagName) : 00049 ModelComponent(mgr, descrName, tagName), 00050 itsOfs(ofs) 00051 { 00052 //Subscribe to the various topics 00053 IceStorm::TopicPrx topicPrx; 00054 itsTopicsSubscriptions.push_back(TopicInfo("RetinaTopic", topicPrx)); 00055 itsTopicsSubscriptions.push_back(TopicInfo("VisualCortexTopic", topicPrx)); 00056 itsTopicsSubscriptions.push_back(TopicInfo("SaliencyMapTopic", topicPrx)); 00057 itsTopicsSubscriptions.push_back(TopicInfo("VisualTrackerTopic", topicPrx)); 00058 00059 00060 #ifdef HAVE_USB_H 00061 usb_init(); 00062 usb_find_busses(); 00063 usb_find_devices(); 00064 00065 itsBusses = usb_get_busses(); 00066 00067 struct usb_bus *bus = NULL; 00068 struct usb_device *dev = NULL; 00069 00070 for (bus = itsBusses; bus && !dev; bus = bus->next) { 00071 for (dev = bus->devices; dev; dev = dev->next) { 00072 LINFO("Checking 0x%04x:0x%04x\n", 00073 dev->descriptor.idVendor, 00074 dev->descriptor.idProduct); 00075 if (dev->descriptor.idVendor == 0x0a81 && 00076 dev->descriptor.idProduct == 0x0701) { 00077 itsDev = dev; 00078 LINFO("Found launcher"); 00079 break; 00080 } 00081 } 00082 } 00083 00084 if (!itsDev) { 00085 LFATAL("Unable to find device.\n"); 00086 } 00087 00088 00089 itsLauncher = usb_open(itsDev); 00090 if (itsLauncher == NULL) { 00091 LFATAL("Unable to open device"); 00092 } 00093 00094 /* Detach kernel driver (usbhid) from device interface and claim */ 00095 usb_detach_kernel_driver_np(itsLauncher, 0); 00096 usb_detach_kernel_driver_np(itsLauncher, 1); 00097 00098 int ret = usb_set_configuration(itsLauncher, 1); 00099 if (ret < 0) { 00100 LFATAL("Unable to set device configuration"); 00101 } 00102 ret = usb_claim_interface(itsLauncher, 0); 00103 if (ret < 0) { 00104 LFATAL("Unable to claim interface"); 00105 } 00106 00107 itsCountdown = COUNTDOWN; 00108 #else 00109 LFATAL("Need libusb to work"); 00110 #endif 00111 } 00112 00113 00114 00115 MissileLauncher::~MissileLauncher() 00116 { 00117 unsubscribeSimEvents(); 00118 #ifdef HAVE_USB_H 00119 usb_release_interface(itsLauncher, 0); 00120 usb_close(itsLauncher); 00121 #endif 00122 } 00123 00124 00125 void MissileLauncher::initSimEvents(Ice::CommunicatorPtr icPtr, Ice::ObjectPrx objectPrx) 00126 { 00127 //Connect to the SimEvents 00128 Ice::ObjectPrx obj = icPtr->stringToProxy("SimEvents/TopicManager:tcp -p 11111"); 00129 IceStorm::TopicManagerPrx topicManager = 00130 IceStorm::TopicManagerPrx::checkedCast(obj); 00131 00132 //Subscribe the SimulationViewer to theTopics 00133 itsObjectPrx = objectPrx; 00134 //subscribe to the topics 00135 for(uint i=0; i<itsTopicsSubscriptions.size(); i++) 00136 { 00137 try { 00138 IceStorm::QoS qos; 00139 itsTopicsSubscriptions[i].topicPrx = 00140 topicManager->retrieve(itsTopicsSubscriptions[i].name.c_str()); //Get the 00141 itsTopicsSubscriptions[i].topicPrx->subscribeAndGetPublisher(qos, itsObjectPrx); //Subscribe to the retina topic 00142 } catch (const IceStorm::NoSuchTopic&) { 00143 LINFO("Error! No %s topic found!", itsTopicsSubscriptions[i].name.c_str()); 00144 } 00145 } 00146 } 00147 00148 void MissileLauncher::unsubscribeSimEvents() 00149 { 00150 //Unsubscribe from all the topics we are registerd to 00151 for(uint i=0; i<itsTopicsSubscriptions.size(); i++) 00152 { 00153 itsTopicsSubscriptions[i].topicPrx->unsubscribe(itsObjectPrx); 00154 } 00155 } 00156 00157 00158 void MissileLauncher::evolve(const SimEvents::EventMessagePtr& eMsg, 00159 const Ice::Current&) 00160 { 00161 if(eMsg->ice_isA("::SimEvents::RetinaMessage")){ 00162 SimEvents::RetinaMessagePtr msg = SimEvents::RetinaMessagePtr::dynamicCast(eMsg); 00163 itsRetinaImg = Ice2Image<PixRGB<byte> > (msg->img); 00164 itsMarkupImg = itsRetinaImg; 00165 } else if (eMsg->ice_isA("::SimEvents::VisualCortexMessage")){ 00166 SimEvents::VisualCortexMessagePtr msg = SimEvents::VisualCortexMessagePtr::dynamicCast(eMsg); 00167 itsVCX = Ice2Image<byte>(msg->vco); 00168 } else if (eMsg->ice_isA("::SimEvents::SaliencyMapMessage")){ 00169 SimEvents::SaliencyMapMessagePtr msg = SimEvents::SaliencyMapMessagePtr::dynamicCast(eMsg); 00170 itsSMap = Ice2Image<byte>(msg->smap); 00171 //draw the top N most salient points 00172 if (itsMarkupImg.initialized()) 00173 { 00174 for(uint i=0; i<msg->nMostSalientLoc.size(); i++) 00175 { 00176 SimEvents::LocInfo locInfo = msg->nMostSalientLoc[i]; 00177 00178 if (i == 0) //Draw the most salient location with a stronger color 00179 { 00180 drawRectSquareCorners(itsMarkupImg, 00181 Rectangle(Point2D<int>(locInfo.fullresMaxpos.i, locInfo.fullresMaxpos.j), Dims(3,3)), 00182 PixRGB<byte>(255, 0, 0), 6); 00183 } else { 00184 drawRectSquareCorners(itsMarkupImg, 00185 Rectangle(Point2D<int>(locInfo.fullresMaxpos.i, locInfo.fullresMaxpos.j), Dims(3,3)), 00186 PixRGB<byte>(150, 0, 0), 3); 00187 } 00188 } 00189 } 00190 } else if (eMsg->ice_isA("::SimEvents::VisualTrackerMessage")){ 00191 SimEvents::VisualTrackerMessagePtr msg = SimEvents::VisualTrackerMessagePtr::dynamicCast(eMsg); 00192 //draw the tracker locations 00193 if (itsMarkupImg.initialized()) 00194 { 00195 for(uint i=0; i<msg->trackLocs.size(); i++) 00196 { 00197 SimEvents::TrackInfo trackInfo = msg->trackLocs[i]; 00198 drawRectSquareCorners(itsMarkupImg, 00199 Rectangle(Point2D<int>(trackInfo.pos.i, trackInfo.pos.j), Dims(3,3)), 00200 PixRGB<byte>(0, 255, 0), 3); 00201 00202 itsTrackerLoc = Point2D<int>(trackInfo.pos.i, trackInfo.pos.j); 00203 } 00204 } 00205 } 00206 00207 } 00208 00209 00210 /* 00211 * Command to control Dream Cheeky USB missile launcher 00212 */ 00213 void MissileLauncher::send_command_cheeky(const char *cmd) 00214 { 00215 #ifdef HAVE_USB_H 00216 char data[8]; 00217 int ret; 00218 00219 memset(data, 0, 8); 00220 if (!strcmp(cmd, "up")) { 00221 data[0] = 0x02; 00222 } else if (!strcmp(cmd, "down")) { 00223 data[0] = 0x01; 00224 } else if (!strcmp(cmd, "left")) { 00225 data[0] = 0x04; 00226 } else if (!strcmp(cmd, "right")) { 00227 data[0] = 0x08; 00228 } else if (!strcmp(cmd, "fire")) { 00229 data[0] = 0x10; 00230 } else if (!strcmp(cmd, "stop")) { 00231 data[0] = 0x20; 00232 } else { 00233 LINFO("Unknown command: %s", cmd); 00234 } 00235 00236 ret = usb_control_msg(itsLauncher, 00237 USB_DT_HID, 00238 USB_REQ_SET_CONFIGURATION, 00239 USB_RECIP_ENDPOINT, 00240 0, 00241 data, 00242 8, // Length of data. 00243 5000); // Timeout 00244 if (ret != 8) { 00245 LINFO("Error: %s\n", usb_strerror()); 00246 } 00247 #endif 00248 } 00249 00250 00251 void MissileLauncher::run() 00252 { 00253 while(1) 00254 { 00255 Layout<PixRGB<byte> > outDisp; 00256 00257 if (itsMarkupImg.initialized()) 00258 itsOfs->writeRGB(itsMarkupImg, "Markup", FrameInfo("Markup", SRC_POS)); 00259 00260 if (itsVCX.initialized() && itsRetinaImg.initialized()) 00261 outDisp = toRGB(rescale(itsVCX, itsRetinaImg.getDims())); 00262 00263 if (outDisp.initialized()) 00264 itsOfs->writeRgbLayout(outDisp, "Output", FrameInfo("Output", SRC_POS)); 00265 00266 00267 if (itsMarkupImg.initialized()) 00268 { 00269 LINFO("Tracking %ix%i", itsTrackerLoc.i, itsTrackerLoc.j); 00270 int errX = itsTrackerLoc.i - (itsMarkupImg.getWidth()/2); 00271 int errY = itsTrackerLoc.j - (itsMarkupImg.getHeight()/2); 00272 00273 LINFO("Err %i,%i countdown=%i", errX, errY, itsCountdown); 00274 00275 if (abs(errX) > 30) 00276 { 00277 if (errX > 0) 00278 send_command_cheeky("right"); 00279 else 00280 send_command_cheeky("left"); 00281 itsCountdown = COUNTDOWN; 00282 } else { 00283 00284 itsCountdown--; 00285 if (abs(errY) > 20) 00286 { 00287 if (errY > 0) 00288 send_command_cheeky("down"); 00289 else 00290 send_command_cheeky("up"); 00291 } else { 00292 send_command_cheeky("stop"); 00293 } 00294 } 00295 00296 00297 if (itsCountdown < 0) 00298 { 00299 LINFO("Shoot......"); 00300 send_command_cheeky("fire"); 00301 sleep(4); 00302 itsCountdown = COUNTDOWN; 00303 } 00304 } 00305 00306 usleep(10000); 00307 } 00308 } 00309 00310 00311 /////////////////////////// The SimulationViewer Service to init the retina and start as a deamon /////////////// 00312 class MissileLauncherService : public Ice::Service { 00313 protected: 00314 virtual bool start(int, char* argv[]); 00315 virtual bool stop() 00316 { 00317 if (itsMgr) 00318 delete itsMgr; 00319 return true; 00320 } 00321 private: 00322 Ice::ObjectAdapterPtr itsAdapter; 00323 ModelManager *itsMgr; 00324 }; 00325 00326 bool MissileLauncherService::start(int argc, char* argv[]) 00327 { 00328 00329 itsMgr = new ModelManager("MissileLauncherServiceService"); 00330 00331 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(*itsMgr)); 00332 itsMgr->addSubComponent(ofs); 00333 00334 nub::ref<MissileLauncher> missileLauncher(new MissileLauncher(*itsMgr, ofs)); 00335 itsMgr->addSubComponent(missileLauncher); 00336 00337 itsMgr->parseCommandLine((const int)argc, (const char**)argv, "", 0, 0); 00338 00339 char adapterStr[255]; 00340 sprintf(adapterStr, "default -p %i", BrainObjects::SimulationViewerPort); 00341 itsAdapter = communicator()->createObjectAdapterWithEndpoints( 00342 "SimulationViewerAdapter", adapterStr); 00343 00344 Ice::ObjectPtr object = missileLauncher.get(); 00345 Ice::ObjectPrx objectPrx = itsAdapter->add(object, communicator()->stringToIdentity("SimulationViewer"))->ice_oneway(); 00346 00347 missileLauncher->initSimEvents(communicator(), objectPrx); 00348 itsAdapter->activate(); 00349 00350 itsMgr->start(); 00351 00352 //Start the simulation viewer thread 00353 IceUtil::ThreadPtr svThread = missileLauncher.get(); 00354 svThread->start(); 00355 return true; 00356 } 00357 00358 00359 // ###################################################################### 00360 int main(int argc, char** argv) { 00361 00362 MissileLauncherService svc; 00363 return svc.main(argc, argv); 00364 } 00365