Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
VideoSource_SwissRanger.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5 Multimediale Systeme der Informationsverarbeitung
6 Institut fuer Informatik
7 Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #ifdef _WIN32
26 #pragma comment( lib, "libMesaSR.lib" )
27 #endif
28 
29 
30 //THE header
31 #include "VideoSource_SwissRanger.hh"
32 
33 //std stuff
34 #include <string>
35 #include <sstream>
36 #include <iostream>
37 
38 //BIAS stuff
39 #include <Image/Camera.hh>
40 #include <Base/Image/ImageConvert.hh>
41 #include <Base/Image/ImageIO.hh>
42 
43 
44 //mesa swissranger stuff
45 #include <libMesaSR.h>
46 
47 #ifndef WIN32
48 #include <usb.h>
49 #endif
50 
51 using namespace BIAS;
52 using namespace std;
53 
54 
57 {
58  //for VideoSource-class
59  VideoSource::SetSize(-1,-1,1);
61  Width_ = -1;
62  Height_ = -1;
63  srCam_ = NULL;
64  bIsOpen_ = false;
65  serialNumber_=0;
68  integrationTime_ = 80;
69  distanceOffset_ = 0;
70  modulationFrequency_ = MF_20MHz;
71  bEnsureLatestFrame_=false;
72  dataDepth_ = NULL;
73  dataAmp_ = NULL;
75  camType_ = CT_UNKNOWN;
76  bRetryOpen_ = false;
77 }
78 
81 {
82  if (bIsOpen_) CloseDevice();
83 }
84 
86 GetSoftwareVersion(std::string& version){
87  unsigned short v[4];
88  int ret = SR_GetVersion(v);
89  stringstream ver;
90  ver<<v[3]<<"."<<v[2]<<"."<<v[1]<<"."<<v[0];
91  version = ver.str();
92  return ret;
93 }
94 
96 GetDeviceString(std::string &device){
97  if(srCam_== NULL) return -1;
98  char buf[100];
99  int ret = SR_GetDeviceString(srCam_,buf,100);
100  device = string(buf);
101  return ret;
102 }
103 
106 {
107  int ret = 0;
108  if (bIsOpen_) {
109  BIASERR("Device SwissRanger has been opened already.");
110  return -1;
111  }
112  string version;
113  ret = GetSoftwareVersion(version);
114 #ifdef BIAS_DEBUG
115  cout<<"SRMesa Software Version:"<<version<<endl;
116 #endif
117 
118  //SR_SetTimeout(srCam_,20000);
119  //ret = SR_OpenDlg(&srCam_,2,0);
120  ret = SR_OpenUSB(&srCam_,serialNumber_);
121 
122  if ( ret <= 0) {
123  if (bRetryOpen_) {
124  BIASERR("OpenDevice of Swissranger not successfull (return:"<< ret<<") try to reopen.")
125  bRetryOpen_ = false;
126  CloseDevice();
127  ResetUsbDeviceConnection_();
128  return OpenDevice();
129  } else {
130  BIASERR("Could not open the SwissRanger device (return:"<< ret<<")!");
131  return -1;
132  }
133  }
134 
135  Width_ = SR_GetCols(srCam_);
136  Height_ = SR_GetRows(srCam_);
137 
138  if (Width_ < 10) {
139  if (bRetryOpen_) {
140  BIASERR("Image dimension of Swissranger not correct, try to reopen.")
141  bRetryOpen_ = false;
142  CloseDevice();
143  ResetUsbDeviceConnection_();
144  return OpenDevice();
145  } else {
146  BIASERR("Connection to Swissranger is not sane. Please restart.");
147  return -2;
148  }
149  }
150 
151  ColorChannels_ = 1;
152 
153  int numPics = 0;
154  numPics = SR_GetImageList(srCam_,&imgEntryArray);
155 
156  ImgEntry entr;
157  for(int i = 0; i < numPics; i++){
158  entr = imgEntryArray[i];
159  #ifdef BIAS_DEBUG
160  cout << "ImageType: " << entr.imgType << endl;
161  #endif
162  }
163 
164 
165  DepthImg_.Init(Width_, Height_, 1, ImageBase::ST_unsignedchar);
166  DepthImg_.SetColorModel(ImageBase::CM_Grey);
167  DepthImgF_.Init(Width_, Height_, 1, ImageBase::ST_float);
168  DepthImgF_.SetColorModel(ImageBase::CM_Grey);
169 
170  ModCoeffImg_.Init(Width_, Height_, 1, ImageBase::ST_float);
171  ModCoeffImg_.SetColorModel(ImageBase::CM_Grey);
172 
173  SR_SetIntegrationTime(srCam_,integrationTime_);
174  //if(modulationFrequency_ != MF_20MHz)
175  ret = SR_SetModulationFrequency(srCam_,modulationFrequency_);
176  if(ret != 0) BIASERR("Setting modulation Frequency failed.");
177  modulationFrequency_ = SR_GetModulationFrequency(srCam_);
178  SetMaxDist_();
179 
180  // api provides access to get device string, but lacks obviously needed get cam type
181  string devstring; GetDeviceString(devstring);
182  if (devstring.find("SR3000") != string::npos) {
183  camType_ = CT_SR3K_USB;
184  } else {
185  camType_ = CT_SR4K_USB;
186  }
187 
188  if(bExternalTrigger_){
189  #ifdef BIAS_DEBUG
190  cout<<"SR Setting mode with Trigger!"<<endl;
191  #endif
192  ret = SR_SetMode(srCam_,AM_COR_FIX_PTRN|AM_MEDIAN|AM_DENOISE_ANF|AM_CONV_GRAY|AM_HW_TRIGGER|AM_SW_TRIGGER);
193  }
194  else{
195  //if AM_SW_TRIGGER (SOFTWARE TRIGGER) is set, fps are reduced, because taking image starts by call to SR_ACQUIRE
196  //still better than ensure latest!
197  #ifdef BIAS_DEBUG
198  cout<<"SR Setting normal mode!"<<endl;
199  #endif
200  ret = SR_SetMode(srCam_,AM_COR_FIX_PTRN|AM_MEDIAN|AM_CONV_GRAY|AM_DENOISE_ANF);
201  }
202 
203  if (ret < 0) {
204  BIASERR("Opening Swissranger failed!");
205  return ret;
206  }
207 
208  bIsOpen_ = true;
209  return 0;
210 }
211 
213 OpenDevice(int camNr)
214 {
215  serialNumber_= camNr;
216  return OpenDevice();
217 }
218 
221 {
222  if (SR_Close(srCam_) < 0) {
223  BIASERR("Disonnection of Swiss Ranger via USB failed!");
224  return -1;
225  }
226 
227  bIsOpen_ = false;
228  //cout<<"Closed Swissranger Camera"<<endl;
229  return 0;
230 }
231 
233 SetIntegrationTimeMS(float inttime) {
234  float val = 0.0f;
235  switch (camType_) {
236  case CT_SR3K_ETH:
237  case CT_SR3K_USB:
238  val = 0.25f * ((inttime / 0.2f) - 1.0f);
239  break;
240  case CT_SR4K_ETH:
241  case CT_SR4K_USB:
242  val = 0.25f * ((inttime - 0.3f) / 0.1f);
243  break;
244  default:
245  BIASERR("can not set integration time as camera type is unknown.");
246  return -1;
247  }
248  if (val < 0 || val > 255) {
249  BIASWARN("clipping integration time");
250  }
251  return SetIntegrationTime( (unsigned char)val );
252 }
253 
255 GetIntegrationTimeMS(float &inttime) {
256  switch (camType_) {
257  case CT_SR3K_ETH:
258  case CT_SR3K_USB:
259  inttime = 4.0f * float(integrationTime_+1.0f)*0.2f;
260  break;
261  case CT_SR4K_ETH:
262  case CT_SR4K_USB:
263  inttime = 4.0f * (0.3f+float(integrationTime_)*0.1f);
264  break;
265  default:
266  BIASERR("can not set integration time as camera type is unknown.");
267  return -1;
268  }
269  return 0;
270 }
271 
272 
275 {
276  return 0;
277 }
278 
279 
282 {
283  return 0;
284 }
285 
288  if (!img.IsEmpty()){
289  BIASERR("VideoSource::InitImage() should be called with uninitialized image");
290  img.Release();
291  }
292  img.Init(Width_, Height_, ColorChannels_, ImageBase::ST_unsignedchar);
294  return 0;
295 }
296 
299  if (!img.IsEmpty()){
300  BIASERR("VideoSource::InitImage() should be called with uninitialized image");
301  img.Release();
302  }
303  img.Init(Width_, Height_, 1, ImageBase::ST_float);
305  return 0;
306 }
307 
308 
311 {
312  int res=0;
313 
314  if (!bIsOpen_) {
315  BIASERR("GrabSingle called but device not opened!");
316  return -1;
317  }
318 
319  res=SR_Acquire(srCam_);
320 
321  if(bEnsureLatestFrame_)
322  res+=SR_Acquire(srCam_);
323 
324  if (res<=0) {
325  if(bExternalTrigger_){
326  BIASERR("Reading image from SwissRanger failed. Wait for next trigger.");
327  return res;
328  }else{
329  BIASERR("Reading image from SwissRanger failed. Please restart application");
330  exit(-1);
331  }
332  }
333 
334  SR_GetImageList(srCam_,&imgEntryArray);
335 
336  dataDepth_ = (const unsigned short*)SR_GetImage(srCam_,0);
337  dataAmp_ = (const unsigned short*)SR_GetImage(srCam_,1);
338 
339  ConvertRawImageToFloat_(dataDepth_, DepthImgF_);
340  ConvertRawImage_(dataAmp_, ModCoeffImg_);
341  if (bGrabImageReturnsDepth_) {
342  ConvertImageFloatToCharNormalized_(DepthImgF_, image, true);
343  } else {
344  ConvertImageFloatToCharNormalized_(ModCoeffImg_, image);
345  }
346 
347  return res;
348 }
349 
352  Image<unsigned char> &dst, bool useMaxDist)
353 {
354  dst.ReInit(Width_, Height_, 1, ImageBase::ST_unsignedchar);
355  float normFactor = 0.0f;
356  if (useMaxDist) {
357  normFactor = float(255.0f / max_dist_);
358  } else {
359  float min,max;
360  src.GetMinMaxPixelValue(min,max);
361  normFactor = float(255.0f / max);
362  }
363  const float** srcData = src.GetImageDataArray();
364  unsigned char** dstData=dst.GetImageDataArray();
365  for (unsigned int y=0; y<dst.GetHeight(); y++) {
366  for (unsigned int x=0; x< dst.GetWidth(); x++) {
367  dstData[y][x] = (unsigned char)( srcData[y][x] * normFactor );
368  }
369  }
370 }
371 
373 ConvertRawImageToFloat_(const unsigned short* data,
374  Image<float> &dst)
375 {
376  if (dst.IsEmpty()) {
377  dst.Init(Width_, Height_, ColorChannels_, ImageBase::ST_float);
378  }
379 
380  const unsigned short* srcDepthP=data;
381  float** dstData=dst.GetImageDataArray();
382  for (unsigned int y=0; y<dst.GetHeight(); y++) {
383  for (unsigned int x=0; x< dst.GetWidth(); x++) {
384  float cur = (*srcDepthP)*max_dist_ / (float)0xffff;
385  dstData[y][x] = cur;
386  srcDepthP++;
387  }
388  }
389 }
390 
392 ConvertRawImage_(const unsigned short* data,
393  Image<float> &dst)
394 {
395  if (dst.IsEmpty()) {
396  dst.Init(Width_, Height_, ColorChannels_, ImageBase::ST_float);
397  }
398 
399  const unsigned short* srcDepthP=data;
400  float** dstData=dst.GetImageDataArray();
401  float step = (float)0xff / (float)0xffff;
402  for (unsigned int y=0; y<dst.GetHeight(); y++) {
403  for (unsigned int x=0; x< dst.GetWidth(); x++) {
404  float cur = (*srcDepthP) * step;
405  dstData[y][x] = cur;
406  srcDepthP++;
407  }
408  }
409 }
410 
411 int BIAS::VideoSource_SwissRanger::SetIntegrationTime(const unsigned char inttime) {
412  integrationTime_ = inttime;
413  return SR_SetIntegrationTime(srCam_, inttime);
414 }
415 
416 int BIAS::VideoSource_SwissRanger::SetModulationFrequency(ModulationFrq dModulationFrequency) {
417  modulationFrequency_ = dModulationFrequency;
418  SetMaxDist_();
419  return SR_SetModulationFrequency(srCam_, (ModulationFrq)modulationFrequency_);
420 }
421 
423  float lightspeed = 299792.485f;
424 #ifdef BIAS_DEBUG
425  std::cout<<"modulationFrequency_:"<< modulationFrequency_ <<std::endl;
426 #endif
427 
428  switch (modulationFrequency_) {
429  case MF_60MHz: //!<SR4k: maximal range 2.5m \intDoc{frequency}
430  max_dist_ = (lightspeed / 60.0f) / 2.0f;
431  break;
432  case MF_40MHz: //!<SR3k: maximal range 3.75m
433  max_dist_ = (lightspeed / 40.0f) / 2.0f;
434  break;
435  case MF_31MHz:
436  max_dist_ = (lightspeed / 31.0f) / 2.0f;
437  break;
438  case MF_30MHz:
439  max_dist_ = (lightspeed / 30.0f) / 2.0f;
440  break;
441  case MF_29MHz:
442  max_dist_ = (lightspeed / 29.0f) / 2.0f;
443  break;
444  case MF_21MHz:
445  max_dist_ = (lightspeed / 21.0f) / 2.0f;
446  break;
447  case MF_20MHz:
448  max_dist_ = (lightspeed / 20.0f) / 2.0f;
449  break;
450  case MF_19MHz:
451  max_dist_ = (lightspeed / 19.0f) / 2.0f;
452  break;
453  case MF_15MHz:
454  max_dist_ = (lightspeed / 15.0f) / 2.0f;
455  break;
456  case MF_10MHz:
457  max_dist_ = (lightspeed / 10.0f) / 2.0f;
458  break;
459  case MF_LAST:
460  break;
461  default:
462  BIASERR("Can not set modulation frequency for SwissRanger!");
463  break;
464  }
465 }
466 
468 #ifndef WIN32
469  // inform user
470  BIASWARN("resetting usb device. device will be set to default configuration");
471  // structs holding usb information
472  struct usb_bus *busses;
473  struct usb_bus *bus;
474  struct usb_device *dev;
475  struct usb_dev_handle *handle;
476  // init usb and find all devices on all busses
477  usb_init();
478  usb_find_busses();
479  usb_find_devices();
480 
481  // walk busses and devices until a device matching swissranger vendor and product id is found
482  busses = usb_get_busses();
483  for (bus = busses; bus; bus = bus->next) {
484  for (dev = bus->devices; dev; dev = dev->next) {
485  if ((dev->descriptor.idVendor == 0x0852 || dev->descriptor.idVendor == 0x1ad2) && (dev->descriptor.idProduct == 0x0074 || dev->descriptor.idProduct == 0x0075)) {
486  // open device and set to default config
487  handle = usb_open(dev);
488  usb_reset(handle);
489  usb_set_configuration(handle, dev->config[0].bConfigurationValue);
490  usb_claim_interface(handle, 0);
491  // close it again
492  usb_close(handle);
493  }
494  }
495  }
496 #endif
497 }
498 
500  {
501  return 0;
502  }
503 
505  {
506  return 0;
507  }
virtual void SetSize(int w, int h, int bytesperpixel=1)
Set image size and number of bytes per pixel (e.g.
virtual int PreGrab()
no needed for PreGrab now, does not do anything
int GetDeviceString(std::string &device)
returns the device string of the camera
int GetSoftwareVersion(std::string &version)
returns the version of the used software
Defines a common interface to different devices.
virtual int PostGrab()
no needed for PostGrab now, does not do anything
gray values, 1 channel
Definition: ImageBase.hh:130
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
virtual int InitDepthImage(ImageBase &img)
Init the depth image to grab to.
void SetColorModel(EColorModel Model)
Definition: ImageBase.hh:561
void ConvertImageFloatToCharNormalized_(const Image< float > src, Image< unsigned char > &dst, bool useMaxDist=false)
void ConvertRawImage_(const unsigned short *data, Image< float > &dst)
float image storage type
Definition: ImageBase.hh:118
void GetMinMaxPixelValue(StorageType &min, StorageType &max, unsigned short int channel=0, unsigned int *mincoo=NULL, unsigned int *maxcoo=NULL) const
returns the minimal and maximal pixel value in channel only Finds minimum and maximum pixel value in ...
Definition: Image.cpp:802
unsigned int GetWidth() const
Definition: ImageBase.hh:312
void ConvertRawImageToFloat_(const unsigned short *data, Image< float > &dst)
int Width_
Image format.
virtual int SetColorModel(BIAS::ImageBase::EColorModel mode)
Select colormodel to use.
virtual int InitImage(ImageBase &img)
Init the grey image to grab to.
void ReInit(const unsigned int &width, const unsigned int &height, const unsigned int nChannels=1, const enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true, const EColorModel colormodel=CM_Grey)
(Re-)Initialize Image data if required.
Definition: ImageBase.cpp:131
unsigned int GetHeight() const
Definition: ImageBase.hh:319
virtual int SetIntegrationTime(const unsigned char inttime)
Set IntegrationTime (as uchar 0-255)
int SetModulationFrequency(ModulationFrq dModulationFrequency)
Set the Modulation frequency (from defines.h) MF_40MHz=0, //!&lt;SR3k: maximal range 3...
virtual int GetCapabilities(VideoSourceCapabilities &caps)
Dummy function, does not do anything.
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
void Release(const bool reset_storage_type=false)
Free the allocated data structures Hands off: Do !!NOT!! change the default of reset_storage_type: Im...
Definition: ImageBase.cpp:350
virtual int GetIntegrationTimeMS(float &inttime)
Get IntegrationTime in ms.
void Init(unsigned int width, unsigned int height, unsigned int nChannels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
Initialize image size and channels.
Definition: ImageBase.cpp:229
virtual int OpenDevice()
try to open first unused PMD-camera
void ResetUsbDeviceConnection_()
uses libusb directly to reset the device in case of failure on open
virtual int CloseDevice()
close an active camera
(8bit) unsigned char image storage type
Definition: ImageBase.hh:112
Checks for VideoSource capabilities.
virtual int GrabSingle(Camera< unsigned char > &image)
Returns the 2D image, and reads depth and modulation coefficients.
This is the base class for images in BIAS.
Definition: ImageBase.hh:102
virtual int SetIntegrationTimeMS(float inttime)
Set IntegrationTime in ms (gets clipped to min/max for camera)
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153