SaveImageUtility.cc
Go to the documentation of this file.
00001 
00037 #ifdef WIN32
00038 #ifndef WIN32_LEAN_AND_MEAN
00039 #define WIN32_LEAN_AND_MEAN 1
00040 #endif
00041 
00042 #include <windows.h>
00043 #include <winsock2.h>
00044 #else
00045 #include <unistd.h>
00046 #include <arpa/inet.h> // htons
00047 #endif
00048 
00049 #include <stdio.h>
00050 #include <stdlib.h>
00051 #include <signal.h>
00052 #include <string.h>
00053 #include <string>
00054 #include <fstream>
00055 #include <iostream>
00056 #include <iomanip>
00057 
00058 #include <Utilities/portability/getopt/getopt.h>
00059 
00060 #include <LibMultiSense/details/utility/Portability.hh>
00061 #include <LibMultiSense/MultiSenseChannel.hh>
00062 
00063 using namespace crl::multisense;
00064 
00065 namespace {  // anonymous
00066 
00067 volatile bool doneG = false;
00068 
00069 void usage(const char *programNameP) 
00070 {
00071         std::cerr << "USAGE: " << programNameP << " [<options>]" << std::endl;
00072     std::cerr << "Where <options> are:" << std::endl;
00073         std::cerr << "\t-a <current_address>    : CURRENT IPV4 address (default=10.66.171.21)" << std::endl;
00074     
00075     exit(-1);
00076 }
00077 
00078 #ifdef WIN32
00079 BOOL WINAPI signalHandler(DWORD dwCtrlType)
00080 {
00081         std::cerr << "Shutting down on signal: CTRL-C" << std::endl;
00082     doneG = true;
00083     return TRUE;
00084 }
00085 #else
00086 void signalHandler(int sig)
00087 {
00088         std::cerr << "Shutting down on signal: " << strsignal(sig) << std::endl;
00089     doneG = true;
00090 }
00091 #endif
00092 
00093 bool savePgm(const std::string& fileName,
00094              uint32_t           width,
00095              uint32_t           height,
00096              uint32_t           bitsPerPixel,
00097              const void        *dataP)
00098 {
00099     std::ofstream outputStream(fileName.c_str(), std::ios::binary | std::ios::out);
00100     
00101     if (false == outputStream.good()) {
00102                 std::cerr << "Failed to open \"" << fileName << "\"" << std::endl;
00103         return false;
00104     }
00105 
00106     const uint32_t imageSize = height * width;
00107 
00108     switch(bitsPerPixel) {
00109     case 8: 
00110     {
00111 
00112         outputStream << "P5\n"
00113                      << width << " " << height << "\n"
00114                      << 0xFF << "\n";
00115         
00116         outputStream.write(reinterpret_cast<const char*>(dataP), imageSize);
00117 
00118         break;
00119     }
00120     case 16:
00121     {
00122         outputStream << "P5\n"
00123                      << width << " " << height << "\n"
00124                      << 0xFFFF << "\n";
00125 
00126         const uint16_t *imageP = reinterpret_cast<const uint16_t*>(dataP);
00127         
00128         for (uint32_t i=0; i<imageSize; ++i) {
00129             uint16_t o = htons(imageP[i]);
00130             outputStream.write(reinterpret_cast<const char*>(&o), sizeof(uint16_t));
00131         }
00132 
00133         break;
00134     }
00135     }
00136         
00137     outputStream.close();
00138     return true;
00139 }
00140 
00141 void ppsCallback(const pps::Header& header,
00142                  void              *userDataP)
00143 {
00144         std::cerr << "PPS: " << header.sensorTime << " ns" << std::endl;
00145 }                
00146 
00147 void laserCallback(const lidar::Header& header,
00148                    void                *userDataP)
00149 {
00150 //      std::cerr << "lidar: " << header.pointCount << std::endl;
00151 }
00152 
00153 void imageCallback(const image::Header& header,
00154                    void                *userDataP)
00155 {
00156     Channel *channelP = reinterpret_cast<Channel*>(userDataP);
00157     
00158 //    double timeStamp = header.timeSeconds + 1e-6 * header.timeMicroSeconds;
00159     
00160     static int64_t lastFrameId = -1;
00161 
00162     if (-1 == lastFrameId)
00163         savePgm("test.pgm",
00164                 header.width,
00165                 header.height,
00166                 header.bitsPerPixel,
00167                 header.imageDataP);
00168 
00169     lastFrameId = header.frameId;
00170 
00171     image::Histogram histogram;
00172 
00173         if (Status_Ok != channelP->getImageHistogram(header.frameId, histogram))
00174                 std::cerr << "failed to get histogram for frame " << header.frameId << std::endl;
00175 }
00176 
00177 }; // anonymous
00178 
00179 int main(int    argc, 
00180          char **argvPP)
00181 {
00182     std::string currentAddress = "10.66.171.21";
00183     int32_t mtu = 7200;
00184 
00185 #if WIN32
00186     SetConsoleCtrlHandler (signalHandler, TRUE);
00187 #else
00188     signal(SIGINT, signalHandler);
00189 #endif
00190 
00191     //
00192     // Parse args
00193 
00194     int c;
00195 
00196     while(-1 != (c = getopt(argc, argvPP, "a:m:")))
00197         switch(c) {
00198         case 'a': currentAddress = std::string(optarg);    break;
00199         case 'm': mtu            = atoi(optarg);           break;
00200         default: usage(*argvPP);                           break;
00201         }
00202 
00203     //
00204     // Initialize communications.
00205 
00206     Channel *channelP = Channel::Create(currentAddress);
00207     if (NULL == channelP) {
00208                 std::cerr << "Failed to establish communications with \"" << currentAddress << "\"" << std::endl;
00209         return -1;
00210     }
00211 
00212     //
00213     // Query version
00214 
00215     Status status;
00216     system::VersionInfo v;
00217 
00218     status = channelP->getVersionInfo(v);
00219     if (Status_Ok != status) {
00220                 std::cerr << "Failed to query sensor version: " << Channel::statusString(status) << std::endl;
00221         goto clean_out;
00222     }
00223 
00224         std::cout << "API build date      :  " << v.apiBuildDate << "\n";
00225     std::cout << "API version         :  0x" << std::hex << std::setw(4) << std::setfill('0') << v.apiVersion << "\n";
00226         std::cout << "Firmware build date :  " << v.sensorFirmwareBuildDate << "\n";
00227         std::cout << "Firmware version    :  0x" << std::hex << std::setw(4) << std::setfill('0') << v.sensorFirmwareVersion << "\n";
00228         std::cout << "Hardware version    :  0x" << std::hex << v.sensorHardwareVersion << "\n";
00229         std::cout << "Hardware magic      :  0x" << std::hex << v.sensorHardwareMagic << "\n";
00230         std::cout << "FPGA DNA            :  0x" << std::hex << v.sensorFpgaDna << "\n";
00231         std::cout << std::dec;
00232 
00233     //
00234     // Change framerate
00235 
00236     {
00237         image::Config cfg;
00238 
00239         status = channelP->getImageConfig(cfg);
00240         if (Status_Ok != status) {
00241                         std::cerr << "Failed to get image config: " << Channel::statusString(status) << std::endl;
00242             goto clean_out;
00243         } else {
00244 
00245             cfg.setResolution(1024, 544);
00246             cfg.setFps(30.0);
00247         
00248             status = channelP->setImageConfig(cfg);
00249             if (Status_Ok != status) {
00250                                 std::cerr << "Failed to configure sensor: " << Channel::statusString(status) << std::endl;
00251                 goto clean_out;
00252             }
00253         }
00254     }
00255 
00256     //
00257     // Change MTU
00258 
00259     status = channelP->setMtu(mtu);
00260     if (Status_Ok != status) {
00261                 std::cerr << "Failed to set MTU to " << mtu << ": " << Channel::statusString(status) << std::endl;
00262         goto clean_out;
00263     }
00264 
00265     //
00266     // Change trigger source
00267 
00268     status = channelP->setTriggerSource(Trigger_Internal);
00269     if (Status_Ok != status) {
00270                 std::cerr << "Failed to set trigger source: " << Channel::statusString(status) << std::endl;
00271         goto clean_out;
00272     }
00273 
00274     //
00275     // Add callbacks
00276 
00277     channelP->addIsolatedCallback(imageCallback, Source_All, channelP);
00278     channelP->addIsolatedCallback(laserCallback, channelP);
00279     channelP->addIsolatedCallback(ppsCallback, channelP);
00280 
00281     //
00282     // Start streaming
00283 
00284     status = channelP->startStreams(Source_Luma_Rectified_Left | Source_Lidar_Scan);
00285     if (Status_Ok != status) {
00286                 std::cerr << "Failed to start streams: " << Channel::statusString(status) << std::endl;
00287         goto clean_out;
00288     }
00289 
00290     while(!doneG)
00291         usleep(100000);
00292 
00293     status = channelP->stopStreams(Source_All);
00294     if (Status_Ok != status) {
00295                 std::cerr << "Failed to stop streams: " << Channel::statusString(status) << std::endl;
00296     }
00297 
00298 clean_out:
00299 
00300     Channel::Destroy(channelP);
00301     return 0;
00302 }


multisense_lib
Author(s):
autogenerated on Thu Aug 27 2015 14:01:11