00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
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
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
00128 Ice::ObjectPrx obj = icPtr->stringToProxy("SimEvents/TopicManager:tcp -p 11111");
00129 IceStorm::TopicManagerPrx topicManager =
00130 IceStorm::TopicManagerPrx::checkedCast(obj);
00131
00132
00133 itsObjectPrx = objectPrx;
00134
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());
00141 itsTopicsSubscriptions[i].topicPrx->subscribeAndGetPublisher(qos, itsObjectPrx);
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
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
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)
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
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
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,
00243 5000);
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
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
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