00001 #include "Shared/RobotInfo.h"
00002 #if defined(TGT_HAS_CAMERA) || defined(TGT_HAS_WEBCAM)
00003
00004 #include "SegCam.h"
00005 #include "Wireless/Wireless.h"
00006 #include "Events/EventRouter.h"
00007 #include "Events/FilterBankEvent.h"
00008 #include "Behaviors/Controller.h"
00009 #include "Shared/ProjectInterface.h"
00010 #include "Vision/SegmentedColorGenerator.h"
00011 #include "Vision/RLEGenerator.h"
00012 #include "Shared/debuget.h"
00013
00014 REGISTER_BEHAVIOR_MENU_OPT(SegCam,"TekkotsuMon",BEH_NONEXCLUSIVE);
00015
00016 SegCam* SegCam::theOne=NULL;
00017
00018 SegCam::SegCam()
00019 : CameraStreamBehavior("SegCam",visRLE), visRLE(NULL), packet(NULL), cur(NULL), avail(0), max_buf(0), lastProcessedTime(0)
00020 {
00021 ASSERT(theOne==NULL,"there was already a SegCam running!");
00022 theOne=this;
00023 }
00024
00025 void
00026 SegCam::doStart() {
00027 BehaviorBase::doStart();
00028 setupServer();
00029 erouter->addListener(this,EventBase::visSegmentEGID,ProjectInterface::visSegmentSID,EventBase::deactivateETID);
00030 erouter->addListener(this,EventBase::visRLEEGID,ProjectInterface::visRLESID,EventBase::deactivateETID);
00031 }
00032
00033 void
00034 SegCam::doStop() {
00035 erouter->removeListener(this);
00036 closeServer();
00037 BehaviorBase::doStop();
00038 }
00039
00040 void
00041 SegCam::doEvent() {
00042 if(!wireless->isConnected(visRLE->sock))
00043 return;
00044 if( (config->vision.segcam.transport==0 && visRLE->getTransport()==Socket::SOCK_STREAM)
00045 || (config->vision.segcam.transport==1 && visRLE->getTransport()==Socket::SOCK_DGRAM) ) {
00046 closeServer();
00047 setupServer();
00048 return;
00049 }
00050 try {
00051 const FilterBankEvent* fbke=dynamic_cast<const FilterBankEvent*>(event);
00052 if(fbke==NULL) {
00053 CameraStreamBehavior::doEvent();
00054 return;
00055 }
00056 if ((get_time() - lastProcessedTime) < config->vision.segcam.interval)
00057 return;
00058 if(config->vision.segcam.compression==Config::vision_config::SegCamConfig::COMPRESS_NONE && event->getGeneratorID()==EventBase::visSegmentEGID) {
00059 if(!writeSeg(*fbke)) {
00060 if(packet!=NULL) {
00061 cur=packet;
00062 closePacket();
00063 }
00064
00065
00066 }
00067 }
00068 if(config->vision.segcam.compression==Config::vision_config::SegCamConfig::COMPRESS_RLE && event->getGeneratorID()==EventBase::visRLEEGID) {
00069 if(!writeRLE(*fbke)) {
00070 if(packet!=NULL) {
00071 cur=packet;
00072 closePacket();
00073 }
00074
00075
00076 }
00077 }
00078 } catch(...) {
00079 if(packet!=NULL) {
00080 cur=packet;
00081 closePacket();
00082 }
00083
00084 serr->printf("%s: exception generated during image serialization, stopping stream.\n",getName().c_str());
00085 stop();
00086 throw;
00087 }
00088 }
00089
00090 void
00091 SegCam::closeServer() {
00092 if(wireless->isConnected(visRLE->sock))
00093 sendCloseConnectionPacket();
00094 Controller::closeGUI("SegVisionGUI");
00095
00096
00097
00098 wireless->setDaemon(visRLE,false);
00099 wireless->close(visRLE->sock);
00100 }
00101
00102 void
00103 SegCam::setupServer() {
00104 std::vector<std::string> args;
00105 args.push_back("rle");
00106 char port[50];
00107 snprintf(port,50,"%d",*config->vision.segcam.port);
00108 args.push_back(port);
00109 if(config->vision.segcam.transport==0) {
00110 max_buf=UDP_WIRELESS_BUFFER_SIZE;
00111 visRLE=wireless->socket(Socket::SOCK_DGRAM, 1024, max_buf);
00112 args.push_back("udp");
00113 } else if(config->vision.segcam.transport==1) {
00114 max_buf=TCP_WIRELESS_BUFFER_SIZE;
00115 visRLE=wireless->socket(Socket::SOCK_STREAM, 1024, max_buf);
00116 args.push_back("tcp");
00117 } else {
00118 serr->printf("ERROR: Invalid Config::vision.segcam.transport: %d\n",*config->vision.segcam.transport);
00119 return;
00120 }
00121 wireless->setDaemon(visRLE,true);
00122 wireless->setReceiver(visRLE,networkCallback);
00123 wireless->listen(visRLE,config->vision.segcam.port);
00124
00125 Controller::loadGUI("org.tekkotsu.mon.VisionGUI","SegVisionGUI",config->vision.segcam.port,args);
00126 }
00127
00128 bool
00129 SegCam::openPacket(FilterBankGenerator& fbkgen, unsigned int time, unsigned int layer) {
00130 if(packet!=NULL)
00131 return false;
00132
00133 avail=max_buf-1;
00134 ASSERT(cur==NULL,"cur non-NULL");
00135 cur=NULL;
00136 char * buf=packet=(char*)visRLE->getWriteBuffer(avail);
00137 ASSERT(packet!=NULL,"dropped frame, network bandwidth is saturated (reduce frame rate or size)");
00138 if(packet==NULL)
00139 return false;
00140
00141 if(!LoadSave::encodeInc("TekkotsuImage",buf,avail,"ran out of space %s:%u\n",__FILE__,__LINE__)) return false;;
00142 if(!LoadSave::encodeInc(Config::vision_config::ENCODE_SINGLE_CHANNEL,buf,avail,"ran out of space %s:%u\n",__FILE__,__LINE__)) return false;;
00143 if(!LoadSave::encodeInc(Config::vision_config::SegCamConfig::COMPRESS_RLE,buf,avail,"ran out of space %s:%u\n",__FILE__,__LINE__)) return false;;
00144
00145 if(!LoadSave::encodeInc(fbkgen.getWidth(layer),buf,avail,"ran out of space %s:%u\n",__FILE__,__LINE__)) return false;;
00146 if(!LoadSave::encodeInc(fbkgen.getHeight(layer),buf,avail,"ran out of space %s:%u\n",__FILE__,__LINE__)) return false;;
00147 if(!LoadSave::encodeInc(time,buf,avail,"ran out of space %s:%u\n",__FILE__,__LINE__)) return false;;
00148 if(!LoadSave::encodeInc(fbkgen.getFrameNumber(),buf,avail,"ran out of space %s:%u\n",__FILE__,__LINE__)) return false;;
00149
00150 cur=buf;
00151 return true;
00152 }
00153
00154 bool
00155 SegCam::writeRLE(const FilterBankEvent& e) {
00156 FilterBankGenerator& fbkgen=*e.getSource();
00157
00158 unsigned int layer=fbkgen.getNumLayers()-1-config->vision.segcam.skip;
00159 openPacket(fbkgen,e.getTimeStamp(),layer);
00160 if(cur==NULL)
00161 return false;
00162
00163 RLEGenerator * rle = dynamic_cast<RLEGenerator*>(&fbkgen);
00164 ASSERTRETVAL(rle!=NULL,"fbkgen isn't an RLEGenerator",false);
00165
00166 rle->selectSaveImage(layer,config->vision.segcam.channel);
00167 if(!LoadSave::checkInc(rle->saveBuffer(cur,avail),cur,avail,"image size too large -- may need to set Config::vision.segcam.transport to TCP and reopen seg cam")) return false;
00168
00169
00170 const SegmentedColorGenerator * seg = dynamic_cast<const SegmentedColorGenerator*>(rle->getSourceGenerator());
00171 ASSERTRETVAL(seg!=NULL,"RLE's source is not a SegmentedColorGenerator - how do i know what the colors are?",false);
00172 if(!seg->encodeColorsInc(cur,avail)) return false;
00173
00174 closePacket();
00175
00176 return true;
00177 }
00178
00179 bool
00180 SegCam::writeSeg(const FilterBankEvent& e) {
00181 FilterBankGenerator& fbkgen=*e.getSource();
00182
00183 unsigned int layer=fbkgen.getNumLayers()-1-config->vision.segcam.skip;
00184 openPacket(fbkgen,e.getTimeStamp(),layer);
00185 if(cur==NULL)
00186 return false;
00187
00188 fbkgen.selectSaveImage(layer,config->vision.segcam.channel);
00189 if(!LoadSave::checkInc(fbkgen.saveBuffer(cur,avail),cur,avail,"image size too large -- may need to set Config::vision.segcam.transport to TCP and reopen seg cam")) return false;
00190
00191 closePacket();
00192
00193 return true;
00194 }
00195
00196 void
00197 SegCam::closePacket() {
00198 if(packet==NULL)
00199 return;
00200 visRLE->write(cur-packet);
00201 packet=cur=NULL;
00202 avail=0;
00203 lastProcessedTime = get_time();
00204 }
00205
00206 bool
00207 SegCam::sendCloseConnectionPacket() {
00208 char msg[]="CloseConnection";
00209 unsigned int len=strlen(msg)+LoadSave::stringpad;
00210 char * buf = (char*)visRLE->getWriteBuffer(len);
00211 if(buf==NULL) {
00212 std::cerr << "Could not get buffer for closing packet" << std::endl;
00213 return false;
00214 }
00215 unsigned int used=LoadSave::encode(msg,buf,len);
00216 if(used==0)
00217 std::cerr << "Could not write close packet" << std::endl;
00218 visRLE->write(used);
00219 return true;
00220 }
00221
00222 #endif
00223
00224
00225
00226
00227
00228