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 "Component/ModelManager.H"
00039 #include "Devices/RangeFinder.H"
00040 #include "Component/OptionManager.H"
00041 #include "Devices/Serial.H"
00042 #include "Devices/FrameGrabberConfigurator.H"
00043 #include "Devices/DeviceOpts.H"
00044 #include "Image/DrawOps.H"
00045 #include "Image/Image.H"
00046 #include "Image/ShapeOps.H"
00047 #include "Image/CutPaste.H"
00048 #include "Image/ImageCache.H"
00049 #include "Image/Pixels.H"
00050 #include "Image/MathOps.H"
00051 #include "Image/IO.H"
00052 #include "Image/Layout.H"
00053 #include "GUI/SDLdisplay.H"
00054 #include "GUI/GUIOpts.H"
00055 #include "Raster/Raster.H"
00056 #include "Media/FrameSeries.H"
00057 #include "Transport/FrameIstream.H"
00058 #include "Transport/FrameInfo.H"
00059 #include "Util/Timer.H"
00060 #include "Util/log.H"
00061 #include "Util/sformat.H"
00062 #include "Video/RgbConversion.H" 
00063 #include "Raster/DeBayer.H" 
00064 #include "Raster/PlaintextWriter.H"
00065 #include "Robots/LoBot/io/LoLaserRangeFinder.H"
00066 #include <pthread.h>
00067 #include <algorithm>
00068 #include <iterator>
00069 #include <queue>
00070 #include <fstream>
00071 #include <iostream>
00072 
00073 using namespace std;
00074 
00075 #define MAXSAVETHREAD 4
00076 std::vector<std::string> base;
00077 ImageCache<byte> cacheVideo;
00078 ImageCache<PixRGB<byte> > cacheLaserVid;
00079 std::queue<Image<int> > cacheLaser;
00080 pthread_mutex_t qmutex_cache,qmutex_timer, qmutex_laser;
00081 lobot::LaserRangeFinder* lrf = new lobot::LaserRangeFinder();
00082 bool haveLaser = false, haveFrames = false;
00083 uint frameNum = 0,laserNum=0;
00084 std::ofstream laserData, metaVideo, metaLaser;
00085 Timer tim;
00086 
00087 
00088 static void* saveLaser(void *arg)
00089 {
00090 
00091   while(1)
00092     {
00093       Image<int> dists;
00094       Image<int>::iterator aptr, stop;
00095       float rad;
00096       int  min,max;
00097       long int startAng;
00098       Image<PixRGB<byte> > laserImg(512,512,ZEROS);
00099       uint64 t;
00100 
00101       lrf->update();
00102       dists = lrf->get_distances();
00103       pthread_mutex_lock(&qmutex_laser);
00104       cacheLaser.push(dists);
00105       haveLaser = true;
00106       laserNum++;
00107 
00108       pthread_mutex_unlock(&qmutex_laser);
00109 
00110       
00111       const int w = dists.getWidth();
00112       const int h = dists.getHeight();
00113 
00114       Image<int>::const_iterator itr = dists.begin();
00115       for (int y = 0; y < h; ++y)
00116         {
00117           for (int x = 0; x < w; ++x)
00118             {
00119               laserData<<" "<<*itr;
00120               ++itr;
00121             }
00122           laserData<<"\n";
00123         }
00124 
00125       laserData<<"\n";
00126 
00127       t = tim.get();
00128       metaLaser<<t<<" \t"<<laserNum<<std::endl;
00129 
00130       
00131 
00132       if(!cacheLaser.empty())
00133         {
00134           dists = cacheLaser.front();
00135           cacheLaser.pop();
00136           haveLaser = false;
00137           aptr = dists.beginw();
00138           stop = dists.endw();
00139           startAng = -141;
00140 
00141           while(aptr!=stop)
00142             {
00143               rad = *aptr++;
00144               
00145               getMinMax(dists, min, max);
00146               rad = ((rad - min)/(max-min))*256;
00147 
00148               if (rad < 0)
00149                 rad =1;
00150 
00151               Point2D<int> pt;
00152               pt.i = 256 - (int) (rad*sin(startAng*M_PI/180.0));
00153               pt.j = 256 - (int) (rad*cos(startAng*M_PI/180.0));
00154 
00155               drawCircle(laserImg, pt, 3, PixRGB<byte>(255,0,0));
00156               drawLine(laserImg, Point2D<int>(256,256),pt,
00157                        PixRGB<byte>(0,255,0));
00158               startAng = startAng+1;
00159               if(startAng > 140)
00160                 startAng = -140;
00161             }
00162           pthread_mutex_lock(&qmutex_laser);
00163           cacheLaserVid.push_back(laserImg);
00164           pthread_mutex_unlock(&qmutex_laser);
00165         }
00166     }
00167 
00168   return NULL;
00169 }
00170 
00171 static void* saveFrames(void *arg)
00172 {
00173 
00174   while(1)
00175   {
00176 
00177     Image<byte> savImg;
00178     uint64 t;
00179     haveFrames = false;
00180     pthread_mutex_lock(&qmutex_cache);
00181     if(cacheVideo.size())
00182       {
00183         savImg = cacheVideo.pop_front();
00184         frameNum++;
00185 
00186         if(cacheVideo.size()) haveFrames = true;
00187 
00188         if (savImg.initialized())
00189           {
00190             const char *b = base[frameNum % (base.size()-3)].c_str();
00191             Raster::WriteGray(savImg, sformat("%s%06u.pgm", b, frameNum));
00192           }
00193         t = tim.get();
00194         metaVideo<<t<<"\t"<<frameNum<<std::endl;
00195       }
00196     pthread_mutex_unlock(&qmutex_cache);
00197     if(haveFrames == false) usleep(1000);
00198   }
00199 
00200   return NULL;
00201 }
00202 
00203 static int submain(const int argc, char** argv)
00204 {
00205   
00206   Image<byte> ima(640,480,ZEROS);
00207   pthread_t frameStreams[MAXSAVETHREAD], laserStream;
00208   uint64 t;
00209 
00210   
00211   ModelManager manager("locust recording camera + laser");
00212 
00213   nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00214   manager.addSubComponent(ofs);
00215 
00216   nub::soft_ref<FrameGrabberConfigurator>
00217   gbc(new FrameGrabberConfigurator(manager));
00218   manager.addSubComponent(gbc);
00219 
00220   manager.setOptionValString(&OPT_FrameGrabberType, "XC");
00221   manager.setOptionValString(&OPT_FrameGrabberDims, "640x478");
00222 
00223   
00224   if (manager.parseCommandLine(argc, argv, "<basename1> <basename2> <basename3> <basename 4>..<laserdatafile> <metaDataVideo> <metaDataLaser>",4, MAXSAVETHREAD+3) == false)
00225     return(1);
00226 
00227  
00228   nub::soft_ref<FrameIstream> gb = gbc->getFrameGrabber();
00229 
00230   if (gb.isInvalid())
00231     LFATAL("You need to have XC camera and XClibrary");
00232 
00233   
00234   for (uint i = 0; i < manager.numExtraArgs(); i ++)
00235     base.push_back(manager.getExtraArg(i));
00236 
00237   manager.start();
00238 
00239   
00240   gb->startStream();
00241 
00242   laserData.open(base[4].c_str(), ios::out | ios::ate);
00243   metaVideo.open(base[5].c_str(), ios::out | ios::ate);
00244   metaLaser.open(base[6].c_str(), ios::out | ios::ate);
00245 
00246   for(int ii = 0; ii<(int)base.size()-3; ii++)
00247     pthread_create(frameStreams+ii, NULL, &saveFrames, (void *)NULL);
00248 
00249   
00250   
00251   int rc2 = pthread_create(&laserStream, NULL, &saveLaser, NULL);
00252   if(rc2)
00253     {
00254       LFATAL("cannot create thread");
00255       exit(-1);
00256     }
00257 
00258   Image<PixRGB<byte> > laserImg(512,512,ZEROS);
00259 
00260   while(1)
00261   {
00262       
00263       ima = gb->readGray();
00264       laserImg.clear();
00265 
00266       pthread_mutex_lock(&qmutex_cache);
00267       cacheVideo.push_back(ima);
00268       pthread_mutex_unlock(&qmutex_cache);
00269 
00270       pthread_mutex_lock(&qmutex_laser);
00271       if(cacheLaserVid.size())
00272         laserImg = cacheLaserVid.pop_front();
00273       pthread_mutex_unlock(&qmutex_laser);
00274 
00275       Image<PixRGB<byte> > imgByte = ima;
00276       Layout<PixRGB<byte> >  dispLayout(imgByte);
00277       dispLayout = vcat(dispLayout,laserImg);
00278       
00279       
00280 
00281       ofs->writeRgbLayout(dispLayout,"Output",FrameInfo("output",SRC_POS));
00282 
00283       t = tim.get();
00284       if(t >5000)
00285         {
00286           laserData.close();
00287           metaVideo.close();
00288           metaLaser.close();
00289           manager.stop();
00290           exit(1);
00291         }
00292   }
00293 
00294         laserData.close();
00295         metaVideo.close();
00296         metaLaser.close();
00297         manager.stop();
00298 }
00299 
00300 
00301 
00302 extern "C" int main(const int argc, char** argv)
00303 {
00304   try
00305     {
00306       return submain(argc, argv);
00307     }
00308   catch (...)
00309     {
00310       REPORT_CURRENT_EXCEPTION;
00311     }
00312 
00313   return 1;
00314 }
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322