imi_Device.cpp
Go to the documentation of this file.
1 #include "imi_Device.h"
2 #include <boost/thread/thread.hpp>
3 #include <stdio.h>
4 #include <string>
5 #include "ImiProperties.h"
9 #include <ros/console.h>
10 
11 namespace imi_wrapper
12 {
13  static const double imi_factor = 1000.0;
14  static const double imi_cx = 316.2;
15  static const double imi_cy = 235.7;
16  static const double imi_fx = 565.0;
17  static const double imi_fy = 566.3;
18 
20  pDeviceAttr(NULL),
21  pImiDevice(NULL),
22  depthHandle(NULL),
23  colorHandle(NULL),
24  camHandle(NULL),
25  isDeviceValid(false),
26  color_video_started_(0),
27  depth_video_started_(0),
28  uvc_video_started_(0),
29  m_cx(imi_cx),
30  m_cy(imi_cy),
31  m_fx(imi_fx),
32  m_fy(imi_fy),
33  depthCallback(NULL),
34  colorCallback(NULL),
35  cloudCallback(NULL),
36  uvcCallback(NULL)
37  {
38 
39  }
40 
42  {
43  closeDevice();
44  }
45 
47  {
48  //boost::lock_guard<boost::mutex> lock(device_mutex_);
49  //1.imiInitialize()
50  if (0 != imiInitialize(NULL))
51  {
52  ROS_WARN("ImiNect Init Failed!\n");
53  return -1;
54  }
55  ROS_WARN("ImiNect Init Success.\n");
56 
57  uint32_t deviceCount = 0;
58  imiGetDeviceList(&pDeviceAttr, &deviceCount);
59  if (deviceCount <= 0 || NULL == pDeviceAttr)
60  {
61  ROS_WARN("Get No Connected Imidevice!\n");
62  return -1;
63  }
64  ROS_WARN("Get %d Connected Imidevice.\n", deviceCount);
65 
66  //3.imiOpenDevice()
67  if (0 != imiOpenDevice(pDeviceAttr[0].uri, &pImiDevice, 0))
68  {
69  ROS_WARN("Open Imidevice Failed!\n");
70  return -1;
71  }
72  ROS_INFO("Imidevice Opened.\n");
73 
74 
75  float cameraParams[4];
76  uint32_t nLen = sizeof(float)*4;
77  int32_t ret = imiGetDeviceProperty(pImiDevice, IMI_PROPERTY_COLOR_INTRINSIC_PARAMS, (void*)cameraParams, &nLen);
78  if (ret == 0)
79  {
80  m_fx = cameraParams[0];
81  m_fy = cameraParams[1];
82  m_cx = cameraParams[2];
83  m_cy = cameraParams[3];
84  }
85 
86  // ROS_INFO("****** fx=%f fy=%f cx=%f cy=%f\n", m_fx, m_fy, m_cx, m_cy);
87 
88  if (0 != imiCamOpen(&camHandle))
89  {
90  ROS_INFO("imiCamOpen Failed!\n");
91  return -1;
92  }
93 
94  ROS_INFO("imiCamOpen Success.\n");
95 
96  isDeviceValid = true;
97 
98  boost::thread depthThread(readFrame, this);
99 
100  boost::thread depthThreadUVC(readUVCFrame, this);
101 
102  return 0;
103  }
104 
105  void ImiDevice::convertToCloudPoint(ImiImageFrame* pFrame)
106  {
107  boost::shared_ptr<sensor_msgs::PointCloud2> cloudPtr(new sensor_msgs::PointCloud2);
108  cloudPtr->width = pFrame->height * pFrame->width;
109  cloudPtr->height = 1;
110 
111  cloudPtr->header.frame_id = "IMI_CloudPoints";
112 
113  sensor_msgs::PointCloud2Modifier modifier(*cloudPtr);
114  modifier.setPointCloud2Fields(3, "x", 1, sensor_msgs::PointField::FLOAT32,
115  "y", 1, sensor_msgs::PointField::FLOAT32,
116  "z", 1, sensor_msgs::PointField::FLOAT32);
117 
118  modifier.setPointCloud2FieldsByString(1, "xyz");
119 
120  sensor_msgs::PointCloud2Iterator<float> iter_x(*cloudPtr, "x");
121  sensor_msgs::PointCloud2Iterator<float> iter_y(*cloudPtr, "y");
122  sensor_msgs::PointCloud2Iterator<float> iter_z(*cloudPtr, "z");
123 
124  uint16_t* pData = (uint16_t *)pFrame->pData;
125  for (int j=0; j<pFrame->height; j++)
126  {
127  for (int i=0; i<pFrame->width; i++)
128  {
129  uint16_t dp = pData[j*pFrame->width + i];
130  if (dp > 0)
131  {
132  double pz = dp/imi_factor;
133  double py = (j - m_cy)*pz/m_fy;
134  double px = (i - m_cx)*pz/m_fx;
135 
136  *iter_x = px;
137  *iter_y = py;
138  *iter_z = pz;
139  }
140  else
141  {
142  *iter_x = 0;
143  *iter_y = 0;
144  *iter_z = 0;
145  }
146  ++iter_x;
147  ++iter_y;
148  ++iter_z;
149  }
150  }
151 
152  cloudCallback(cloudPtr);
153  }
154 
155  int ImiDevice::readFrame(void* lParam)
156  {
157  ImiDevice* pIMi = (ImiDevice *)lParam;
158 
159  while (pIMi->isDeviceValid)
160  {
161  if (!(pIMi->depth_video_started_>0 || pIMi->color_video_started_>0))
162  {
163  //ROS_WARN("wait for subscribers");
164  boost::this_thread::sleep(boost::posix_time::milliseconds(500));
165  continue;
166  }
167 
168  boost::lock_guard<boost::mutex> lock(pIMi->device_mutex_);
169 
170  int32_t g_streamNum = 0;
171  ImiStreamHandle g_streams[2];
172 
173  if (pIMi->depth_video_started_)
174  {
175  g_streams[g_streamNum++] = pIMi->depthHandle;
176  }
177 
178  if (pIMi->color_video_started_)
179  {
180  g_streams[g_streamNum++] = pIMi->colorHandle;
181  }
182 
183 
184  int32_t avStreamIndex;
185  if (0 != imiWaitForStreams(g_streams, g_streamNum, &avStreamIndex, 100))
186  {
187  boost::this_thread::sleep(boost::posix_time::milliseconds(50));
188  continue;
189  }
190 
191  if ((avStreamIndex < 0) || ((uint32_t)avStreamIndex >= g_streamNum))
192  {
193  ROS_WARN("imiWaitForStream returns 0, but channel index abnormal: %d\n", avStreamIndex);
194  continue;
195  }
196 
197  ImiImageFrame* pFrame = NULL;
198  if (0 != imiReadNextFrame(g_streams[avStreamIndex], &pFrame, 0))
199  {
200  ROS_WARN("imiReadNextFrame Failed, channel index : %d\n", avStreamIndex);
201  continue;
202  }
203 
204  sensor_msgs::ImagePtr image(new sensor_msgs::Image);
205 
206  if (pIMi->depthCallback!=NULL || (pIMi->colorCallback!=NULL && pFrame->pixelFormat==IMI_PIXEL_FORMAT_IMAGE_RGB24))
207  {
208 
209 
210  uint64_t device_time = pFrame->timeStamp;
211 
212  double device_time_in_sec = static_cast<double>(device_time) / 1000000.0;
213 
214  image->header.stamp.fromSec(device_time_in_sec);
215 
216  image->width = pFrame->width;
217  image->height = pFrame->height;
218 
219  std::size_t data_size = pFrame->size;
220 
221  image->data.resize(data_size);
222  memcpy(&image->data[0], pFrame->pData, data_size);
223 
224  image->is_bigendian = 0;
225  }
226 
227 
228  if (pFrame->pixelFormat==IMI_PIXEL_FORMAT_IMAGE_RGB24 && pIMi->colorCallback!=NULL)
229  {
230  image->header.frame_id = "IMI_RGB_Image";
231  image->encoding = sensor_msgs::image_encodings::RGB8;
232  image->step = sizeof(unsigned char) * 3 * image->width;
233 
234  pIMi->colorCallback(image);
235  }
236 
237  if (pFrame->pixelFormat == IMI_PIXEL_FORMAT_DEP_16BIT)
238  {
239 
240  if (pIMi->depthCallback != NULL)
241  {
242  image->header.frame_id = "IMI_DEPTH_Image";
244  image->step = sizeof(unsigned char) * 2 * image->width;
245  pIMi->depthCallback(image);
246  }
247 
248  if (pIMi->cloudCallback != NULL)
249  {
250  pIMi->convertToCloudPoint(pFrame);
251  }
252  }
253 
254  imiReleaseFrame(&pFrame);
255  }
256  }
257 
258  int ImiDevice::readUVCFrame(void* lParam)
259  {
260  ImiDevice* pIMi = (ImiDevice *)lParam;
261 
262  while (pIMi->isDeviceValid)
263  {
264  if (!(pIMi->uvc_video_started_>0))
265  {
266  //ROS_WARN("wait for uvc subscribers");
267  boost::this_thread::sleep(boost::posix_time::milliseconds(500));
268  continue;
269  }
270 
271  boost::lock_guard<boost::mutex> lock(pIMi->uvc_mutex_);
272 
273  ImiCameraFrame* uvcFrame = NULL;
274  int ret = imiCamReadNextFrame(pIMi->camHandle, &uvcFrame, 40);
275  if (ret!=0 || uvcFrame==NULL)
276  {
277  //ROS_WARN("imiCamReadNextFrame Failed\n");
278  continue;
279  }
280 
281 
282  sensor_msgs::ImagePtr image(new sensor_msgs::Image);
283 
284 
285  uint64_t device_time = uvcFrame->timeStamp;
286 
287  double device_time_in_sec = static_cast<double>(device_time) / 1000000.0;
288 
289  image->header.stamp.fromSec(device_time_in_sec);
290 
291 
292 
293  image->width = uvcFrame->width;
294  image->height = uvcFrame->height;
295 
296  std::size_t data_size = uvcFrame->size;
297 
298  image->data.resize(data_size);
299  memcpy(&image->data[0], uvcFrame->pData, data_size);
300 
301  image->is_bigendian = 0;
302 
303 
304  image->header.frame_id = "IMI_UVC_Image";
305  image->encoding = sensor_msgs::image_encodings::RGB8;
306  image->step = sizeof(unsigned char) * 3 * image->width;
307 
308  if (pIMi->uvcCallback != NULL)
309  {
310  pIMi->uvcCallback(image);
311  }
312 
313 
314  imiCamReleaseFrame(&uvcFrame);
315  }
316  }
317 
319  {
320  //boost::lock_guard<boost::mutex> lock(device_mutex_);
321  isDeviceValid = false;
322 
323  stopAllStreams();
324 
325  if (NULL != pImiDevice)
326  {
327  imiCloseDevice(pImiDevice);
328  pImiDevice = NULL;
329  }
330 
331  if (NULL != pDeviceAttr)
332  {
333  imiReleaseDeviceList(&pDeviceAttr);
334  pDeviceAttr = NULL;
335  }
336 
337  imiDestroy();
338 
339  if (NULL != camHandle)
340  {
341  imiCamClose(camHandle);
342  camHandle = NULL;
343  }
344  }
345 
346  sensor_msgs::CameraInfoPtr ImiDevice::getDefaultCameraInfo(int width, int height)
347  {
348  sensor_msgs::CameraInfoPtr info = boost::make_shared<sensor_msgs::CameraInfo>();
349 
350  info->width = width;
351  info->height = height;
352 
353  // distortion model and params
354  info->D.resize(5, 0.0);
355  info->distortion_model = sensor_msgs::distortion_models::PLUMB_BOB;
356 
357  // camera Params
358  info->K.assign(0.0);
359  info->K[0] = m_fx;
360  info->K[4] = m_fy;
361  info->K[2] = m_cx;
362  info->K[5] = m_cy;
363  info->K[8] = 1.0;
364 
365  // Rectification matrix (stereo cameras only)
366  info->R.assign(0.0);
367  info->R[0] = info->R[4] = info->R[8] = 1.0;
368 
369  // Projection/camera matrix
370  info->P.assign(0.0);
371  info->P[0] = m_fx;
372  info->P[5] = m_fy;
373  info->P[2] = m_cx;
374  info->P[6] = m_cy;
375  info->P[10] = 1.0;
376 
377  return info;
378  }
379 
380  const std::string ImiDevice::getUri() const
381  {
382  if (pDeviceAttr != NULL)
383  {
384  return std::string(pDeviceAttr[0].uri);
385  }
386 
387  return "";
388  }
389 
390  uint16_t ImiDevice::getUsbVendorId() const
391  {
392  if (pDeviceAttr != NULL)
393  {
394  return pDeviceAttr[0].vendorId;
395  }
396 
397  return 0;
398  }
399 
400  uint16_t ImiDevice::getUsbProductId() const
401  {
402  if (pDeviceAttr != NULL)
403  {
404  return pDeviceAttr[0].productId;
405  }
406 
407  return 0;
408  }
409 
410  bool ImiDevice::isValid() const
411  {
412  return isDeviceValid;
413  }
414 
416  {
417  return true;
418  }
419 
421  {
422  return true;
423  }
424 
426  {
427  return true;
428  }
429 
431  {
432  boost::lock_guard<boost::mutex> lock(device_mutex_);
433  colorCallback = callback;
434  }
435 
437  {
438  boost::lock_guard<boost::mutex> lock(uvc_mutex_);
439  uvcCallback = callback;
440  }
441 
443  {
444  boost::lock_guard<boost::mutex> lock(device_mutex_);
445  depthCallback = callback;
446  }
447 
449  {
450  boost::lock_guard<boost::mutex> lock(device_mutex_);
451  cloudCallback = callback;
452  }
453 
454  int ImiDevice::startColorStream(ImiFrameMode colorframeMode)
455  {
456  boost::lock_guard<boost::mutex> lock(device_mutex_);
458 
459  if (color_video_started_ > 1)
460  {
461  printf("already Open Color Stream Success.\n");
462  return 0;
463  }
464 
465  imiSetFrameMode(pImiDevice, IMI_COLOR_FRAME, &colorframeMode);
466 
467  if (0 != imiOpenStream(pImiDevice, IMI_COLOR_FRAME, NULL, NULL, &colorHandle))
468  {
469  ROS_WARN("Open Color Stream Failed!\n");
470  return -1;
471  }
472 
473  printf("Open Color Stream Success.\n");
474 
475  return 0;
476  }
477 
478  int ImiDevice::startUVCStream(ImiCameraFrameMode uvcframeMode)
479  {
480  boost::lock_guard<boost::mutex> lock(uvc_mutex_);
482 
483  if (uvc_video_started_ > 1)
484  {
485  ROS_WARN("already Open UVC Stream Success.\n");
486  return 0;
487  }
488 
489  if (0 != imiCamStartStream(camHandle, &uvcframeMode))
490  {
491  ROS_WARN("imiCamStartStream Failed!\n");
492  return -1;
493  }
494 
495  printf("Open UVC Stream Success.\n");
496 
497  return 0;
498  }
499 
500  int ImiDevice::startDepthStream(ImiFrameMode frameMode)
501  {
502  boost::lock_guard<boost::mutex> lock(device_mutex_);
504  if (depth_video_started_ > 1)
505  {
506  printf("already Open Depth Stream Success.\n");
507  return 0;
508  }
509 
510  imiSetFrameMode(pImiDevice, IMI_DEPTH_FRAME, &frameMode);
511 
512  if (frameMode.resolutionX==640 && frameMode.resolutionY==480)
513  {
514  m_cx = imi_cx;
515  m_cy = imi_cy;
516  m_fx = imi_fx;
517  m_fy = imi_fy;
518  }
519  else
520  {
521  m_cx = imi_cx/2;
522  m_cy = imi_cy/2;
523  m_fx = imi_fx/2;
524  m_fy = imi_fy/2;
525  }
526 
527  if (0 != imiOpenStream(pImiDevice, IMI_DEPTH_FRAME, NULL, NULL, &depthHandle))
528  {
529  ROS_WARN("Open Depth Stream Failed!\n");
530  return -1;
531  }
532 
533  printf("Open Depth Stream Success.\n");
534 
535  return 0;
536  }
537 
539  {
540  if (color_video_started_ > 0)
541  {
543  }
544 
545  stopColorStream();
546  if (depth_video_started_ > 0)
547  {
549  }
550 
551  stopDepthStream();
552 
553  if (uvc_video_started_ > 0)
554  {
555  uvc_video_started_ = 1;
556  }
557 
558  stopUVCStream();
559  }
560 
562  {
563  boost::lock_guard<boost::mutex> lock(device_mutex_);
564  if (color_video_started_ == 0)
565  {
566  return;
567  }
568 
570 
571  if (NULL != colorHandle && color_video_started_==0)
572  {
574  imiCloseStream(colorHandle);
575  colorHandle = NULL;
576  }
577  }
578 
580  {
581  boost::lock_guard<boost::mutex> lock(uvc_mutex_);
582  if (uvc_video_started_ == 0)
583  {
584  return;
585  }
586 
588 
589  if (NULL != camHandle && uvc_video_started_==0)
590  {
591  uvc_video_started_ = 0;
592  imiCamStopStream(camHandle);
593  }
594  }
595 
597  {
598  boost::lock_guard<boost::mutex> lock(device_mutex_);
599  if (depth_video_started_ == 0)
600  {
601  return;
602  }
603 
605  if (NULL != depthHandle && depth_video_started_==0)
606  {
608  imiCloseStream(depthHandle);
609  depthHandle = NULL;
610  }
611  }
612 
613 }
614 
ImiDeviceAttribute * pDeviceAttr
Definition: imi_Device.h:71
static const double imi_fx
Definition: imi_Device.cpp:16
static int readUVCFrame(void *lParam)
Definition: imi_Device.cpp:258
void setUVCFrameCallback(FrameCallbackFunction callback)
Definition: imi_Device.cpp:436
boost::mutex uvc_mutex_
Definition: imi_Device.h:70
ImiCameraHandle camHandle
Definition: imi_Device.h:76
FrameCallbackFunction depthCallback
Definition: imi_Device.h:83
ImiStreamHandle colorHandle
Definition: imi_Device.h:75
bool hasDepthSensor() const
Definition: imi_Device.cpp:425
static const double imi_cx
Definition: imi_Device.cpp:14
void convertToCloudPoint(ImiImageFrame *pFrame)
Definition: imi_Device.cpp:105
void setPointCloud2Fields(int n_fields,...)
const std::string getUri() const
Definition: imi_Device.cpp:380
bool isValid() const
Definition: imi_Device.cpp:410
#define ROS_WARN(...)
int startDepthStream(ImiFrameMode depthFrameMode)
Definition: imi_Device.cpp:500
int startColorStream(ImiFrameMode colorFrameMode)
Definition: imi_Device.cpp:454
boost::function< void(sensor_msgs::ImagePtr image)> FrameCallbackFunction
Definition: imi_Device.h:24
void setCloudPointCallback(CloudCallbackFunction callback)
Definition: imi_Device.cpp:448
static const double imi_fy
Definition: imi_Device.cpp:17
FrameCallbackFunction colorCallback
Definition: imi_Device.h:84
CloudCallbackFunction cloudCallback
Definition: imi_Device.h:85
ImiDeviceHandle pImiDevice
Definition: imi_Device.h:72
static const double imi_factor
Definition: imi_Device.cpp:13
FrameCallbackFunction uvcCallback
Definition: imi_Device.h:86
#define ROS_INFO(...)
boost::mutex device_mutex_
Definition: imi_Device.h:69
int startUVCStream(ImiCameraFrameMode uvcframeMode)
Definition: imi_Device.cpp:478
const std::string TYPE_16UC1
uint16_t getUsbVendorId() const
Definition: imi_Device.cpp:390
bool hasColorSensor() const
Definition: imi_Device.cpp:415
void setColorFrameCallback(FrameCallbackFunction callback)
Definition: imi_Device.cpp:430
sensor_msgs::CameraInfoPtr getDefaultCameraInfo(int width, int height)
Definition: imi_Device.cpp:346
void setDepthFrameCallback(FrameCallbackFunction callback)
Definition: imi_Device.cpp:442
static int readFrame(void *lParam)
Definition: imi_Device.cpp:155
boost::function< void(boost::shared_ptr< sensor_msgs::PointCloud2 > cloudPtr)> CloudCallbackFunction
Definition: imi_Device.h:25
uint16_t getUsbProductId() const
Definition: imi_Device.cpp:400
void setPointCloud2FieldsByString(int n_fields,...)
bool hasUVCSensor() const
Definition: imi_Device.cpp:420
static const double imi_cy
Definition: imi_Device.cpp:15
ImiStreamHandle depthHandle
Definition: imi_Device.h:74


imi_camera
Author(s): hjimi , HUAJIEIMI
autogenerated on Mon Jun 10 2019 13:32:59