Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
vpPylonGrabberGigE.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description: Implementation of vpPylonGrabberGigE class.
32  *
33  * Authors:
34  * Wenfeng CAI
35  *
36  *****************************************************************************/
37 
44 #include "vpPylonGrabberGigE.h"
45 
46 #ifdef VISP_HAVE_PYLON
47 
48 #include <visp3/core/vpException.h>
49 #include <visp3/core/vpTime.h>
50 
55 vpPylonGrabberGigE::vpPylonGrabberGigE() : m_camera(), m_index(0), m_numCameras(0), m_connected(false)
56 {
57  getNumCameras();
58 }
59 
64 
69 {
70  Pylon::CTlFactory &TlFactory = Pylon::CTlFactory::GetInstance();
71  Pylon::DeviceInfoList_t lstDevices;
72  Pylon::DeviceInfoList_t filter; // Filter for GigE cameras.
73  Pylon::CBaslerGigEDeviceInfo gige_devinfo;
74  filter.push_back(gige_devinfo);
75  TlFactory.EnumerateDevices(lstDevices, filter);
76 
77  m_numCameras = lstDevices.size();
78  return m_numCameras;
79 }
80 
86 std::ostream &vpPylonGrabberGigE::getCameraInfo(std::ostream &os)
87 {
88  connect();
89 
90  Pylon::CDeviceInfo deviceInfo = m_camera.GetDeviceInfo();
91  // Get the camera control object.
92  GenApi::INodeMap &control = m_camera.GetNodeMap();
93 
94  GenApi::CIntegerPtr widthMax = control.GetNode("WidthMax");
95  GenApi::CIntegerPtr heightMax = control.GetNode("HeightMax");
96 
97  os << "Camera information: " << std::endl;
98  os << " Serial number : " << deviceInfo.GetSerialNumber() << std::endl;
99  os << " Camera model : " << deviceInfo.GetModelName() << std::endl;
100  os << " Camera vendor : " << deviceInfo.GetVendorName() << std::endl;
101  os << " Resolution : " << widthMax->GetValue() << "x" << heightMax->GetValue() << std::endl;
102  os << " Firmware version : " << deviceInfo.GetDeviceVersion() << std::endl;
103 
104  return os;
105 }
106 
113 Pylon::CInstantCamera *vpPylonGrabberGigE::getCameraHandler()
114 {
115  connect();
116 
117  if (m_connected == true) {
118  return &m_camera;
119  } else {
120  return NULL;
121  }
122 }
123 
131 {
132  connect();
133 
134  float frame_rate = m_camera.AcquisitionFrameRateAbs.GetValue();
135  return frame_rate;
136 }
137 
145 {
146  connect();
147 
148  if (GenApi::IsReadable(m_camera.GainAbs))
149  return m_camera.GainAbs.GetValue();
150  else if (GenApi::IsReadable(m_camera.GainRaw))
151  return m_camera.GainRaw.GetValue();
152  else
153  throw vpException(vpException::notImplementedError, "Don't know how to get gain.");
154 }
155 
168 {
169  connect();
170 
171  if (GenApi::IsReadable(m_camera.BlackLevelAbs))
172  return m_camera.BlackLevelAbs.GetValue();
173  else if (GenApi::IsReadable(m_camera.BlackLevelRaw))
174  return m_camera.BlackLevelRaw.GetValue();
175  else
176  throw vpException(vpException::notImplementedError, "Don't know how to get blacklevel.");
177 }
178 
191 {
192  connect();
193 
194  if (GenApi::IsReadable(m_camera.ExposureTimeAbs))
195  return m_camera.ExposureTimeAbs.GetValue() * 0.001;
196  else if (GenApi::IsReadable(m_camera.ExposureTimeRaw))
197  return m_camera.ExposureTimeRaw.GetValue();
198  else
199  throw vpException(vpException::notImplementedError, "Don't know how to get exposure.");
200 }
201 
209 {
210  connect();
211 
212  float gamma = m_camera.Gamma.GetValue();
213  return gamma;
214 }
215 
222 std::string vpPylonGrabberGigE::getCameraSerial(unsigned int index)
223 {
224  getNumCameras();
225 
226  if (index >= m_numCameras) {
227  throw(vpException(vpException::badValue, "The camera with index %u is not present. Only %d cameras connected.",
228  index, m_numCameras));
229  }
230 
231  Pylon::CTlFactory &TlFactory = Pylon::CTlFactory::GetInstance();
232  Pylon::DeviceInfoList_t lstDevices; // List of connected cameras
233  Pylon::DeviceInfoList_t filter; // Filter for GigE cameras.
234  Pylon::CBaslerGigEDeviceInfo gige_devinfo;
235  filter.push_back(gige_devinfo);
236  TlFactory.EnumerateDevices(lstDevices, filter);
237 
238  std::ostringstream os;
239  os << lstDevices[index].GetSerialNumber();
240  return os.str();
241 }
242 
253 {
254  connect();
255 
256  bool success = selectUserSet(user_set);
257 
258  if (success) {
259  m_camera.UserSetLoad.Execute();
260  vpTime::wait(200); // How long you have to wait?
261  success = m_camera.UserSetLoad.IsDone();
262  }
263 
264  return success;
265 }
266 
274 {
275  connect();
276 
277  Basler_GigECamera::UserSetDefaultSelectorEnums user_set = m_camera.UserSetDefaultSelector.GetValue();
278 
279  switch (user_set) {
280  case Basler_GigECamera::UserSetDefaultSelector_Default:
281  return USERSET_DEFAULT;
282  break;
283  case Basler_GigECamera::UserSetDefaultSelector_UserSet1:
284  return USERSET_USERSET1;
285  break;
286  case Basler_GigECamera::UserSetDefaultSelector_UserSet2:
287  return USERSET_USERSET2;
288  break;
289  case Basler_GigECamera::UserSetDefaultSelector_UserSet3:
290  return USERSET_USERSET3;
291  break;
292  default:
293  return USERSET_UNKNOWN;
294  }
295 }
296 
313 void vpPylonGrabberGigE::setCameraIndex(unsigned int index)
314 {
315  if (index >= m_numCameras) {
316  throw(vpException(vpException::badValue, "The camera with index %u is not present. Only %d cameras connected.",
317  index, m_numCameras));
318  }
319 
320  m_index = index;
321 }
322 
329 void vpPylonGrabberGigE::setCameraSerial(const std::string &serial)
330 {
331  m_numCameras = getNumCameras();
332  for (unsigned int i = 0; i < m_numCameras; i++) {
333  if (getCameraSerial(i) == serial) {
334  m_index = i;
335  return;
336  }
337  }
338  throw(vpException(vpException::badValue, "The camera with serial id %s is not present.", serial.c_str()));
339 }
340 
348 float vpPylonGrabberGigE::setFrameRate(float frame_rate)
349 {
350  connect();
351 
352  m_camera.AcquisitionFrameRateAbs.SetValue(frame_rate);
353 
354  return m_camera.AcquisitionFrameRateAbs.GetValue();
355 }
356 
370 float vpPylonGrabberGigE::setGain(bool gain_auto, float gain_value)
371 {
372  connect();
373 
374  if (gain_auto)
375  m_camera.GainAuto.SetValue(Basler_GigECamera::GainAuto_Continuous);
376  else
377  m_camera.GainAuto.SetValue(Basler_GigECamera::GainAuto_Off);
378 
379  if (GenApi::IsWritable(m_camera.GainAbs)) {
380  m_camera.GainAbs.SetValue(gain_value);
381  return m_camera.GainAbs.GetValue();
382  } else if (GenApi::IsWritable(m_camera.GainRaw)) {
383  m_camera.GainRaw.SetValue(gain_value);
384  return m_camera.GainRaw.GetValue();
385  } else
386  throw vpException(vpException::notImplementedError, "Don't know how to set gain.");
387 }
388 
403 float vpPylonGrabberGigE::setBlackLevel(float blacklevel_value)
404 {
405  connect();
406 
407  if (GenApi::IsWritable(m_camera.BlackLevelAbs)) {
408  m_camera.BlackLevelAbs.SetValue(blacklevel_value);
409  return m_camera.BlackLevelAbs.GetValue();
410  } else if (GenApi::IsWritable(m_camera.BlackLevelRaw)) {
411  m_camera.BlackLevelRaw.SetValue(blacklevel_value);
412  return m_camera.BlackLevelRaw.GetValue();
413  } else
414  throw vpException(vpException::notImplementedError, "Don't know how to set blacklevel.");
415 }
416 
434 float vpPylonGrabberGigE::setExposure(bool exposure_on, bool exposure_auto, float exposure_value)
435 {
436  connect();
437 
438  if (exposure_on)
439  m_camera.ExposureMode.SetValue(Basler_GigECamera::ExposureMode_Timed);
440  else
441  m_camera.ExposureMode.SetValue(Basler_GigECamera::ExposureMode_Off);
442 
443  if (exposure_auto)
444  m_camera.ExposureAuto.SetValue(Basler_GigECamera::ExposureAuto_Continuous);
445  else
446  m_camera.ExposureAuto.SetValue(Basler_GigECamera::ExposureAuto_Off);
447 
448  if (GenApi::IsWritable(m_camera.ExposureTimeAbs)) {
449  m_camera.ExposureTimeAbs.SetValue(exposure_value * 1000);
450  return m_camera.ExposureTimeAbs.GetValue() * 0.001;
451  } else if (GenApi::IsWritable(m_camera.ExposureTimeRaw)) {
452  m_camera.ExposureTimeRaw.SetValue(exposure_value);
453  return m_camera.ExposureTimeRaw.GetValue();
454  } else
455  throw vpException(vpException::notImplementedError, "Don't know how to set exposure.");
456 }
457 
470 float vpPylonGrabberGigE::setGamma(bool gamma_on, float gamma_value)
471 {
472  connect();
473 
474  if (GenApi::IsWritable(m_camera.GammaEnable))
475  m_camera.GammaEnable.SetValue(gamma_on);
476 
477  if (GenApi::IsWritable(m_camera.Gamma)) {
478  m_camera.Gamma.SetValue(gamma_value);
479  return m_camera.Gamma.GetValue();
480  } else
481  throw vpException(vpException::notImplementedError, "Don't know how to set gamma.");
482 }
483 
495 bool vpPylonGrabberGigE::saveUserSet(UserSetName user_set, bool set_default)
496 {
497  connect();
498 
499  bool success = selectUserSet(user_set);
500 
501  if (success) {
502  m_camera.UserSetSave.Execute();
503  vpTime::wait(200); // How long you have to wait?
504  success = m_camera.UserSetSave.IsDone();
505  }
506 
507  if (success && set_default)
508  success = setUserSetDefault(user_set);
509 
510  return success;
511 }
512 
523 {
524  connect();
525 
526  switch (user_set) {
527  case USERSET_DEFAULT:
528  m_camera.UserSetDefaultSelector.SetValue(Basler_GigECamera::UserSetDefaultSelector_Default);
529  return true;
530  break;
531  case USERSET_USERSET1:
532  m_camera.UserSetDefaultSelector.SetValue(Basler_GigECamera::UserSetDefaultSelector_UserSet1);
533  return true;
534  break;
535  case USERSET_USERSET2:
536  m_camera.UserSetDefaultSelector.SetValue(Basler_GigECamera::UserSetDefaultSelector_UserSet2);
537  return true;
538  break;
539  case USERSET_USERSET3:
540  m_camera.UserSetDefaultSelector.SetValue(Basler_GigECamera::UserSetDefaultSelector_UserSet3);
541  return true;
542  break;
543  default:
544  return false;
545  }
546 }
547 
554 {
555  connect();
556 
557  if (!m_camera.IsGrabbing()) {
558  m_camera.StartGrabbing(1);
559  }
560  if (m_connected && m_camera.IsGrabbing())
561  init = true;
562  else
563  init = false;
564 }
565 
572 {
573  if (m_camera.IsGrabbing()) {
574  m_camera.StopGrabbing();
575  }
576  if (m_connected && m_camera.IsGrabbing())
577  init = true;
578  else
579  init = false;
580 }
581 
588 {
589  if (m_connected == false) {
590  m_numCameras = getNumCameras();
591  if (m_numCameras == 0) {
592  throw(vpException(vpException::fatalError, "No camera found"));
593  }
594 
595  if (!m_camera.IsPylonDeviceAttached()) {
596  Pylon::CTlFactory &TlFactory = Pylon::CTlFactory::GetInstance();
597  Pylon::DeviceInfoList_t lstDevices;
598  Pylon::DeviceInfoList_t filter; // Filter for GigE cameras.
599  Pylon::CBaslerGigEDeviceInfo gige_devinfo;
600  filter.push_back(gige_devinfo);
601  TlFactory.EnumerateDevices(lstDevices, filter);
602 
603  m_camera.Attach(TlFactory.CreateDevice(lstDevices[m_index]));
604  }
605  // Connect to a camera
606  m_camera.Open();
607  m_connected = true;
608  }
609  if (m_connected && m_camera.IsGrabbing())
610  init = true;
611  else
612  init = false;
613 }
614 
621 {
622  if (m_connected == true) {
623  m_camera.Close();
624  m_connected = false;
625  }
626  if (m_connected && m_camera.IsGrabbing())
627  init = true;
628  else
629  init = false;
630 }
631 
641 {
642  stopCapture();
643  disconnect();
644 }
645 
652 {
653  open();
654 
655  Pylon::CGrabResultPtr grabResult;
656  // Retrieve an image
657  if (!m_camera.RetrieveResult(2000, grabResult)) {
658  throw(vpException(vpException::fatalError, "Cannot retrieve image from camera with serial %s",
659  getCameraSerial(m_index).c_str()));
660  }
661 
662  if (grabResult->GrabSucceeded()) {
663  height = grabResult->GetHeight();
664  width = grabResult->GetWidth();
665  I.resize(height, width);
666 
667  Pylon::CImageFormatConverter imageConvert;
668  imageConvert.OutputPixelFormat = Pylon::PixelType_Mono8;
669  imageConvert.OutputPaddingX = 0;
670  // Create a converted image
671  imageConvert.Convert(I.bitmap, sizeof(unsigned char) * width * height, (Pylon::IImage &)grabResult);
672  }
673 }
674 
681 {
682  open();
683 
684  Pylon::CGrabResultPtr grabResult;
685  // Retrieve an image
686  if (!m_camera.RetrieveResult(2000, grabResult)) {
687  throw(vpException(vpException::fatalError, "Cannot retrieve image from camera with serial %s",
688  getCameraSerial(m_index).c_str()));
689  }
690 
691  if (grabResult->GrabSucceeded()) {
692  height = grabResult->GetHeight();
693  width = grabResult->GetWidth();
694  I.resize(height, width);
695 
696  Pylon::CImageFormatConverter imageConvert;
697  imageConvert.OutputPixelFormat = Pylon::PixelType_BGRA8packed;
698  imageConvert.OutputPaddingX = 0;
699  // Create a converted image
700  Pylon::CPylonImage destImage;
701  imageConvert.Convert(destImage, (Pylon::IImage &)grabResult);
702  Pylon::SBGRA8Pixel *pixel = (Pylon::SBGRA8Pixel *)destImage.GetBuffer();
703  for (unsigned int i = 0; i < height; i++) {
704  for (unsigned int j = 0; j < width; j++) {
705  unsigned int p_index = i * width + j;
706  I[i][j].R = pixel[p_index].R;
707  I[i][j].G = pixel[p_index].G;
708  I[i][j].B = pixel[p_index].B;
709  I[i][j].A = pixel[p_index].A;
710  }
711  }
712  }
713 }
714 
720 {
721  open();
722  acquire(I);
723 }
724 
730 {
731  open();
732  acquire(I);
733 }
734 
747 {
748  connect();
749  startCapture();
750 }
751 
761 {
762  connect();
763 
764  switch (user_set) {
765  case USERSET_DEFAULT:
766  m_camera.UserSetSelector.SetValue(Basler_GigECamera::UserSetSelector_Default);
767  return true;
768  break;
769  case USERSET_USERSET1:
770  m_camera.UserSetSelector.SetValue(Basler_GigECamera::UserSetSelector_UserSet1);
771  return true;
772  break;
773  case USERSET_USERSET2:
774  m_camera.UserSetSelector.SetValue(Basler_GigECamera::UserSetSelector_UserSet2);
775  return true;
776  break;
777  case USERSET_USERSET3:
778  m_camera.UserSetSelector.SetValue(Basler_GigECamera::UserSetSelector_UserSet3);
779  return true;
780  break;
781  default:
782  return false;
783  }
784 }
785 
791 {
792  acquire(I);
793  return *this;
794 }
795 
801 {
802  acquire(I);
803  return *this;
804 }
805 
806 #else
807 // Work arround to avoid warning:
808 // libvisp_pylon.a(vpPylonGrabberGigE.cpp.o) has no symbols
809 void dummy_vpPylonGrabberGigE(){};
810 #endif // #ifdef VISP_HAVE_PYLON
float setGain(bool gain_auto, float gain_value=0)
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:97
VISP_EXPORT int wait(double t0, double t)
Definition: vpTime.cpp:173
bool loadUserSet(UserSetName user_set)
Loads the selected configuration into the camera&#39;s volatile memory and makes it the active configurat...
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:879
Type * bitmap
points toward the bitmap
Definition: vpImage.h:141
User set not supported.
std::ostream & getCameraInfo(std::ostream &os)
error that can be emited by ViSP classes.
Definition: vpException.h:71
void acquire(vpImage< unsigned char > &I)
unsigned int getNumCameras()
void setCameraSerial(const std::string &serial)
std::string getCameraSerial(unsigned int index)
Pylon::CInstantCamera * getCameraHandler()
unsigned int height
Number of rows in the image.
float setFrameRate(float frame_rate)
vpPylonGrabber & operator>>(vpImage< unsigned char > &I)
float setGamma(bool gamma_on, float gamma_value=1)
The default user set.
bool init
Set to true if the frame grabber has been initialized.
UserSetName getUserSetDefault()
Gets the configuration set being used as the default startup set.
bool selectUserSet(UserSetName user_set)
Selects the configuration set to load, save, or configure.
void close()
Stop active camera capturing images and disconnect the active camera.
float setExposure(bool exposure_on, bool exposure_auto, float exposure_value=0)
float setBlackLevel(float blacklevel_value=0)
void setCameraIndex(unsigned int index)
unsigned int width
Number of columns in the image.
bool saveUserSet(UserSetName user_set, bool set_default=false)
Saves the current active configuration set into the selected user set.
bool setUserSetDefault(UserSetName user_set)
Sets the configuration set to be used as the default startup set.