00001 #include "Shared/RobotInfo.h"
00002 #if defined(TGT_HAS_CAMERA) || defined(TGT_HAS_WEBCAM)
00003
00004 #include "RegionCam.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/RegionGenerator.h"
00012 #include "Shared/debuget.h"
00013
00014 REGISTER_BEHAVIOR_MENU_OPT(RegionCam,"TekkotsuMon",BEH_NONEXCLUSIVE);
00015
00016 RegionCam::RegionCam()
00017 : BehaviorBase("RegionCam"), visRegion(NULL), packet(NULL), cur(NULL), avail(0), max_buf(0)
00018 {
00019 }
00020
00021 void
00022 RegionCam::doStart() {
00023 BehaviorBase::doStart();
00024 setupServer();
00025 erouter->addListener(this,EventBase::visRegionEGID,ProjectInterface::visRegionSID,EventBase::deactivateETID);
00026 }
00027
00028 void
00029 RegionCam::doStop() {
00030 erouter->removeListener(this);
00031 closeServer();
00032 BehaviorBase::doStop();
00033 }
00034
00035 void
00036 RegionCam::doEvent() {
00037 if(!wireless->isConnected(visRegion->sock))
00038 return;
00039 if( (config->vision.regioncam.transport==0 && visRegion->getTransport()==Socket::SOCK_STREAM)
00040 || (config->vision.regioncam.transport==1 && visRegion->getTransport()==Socket::SOCK_DGRAM) ) {
00041 closeServer();
00042 setupServer();
00043 return;
00044 }
00045 const FilterBankEvent* fbke=dynamic_cast<const FilterBankEvent*>(event);
00046 ASSERTRET(fbke!=NULL,"unexpected event");
00047 #if DEBUG
00048 bool succ=writeRegions(*fbke);
00049 ASSERTRET(succ,"serialization failed");
00050 #else
00051 writeRegions(*fbke);
00052 #endif
00053 }
00054
00055 void
00056 RegionCam::closeServer() {
00057 Controller::closeGUI("RegionVisionGUI");
00058
00059
00060
00061 wireless->setDaemon(visRegion,false);
00062 wireless->close(visRegion->sock);
00063 }
00064
00065 void
00066 RegionCam::setupServer() {
00067 std::vector<std::string> args;
00068 args.push_back("reg");
00069 char port[50];
00070 snprintf(port,50,"%d",*config->vision.regioncam.port);
00071 args.push_back(port);
00072 if(config->vision.regioncam.transport==0) {
00073 max_buf=UDP_WIRELESS_BUFFER_SIZE;
00074 visRegion=wireless->socket(Socket::SOCK_DGRAM, 1024, max_buf);
00075 args.push_back("udp");
00076 } else if(config->vision.regioncam.transport==1) {
00077 max_buf=TCP_WIRELESS_BUFFER_SIZE;
00078 visRegion=wireless->socket(Socket::SOCK_STREAM, 1024, max_buf);
00079 wireless->setDaemon(visRegion,true);
00080 args.push_back("tcp");
00081 } else {
00082 serr->printf("ERROR: Invalid Config::vision.region_transport: %d\n",*config->vision.regioncam.transport);
00083 return;
00084 }
00085 wireless->listen(visRegion,config->vision.regioncam.port);
00086 Controller::loadGUI("org.tekkotsu.mon.VisionGUI","RegionVisionGUI",config->vision.regioncam.port,args);
00087 }
00088
00089 bool
00090 RegionCam::openPacket(FilterBankGenerator& fbkgen, unsigned int time, unsigned int layer) {
00091 if(packet!=NULL)
00092 return false;
00093
00094 avail=max_buf-1;
00095 ASSERT(cur==NULL,"cur non-NULL");
00096 cur=NULL;
00097 char * buf=packet=(char*)visRegion->getWriteBuffer(avail);
00098 ASSERT(packet!=NULL,"could not get buffer");
00099 if(packet==NULL)
00100 return false;
00101
00102 if(!LoadSave::encodeInc("TekkotsuImage",buf,avail,"ran out of space %s:%un",__FILE__,__LINE__)) return false;;
00103 if(!LoadSave::encodeInc(Config::vision_config::ENCODE_SINGLE_CHANNEL,buf,avail,"ran out of space %s:%un",__FILE__,__LINE__)) return false;;
00104 if(!LoadSave::encodeInc(Config::vision_config::SegCamConfig::COMPRESS_RLE,buf,avail,"ran out of space %s:%un",__FILE__,__LINE__)) return false;;
00105
00106 if(!LoadSave::encodeInc(fbkgen.getWidth(layer),buf,avail,"ran out of space %s:%un",__FILE__,__LINE__)) return false;;
00107 if(!LoadSave::encodeInc(fbkgen.getHeight(layer),buf,avail,"ran out of space %s:%un",__FILE__,__LINE__)) return false;;
00108 if(!LoadSave::encodeInc(time,buf,avail,"ran out of space %s:%un",__FILE__,__LINE__)) return false;;
00109 if(!LoadSave::encodeInc(fbkgen.getFrameNumber(),buf,avail,"ran out of space %s:%un",__FILE__,__LINE__)) return false;;
00110
00111 cur=buf;
00112 return true;
00113 }
00114
00115 bool
00116 RegionCam::writeRegions(const FilterBankEvent& e) {
00117 FilterBankGenerator& fbkgen=*e.getSource();
00118
00119 unsigned int layer=fbkgen.getNumLayers()-1-config->vision.regioncam.skip;
00120 openPacket(fbkgen,e.getTimeStamp(),layer);
00121 ASSERTRETVAL(cur!=NULL,"header failed",false);
00122
00123 RegionGenerator * regGen = dynamic_cast<RegionGenerator*>(&fbkgen);
00124 ASSERTRETVAL(regGen!=NULL,"fbkgen isn't an RegionGenerator",false);
00125
00126 regGen->selectSaveImage(layer,config->vision.segcam.channel);
00127 if(!LoadSave::checkInc(regGen->saveBuffer(cur,avail),cur,avail,"save region image failed")) return false;
00128
00129 const SegmentedColorGenerator * seg = dynamic_cast<const SegmentedColorGenerator*>((regGen->getSourceGenerator())->getSourceGenerator());
00130 ASSERTRETVAL(seg!=NULL,"The source of RegionGenerator's source is not a SegmentedColorGenerator - how do i know what the colors are?",false);
00131 if(!seg->encodeColorsInc(cur,avail)) return false;
00132
00133 closePacket();
00134
00135 return true;
00136 }
00137
00138
00139 void
00140 RegionCam::closePacket() {
00141 if(packet==NULL)
00142 return;
00143 visRegion->write(cur-packet);
00144 packet=cur=NULL;
00145 avail=0;
00146 }
00147
00148 #endif
00149
00150
00151
00152
00153
00154