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>
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 {
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
00151 }
00152
00153 void imageCallback(const image::Header& header,
00154 void *userDataP)
00155 {
00156 Channel *channelP = reinterpret_cast<Channel*>(userDataP);
00157
00158
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 };
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
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
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
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
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
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
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
00276
00277 channelP->addIsolatedCallback(imageCallback, Source_All, channelP);
00278 channelP->addIsolatedCallback(laserCallback, channelP);
00279 channelP->addIsolatedCallback(ppsCallback, channelP);
00280
00281
00282
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 }