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