DirectedStreamsUtility.cc
Go to the documentation of this file.
1 
38 #ifdef WIN32
39 #ifndef WIN32_LEAN_AND_MEAN
40 #define WIN32_LEAN_AND_MEAN 1
41 #endif
42 
43 #include <windows.h>
44 #include <winsock2.h>
45 #else
46 #include <unistd.h>
47 #include <arpa/inet.h> // htons
48 #endif
49 
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <signal.h>
53 #include <string.h>
54 #include <string>
55 #include <fstream>
56 #include <iostream>
57 #include <iomanip>
58 
60 
63 
64 using namespace crl::multisense;
65 
66 namespace { // anonymous
67 
68 volatile bool doneG = false;
69 
70 void usage(const char *programNameP)
71 {
72  std::cerr << "USAGE: " << programNameP << " [<options>]" << std::endl;
73  std::cerr << "Where <options> are:" << std::endl;
74  std::cerr << "\t-a <current_address> : CURRENT IPV4 address (default=10.66.171.21)" << std::endl;
75  std::cerr << "\t-d <decimation> : Decimation to apply for the directed streams (default=1)" << std::endl;
76 
77  exit(-1);
78 }
79 
80 #ifdef WIN32
81 BOOL WINAPI signalHandler(DWORD dwCtrlType)
82 {
83  std::cerr << "Shutting down on signal: CTRL-C" << std::endl;
84  doneG = true;
85  return TRUE;
86 }
87 #else
88 void signalHandler(int sig)
89 {
90  std::cerr << "Shutting down on signal: " << strsignal(sig) << std::endl;
91  doneG = true;
92 }
93 #endif
94 
95 bool savePgm(const std::string& fileName,
96  uint32_t width,
97  uint32_t height,
98  uint32_t bitsPerPixel,
99  const void *dataP)
100 {
101  std::ofstream outputStream(fileName.c_str(), std::ios::binary | std::ios::out);
102 
103  if (false == outputStream.good()) {
104  std::cerr << "Failed to open \"" << fileName << "\"" << std::endl;
105  return false;
106  }
107 
108  const uint32_t imageSize = height * width;
109 
110  switch(bitsPerPixel) {
111  case 8:
112  {
113 
114  outputStream << "P5\n"
115  << width << " " << height << "\n"
116  << 0xFF << "\n";
117 
118  outputStream.write(reinterpret_cast<const char*>(dataP), imageSize);
119 
120  break;
121  }
122  case 16:
123  {
124  outputStream << "P5\n"
125  << width << " " << height << "\n"
126  << 0xFFFF << "\n";
127 
128  const uint16_t *imageP = reinterpret_cast<const uint16_t*>(dataP);
129 
130  for (uint32_t i=0; i<imageSize; ++i) {
131  uint16_t o = htons(imageP[i]);
132  outputStream.write(reinterpret_cast<const char*>(&o), sizeof(uint16_t));
133  }
134 
135  break;
136  }
137  }
138 
139  outputStream.close();
140  return true;
141 }
142 
143 void ppsCallback(const pps::Header& header,
144  void *userDataP)
145 {
146  std::cerr << "PPS: " << header.sensorTime << " ns" << std::endl;
147 }
148 
149 void laserCallback(const lidar::Header& header,
150  void *userDataP)
151 {
152  double timeStamp = header.timeStartSeconds + 1e-6 * header.timeStartMicroSeconds;
153  static double lastTimeStamp = timeStamp;
154 
155  if (header.scanId % 100 == 0)
156  std::cout << "Laser Frequency " << (1 / (timeStamp - lastTimeStamp)) << std::endl;
157 
158  lastTimeStamp = timeStamp;
159 }
160 
161 void imageCallback(const image::Header& header,
162  void *userDataP)
163 {
164  Channel *channelP = reinterpret_cast<Channel*>(userDataP);
165 
166  double timeStamp = header.timeSeconds + 1e-6 * header.timeMicroSeconds;
167  static double lastTimeStamp = timeStamp;
168 
169  if (header.frameId % 100 == 0)
170  std::cout << "Left Image Frequency " << (1 / (timeStamp - lastTimeStamp)) << " "
171  << "Nominal Frequency " << header.framesPerSecond << std::endl;
172 
173  lastTimeStamp = timeStamp;
174 
175  static int64_t lastFrameId = -1;
176 
177  if (-1 == lastFrameId)
178  savePgm("left_rect.pgm",
179  header.width,
180  header.height,
181  header.bitsPerPixel,
182  header.imageDataP);
183 
184  lastFrameId = header.frameId;
185 
186  image::Histogram histogram;
187 
188  if (Status_Ok != channelP->getImageHistogram(header.frameId, histogram))
189  std::cerr << "failed to get histogram for frame " << header.frameId << std::endl;
190 }
191 
192 void disparityCallback(const image::Header& header,
193  void *userDataP)
194 {
195  Channel *channelP = reinterpret_cast<Channel*>(userDataP);
196 
197  double timeStamp = header.timeSeconds + 1e-6 * header.timeMicroSeconds;
198  static double lastTimeStamp = timeStamp;
199 
200  if (header.frameId % 100 == 0)
201  std::cout << "Disparity Frequency " << (1 / (timeStamp - lastTimeStamp)) << " "
202  << "Nominal Frequency " << header.framesPerSecond << std::endl;
203 
204  lastTimeStamp = timeStamp;
205 
206  static int64_t lastFrameId = -1;
207 
208  if (-1 == lastFrameId)
209  savePgm("disparity.pgm",
210  header.width,
211  header.height,
212  header.bitsPerPixel,
213  header.imageDataP);
214 
215  lastFrameId = header.frameId;
216 
217  image::Histogram histogram;
218 
219  if (Status_Ok != channelP->getImageHistogram(header.frameId, histogram))
220  std::cerr << "failed to get histogram for frame " << header.frameId << std::endl;
221 }
222 
223 }; // anonymous
224 
225 int main(int argc,
226  char **argvPP)
227 {
228  std::string currentAddress = "10.66.171.21";
229  int32_t mtu = 7200;
230  uint32_t decimation = 1;
231 
232 #if WIN32
233  SetConsoleCtrlHandler (signalHandler, TRUE);
234 #else
235  signal(SIGINT, signalHandler);
236 #endif
237 
238  //
239  // A directed stream to start
240  DirectedStream stream;
241 
242  //
243  // A vector to store the directed streams query
244  std::vector<DirectedStream> queryStreams;
245 
246  uint32_t streamIndex;
247 
248  //
249  // The port to stream data to
250  uint16_t port;
251 
252  //
253  // Parse args
254 
255  int c;
256 
257  while(-1 != (c = getopt(argc, argvPP, "a:m:d:")))
258  switch(c) {
259  case 'a': currentAddress = std::string(optarg); break;
260  case 'm': mtu = atoi(optarg); break;
261  case 'd': decimation = atoi(optarg); break;
262  default: usage(*argvPP); break;
263  }
264 
265  //
266  // Initialize communications.
267 
268  Channel *channelP = Channel::Create(currentAddress);
269  if (NULL == channelP) {
270  std::cerr << "Failed to establish communications with \"" << currentAddress << "\"" << std::endl;
271  return -1;
272  }
273 
274  //
275  // Query version
276 
277  Status status;
279 
280  status = channelP->getVersionInfo(v);
281  if (Status_Ok != status) {
282  std::cerr << "Failed to query sensor version: " << Channel::statusString(status) << std::endl;
283  goto clean_out;
284  }
285 
286  std::cout << "API build date : " << v.apiBuildDate << "\n";
287  std::cout << "API version : 0x" << std::hex << std::setw(4) << std::setfill('0') << v.apiVersion << "\n";
288  std::cout << "Firmware build date : " << v.sensorFirmwareBuildDate << "\n";
289  std::cout << "Firmware version : 0x" << std::hex << std::setw(4) << std::setfill('0') << v.sensorFirmwareVersion << "\n";
290  std::cout << "Hardware version : 0x" << std::hex << v.sensorHardwareVersion << "\n";
291  std::cout << "Hardware magic : 0x" << std::hex << v.sensorHardwareMagic << "\n";
292  std::cout << "FPGA DNA : 0x" << std::hex << v.sensorFpgaDna << "\n";
293  std::cout << std::dec;
294 
295  //
296  // Change framerate
297 
298  {
299  image::Config cfg;
300 
301  status = channelP->getImageConfig(cfg);
302  if (Status_Ok != status) {
303  std::cerr << "Failed to get image config: " << Channel::statusString(status) << std::endl;
304  goto clean_out;
305  } else {
306 
307  cfg.setResolution(1024, 544);
308  cfg.setFps(30.0);
309 
310  status = channelP->setImageConfig(cfg);
311  if (Status_Ok != status) {
312  std::cerr << "Failed to configure sensor: " << Channel::statusString(status) << std::endl;
313  goto clean_out;
314  }
315  }
316  }
317 
318  //
319  // Change MTU
320 
321  status = channelP->setMtu(mtu);
322  if (Status_Ok != status) {
323  std::cerr << "Failed to set MTU to " << mtu << ": " << Channel::statusString(status) << std::endl;
324  goto clean_out;
325  }
326 
327  //
328  // Change trigger source
329 
330  status = channelP->setTriggerSource(Trigger_Internal);
331  if (Status_Ok != status) {
332  std::cerr << "Failed to set trigger source: " << Channel::statusString(status) << std::endl;
333  goto clean_out;
334  }
335 
336  //
337  // Add callbacks
338 
339  channelP->addIsolatedCallback(imageCallback, Source_Luma_Rectified_Left, channelP);
340  channelP->addIsolatedCallback(disparityCallback, Source_Disparity, channelP);
341  channelP->addIsolatedCallback(laserCallback, channelP);
342  channelP->addIsolatedCallback(ppsCallback, channelP);
343 
344  //
345  // Get the local UDP port
346 
347  status = channelP->getLocalUdpPort(port);
348 
349  //
350  // Start streaming
351 
353 
354  status = channelP->startDirectedStream(stream);
355  if (Status_Ok != status) {
356  std::cerr << "Failed to start streams: " << Channel::statusString(status) << std::endl;
357  goto clean_out;
358  }
359 
360 
361  //
362  // Query all the active directed streams
363 
364  status = channelP->getDirectedStreams(queryStreams);
365 
366  for (streamIndex = 0 ; streamIndex < queryStreams.size() ; ++streamIndex) {
367  std::cout << "Directed Stream " << streamIndex << std::endl;
368  std::cout << "Address: " << queryStreams[streamIndex].address << std::endl;
369  std::cout << "Port: " << std::dec << queryStreams[streamIndex].udpPort << std::endl;
370  std::cout << "Mask: 0x" << std::hex << queryStreams[streamIndex].mask << std::endl;
371  std::cout << "Decimation: " << std::dec << queryStreams[streamIndex].fpsDecimation << std::endl;
372  std::cout << std::endl;
373  }
374 
375  while(!doneG)
376  usleep(100000);
377 
378  //
379  // Stop the directed streams
380 
381  status = channelP->stopDirectedStream(stream);
382  if (Status_Ok != status) {
383  std::cerr << "Failed to stop streams: " << Channel::statusString(status) << std::endl;
384  }
385 
386 clean_out:
387 
388  Channel::Destroy(channelP);
389  return 0;
390 }
virtual Status startDirectedStream(const DirectedStream &stream)=0
static const char * statusString(Status status)
Definition: channel.cc:609
static CRL_CONSTEXPR DataSource Source_Disparity
static CRL_CONSTEXPR TriggerSource Trigger_Internal
ros::Time * timeStamp(M &m)
virtual Status getDirectedStreams(std::vector< DirectedStream > &streams)=0
static Channel * Create(const std::string &sensorAddress)
Definition: channel.cc:583
virtual Status getImageHistogram(int64_t frameId, image::Histogram &histogram)=0
void setResolution(uint32_t w, uint32_t h)
virtual Status stopDirectedStream(const DirectedStream &stream)=0
virtual Status getVersionInfo(system::VersionInfo &v)=0
int getopt(int argc, char **argv, char *opts)
Definition: getopt.c:34
static CRL_CONSTEXPR DataSource Source_Lidar_Scan
virtual Status addIsolatedCallback(image::Callback callback, DataSource imageSourceMask, void *userDataP=NULL)=0
virtual Status setTriggerSource(TriggerSource s)=0
static CRL_CONSTEXPR Status Status_Ok
virtual Status getLocalUdpPort(uint16_t &port)=0
virtual Status setMtu(int32_t mtu)=0
virtual Status setImageConfig(const image::Config &c)=0
int main(int argc, char **argvPP)
def usage(progname)
static void Destroy(Channel *instanceP)
Definition: channel.cc:596
char * optarg
Definition: getopt.c:32
virtual Status getImageConfig(image::Config &c)=0
static CRL_CONSTEXPR DataSource Source_Luma_Rectified_Left


multisense_lib
Author(s):
autogenerated on Sat Apr 6 2019 02:16:46