Visual Servoing Platform  version 3.6.1 under development (2024-03-18)
vpPylonGrabberUsb.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 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 https://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 vpPylonGrabberUsb class.
32  *
33  * Authors:
34  * Wenfeng CAI
35  *
36 *****************************************************************************/
37 
44 #include "vpPylonGrabberUsb.h"
45 
46 #ifdef VISP_HAVE_PYLON
47 
48 #include <visp3/core/vpException.h>
49 #include <visp3/core/vpTime.h>
50 
55 vpPylonGrabberUsb::vpPylonGrabberUsb() : 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 USB cameras.
73  Pylon::CBaslerUsbDeviceInfo usb_devinfo;
74  filter.push_back(usb_devinfo);
75  TlFactory.EnumerateDevices(lstDevices, filter);
76 
77  m_numCameras = lstDevices.size();
78  return m_numCameras;
79 }
80 
86 std::ostream &vpPylonGrabberUsb::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 *vpPylonGrabberUsb::getCameraHandler()
114 {
115  connect();
116 
117  if (m_connected == true) {
118  return &m_camera;
119  } else {
120  return nullptr;
121  }
122 }
123 
131 {
132  connect();
133 
134  float frame_rate = m_camera.AcquisitionFrameRate.GetValue();
135  return frame_rate;
136 }
137 
145 {
146  connect();
147 
148  if (GenApi::IsReadable(m_camera.Gain))
149  return m_camera.Gain.GetValue();
150  else
151  throw vpException(vpException::notImplementedError, "Don't know how to get gain.");
152 }
153 
166 {
167  connect();
168 
169  if (GenApi::IsReadable(m_camera.BlackLevel))
170  return m_camera.BlackLevel.GetValue();
171  else
172  throw vpException(vpException::notImplementedError, "Don't know how to get blacklevel.");
173 }
174 
187 {
188  connect();
189 
190  if (GenApi::IsReadable(m_camera.ExposureTime))
191  return m_camera.ExposureTime.GetValue() * 0.001;
192  else
193  throw vpException(vpException::notImplementedError, "Don't know how to get exposure.");
194 }
195 
203 {
204  connect();
205 
206  float gamma = m_camera.Gamma.GetValue();
207  return gamma;
208 }
209 
216 std::string vpPylonGrabberUsb::getCameraSerial(unsigned int index)
217 {
218  getNumCameras();
219 
220  if (index >= m_numCameras) {
221  throw(vpException(vpException::badValue, "The camera with index %u is not present. Only %d cameras connected.",
222  index, m_numCameras));
223  }
224 
225  Pylon::CTlFactory &TlFactory = Pylon::CTlFactory::GetInstance();
226  Pylon::DeviceInfoList_t lstDevices; // List of connected cameras
227  Pylon::DeviceInfoList_t filter; // Filter for USB cameras.
228  Pylon::CBaslerUsbDeviceInfo usb_devinfo;
229  filter.push_back(usb_devinfo);
230  TlFactory.EnumerateDevices(lstDevices, filter);
231 
232  std::ostringstream os;
233  os << lstDevices[index].GetSerialNumber();
234  return os.str();
235 }
236 
247 {
248  connect();
249 
250  bool success = selectUserSet(user_set);
251 
252  if (success) {
253  m_camera.UserSetLoad.Execute();
254  vpTime::wait(200); // How long you have to wait?
255  success = m_camera.UserSetLoad.IsDone();
256  }
257 
258  return success;
259 }
260 
268 {
269  connect();
270 
271  Basler_UsbCameraParams::UserSetDefaultEnums user_set = m_camera.UserSetDefault.GetValue();
272 
273  switch (user_set) {
274  case Basler_UsbCameraParams::UserSetDefault_Default:
275  return USERSET_DEFAULT;
276  break;
277  case Basler_UsbCameraParams::UserSetDefault_UserSet1:
278  return USERSET_USERSET1;
279  break;
280  case Basler_UsbCameraParams::UserSetDefault_UserSet2:
281  return USERSET_USERSET2;
282  break;
283  case Basler_UsbCameraParams::UserSetDefault_UserSet3:
284  return USERSET_USERSET3;
285  break;
286  default:
287  return USERSET_UNKNOWN;
288  }
289 }
290 
307 void vpPylonGrabberUsb::setCameraIndex(unsigned int index)
308 {
309  if (index >= m_numCameras) {
310  throw(vpException(vpException::badValue, "The camera with index %u is not present. Only %d cameras connected.",
311  index, m_numCameras));
312  }
313 
314  m_index = index;
315 }
316 
323 void vpPylonGrabberUsb::setCameraSerial(const std::string &serial)
324 {
325  m_numCameras = getNumCameras();
326  for (unsigned int i = 0; i < m_numCameras; i++) {
327  if (getCameraSerial(i) == serial) {
328  m_index = i;
329  return;
330  }
331  }
332  throw(vpException(vpException::badValue, "The camera with serial id %s is not present.", serial.c_str()));
333 }
334 
342 float vpPylonGrabberUsb::setFrameRate(float frame_rate)
343 {
344  connect();
345 
346  m_camera.AcquisitionFrameRate.SetValue(frame_rate);
347 
348  return m_camera.AcquisitionFrameRate.GetValue();
349 }
350 
364 float vpPylonGrabberUsb::setGain(bool gain_auto, float gain_value)
365 {
366  connect();
367 
368  if (gain_auto)
369  m_camera.GainAuto.SetValue(Basler_UsbCameraParams::GainAuto_Continuous);
370  else
371  m_camera.GainAuto.SetValue(Basler_UsbCameraParams::GainAuto_Off);
372 
373  if (GenApi::IsWritable(m_camera.Gain)) {
374  m_camera.Gain.SetValue(gain_value);
375  return m_camera.Gain.GetValue();
376  } else
377  throw vpException(vpException::notImplementedError, "Don't know how to set gain.");
378 }
379 
394 float vpPylonGrabberUsb::setBlackLevel(float blacklevel_value)
395 {
396  connect();
397 
398  if (GenApi::IsWritable(m_camera.BlackLevel)) {
399  m_camera.BlackLevel.SetValue(blacklevel_value);
400  return m_camera.BlackLevel.GetValue();
401  } else
402  throw vpException(vpException::notImplementedError, "Don't know how to set blacklevel.");
403 }
404 
422 float vpPylonGrabberUsb::setExposure(bool exposure_on, bool exposure_auto, float exposure_value)
423 {
424  connect();
425 
426  if (exposure_on)
427  m_camera.ExposureMode.SetValue(Basler_UsbCameraParams::ExposureMode_Timed);
428  else
429  m_camera.ExposureMode.SetValue(Basler_UsbCameraParams::ExposureMode_TriggerWidth);
430 
431  if (exposure_auto)
432  m_camera.ExposureAuto.SetValue(Basler_UsbCameraParams::ExposureAuto_Continuous);
433  else
434  m_camera.ExposureAuto.SetValue(Basler_UsbCameraParams::ExposureAuto_Off);
435 
436  if (GenApi::IsWritable(m_camera.ExposureTime)) {
437  m_camera.ExposureTime.SetValue(exposure_value * 1000);
438  return m_camera.ExposureTime.GetValue() * 0.001;
439  } else
440  throw vpException(vpException::notImplementedError, "Don't know how to set exposure.");
441 }
442 
455 float vpPylonGrabberUsb::setGamma(bool gamma_on, float gamma_value)
456 {
457  connect();
458 
459  if (GenApi::IsWritable(m_camera.Gamma)) {
460  if (gamma_on)
461  m_camera.Gamma.SetValue(gamma_value);
462  else
463  m_camera.Gamma.SetValue(1);
464  return m_camera.Gamma.GetValue();
465  } else
466  throw vpException(vpException::notImplementedError, "Don't know how to set gamma.");
467 }
468 
480 bool vpPylonGrabberUsb::saveUserSet(UserSetName user_set, bool set_default)
481 {
482  connect();
483 
484  bool success = selectUserSet(user_set);
485 
486  if (success) {
487  m_camera.UserSetSave.Execute();
488  vpTime::wait(200); // How long you have to wait?
489  success = m_camera.UserSetSave.IsDone();
490  }
491 
492  if (success && set_default)
493  success = setUserSetDefault(user_set);
494 
495  return success;
496 }
497 
508 {
509  connect();
510 
511  switch (user_set) {
512  case USERSET_DEFAULT:
513  m_camera.UserSetDefault.SetValue(Basler_UsbCameraParams::UserSetDefault_Default);
514  return true;
515  break;
516  case USERSET_USERSET1:
517  m_camera.UserSetDefault.SetValue(Basler_UsbCameraParams::UserSetDefault_UserSet1);
518  return true;
519  break;
520  case USERSET_USERSET2:
521  m_camera.UserSetDefault.SetValue(Basler_UsbCameraParams::UserSetDefault_UserSet2);
522  return true;
523  break;
524  case USERSET_USERSET3:
525  m_camera.UserSetDefault.SetValue(Basler_UsbCameraParams::UserSetDefault_UserSet3);
526  return true;
527  break;
528  default:
529  return false;
530  }
531 }
532 
539 {
540  connect();
541 
542  if (!m_camera.IsGrabbing()) {
543  m_camera.StartGrabbing(1);
544  }
545  if (m_connected && m_camera.IsGrabbing())
546  init = true;
547  else
548  init = false;
549 }
550 
557 {
558  if (m_camera.IsGrabbing()) {
559  m_camera.StopGrabbing();
560  }
561  if (m_connected && m_camera.IsGrabbing())
562  init = true;
563  else
564  init = false;
565 }
566 
573 {
574  if (m_connected == false) {
575  m_numCameras = getNumCameras();
576  if (m_numCameras == 0) {
577  throw(vpException(vpException::fatalError, "No camera found"));
578  }
579 
580  if (!m_camera.IsPylonDeviceAttached()) {
581  Pylon::CTlFactory &TlFactory = Pylon::CTlFactory::GetInstance();
582  Pylon::DeviceInfoList_t lstDevices;
583  Pylon::DeviceInfoList_t filter; // Filter for USB cameras.
584  Pylon::CBaslerUsbDeviceInfo usb_devinfo;
585  filter.push_back(usb_devinfo);
586  TlFactory.EnumerateDevices(lstDevices, filter);
587 
588  m_camera.Attach(TlFactory.CreateDevice(lstDevices[m_index]));
589  }
590  // Connect to a camera
591  m_camera.Open();
592  m_connected = true;
593  }
594  if (m_connected && m_camera.IsGrabbing())
595  init = true;
596  else
597  init = false;
598 }
599 
606 {
607  if (m_connected == true) {
608  m_camera.Close();
609  m_connected = false;
610  }
611  if (m_connected && m_camera.IsGrabbing())
612  init = true;
613  else
614  init = false;
615 }
616 
626 {
627  stopCapture();
628  disconnect();
629 }
630 
637 {
638  open();
639 
640  Pylon::CGrabResultPtr grabResult;
641  // Retrieve an image
642  if (!m_camera.RetrieveResult(2000, grabResult)) {
643  throw(vpException(vpException::fatalError, "Cannot retrieve image from camera with serial %s",
644  getCameraSerial(m_index).c_str()));
645  }
646 
647  if (grabResult->GrabSucceeded()) {
648  height = grabResult->GetHeight();
649  width = grabResult->GetWidth();
650  I.resize(height, width);
651 
652  Pylon::CImageFormatConverter imageConvert;
653  imageConvert.OutputPixelFormat = Pylon::PixelType_Mono8;
654  imageConvert.OutputPaddingX = 0;
655  // Create a converted image
656  imageConvert.Convert(I.bitmap, sizeof(unsigned char) * width * height, (Pylon::IImage &)grabResult);
657  }
658 }
659 
666 {
667  open();
668 
669  Pylon::CGrabResultPtr grabResult;
670  // Retrieve an image
671  if (!m_camera.RetrieveResult(2000, grabResult)) {
672  throw(vpException(vpException::fatalError, "Cannot retrieve image from camera with serial %s",
673  getCameraSerial(m_index).c_str()));
674  }
675 
676  if (grabResult->GrabSucceeded()) {
677  height = grabResult->GetHeight();
678  width = grabResult->GetWidth();
679  I.resize(height, width);
680 
681  Pylon::CImageFormatConverter imageConvert;
682  imageConvert.OutputPixelFormat = Pylon::PixelType_BGRA8packed;
683  imageConvert.OutputPaddingX = 0;
684  // Create a converted image
685  Pylon::CPylonImage destImage;
686  imageConvert.Convert(destImage, (Pylon::IImage &)grabResult);
687  Pylon::SBGRA8Pixel *pixel = (Pylon::SBGRA8Pixel *)destImage.GetBuffer();
688  for (unsigned int i = 0; i < height; i++) {
689  for (unsigned int j = 0; j < width; j++) {
690  unsigned int p_index = i * width + j;
691  I[i][j].R = pixel[p_index].R;
692  I[i][j].G = pixel[p_index].G;
693  I[i][j].B = pixel[p_index].B;
694  I[i][j].A = pixel[p_index].A;
695  }
696  }
697  }
698 }
699 
705 {
706  open();
707  acquire(I);
708 }
709 
715 {
716  open();
717  acquire(I);
718 }
719 
732 {
733  connect();
734  startCapture();
735 }
736 
746 {
747  connect();
748 
749  switch (user_set) {
750  case USERSET_DEFAULT:
751  m_camera.UserSetSelector.SetValue(Basler_UsbCameraParams::UserSetSelector_Default);
752  return true;
753  break;
754  case USERSET_USERSET1:
755  m_camera.UserSetSelector.SetValue(Basler_UsbCameraParams::UserSetSelector_UserSet1);
756  return true;
757  break;
758  case USERSET_USERSET2:
759  m_camera.UserSetSelector.SetValue(Basler_UsbCameraParams::UserSetSelector_UserSet2);
760  return true;
761  break;
762  case USERSET_USERSET3:
763  m_camera.UserSetSelector.SetValue(Basler_UsbCameraParams::UserSetSelector_UserSet3);
764  return true;
765  break;
766  default:
767  return false;
768  }
769 }
770 
776 {
777  acquire(I);
778  return *this;
779 }
780 
786 {
787  acquire(I);
788  return *this;
789 }
790 
791 #else
792 // Work around to avoid warning:
793 // libvisp_pylon.a(vpPylonGrabberUsb.cpp.o) has no symbols
794 void dummy_vpPylonGrabberUsb(){};
795 #endif // #ifdef VISP_HAVE_PYLON
error that can be emitted by ViSP classes.
Definition: vpException.h:59
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:85
@ notImplementedError
Not implemented.
Definition: vpException.h:81
@ fatalError
Fatal error.
Definition: vpException.h:84
unsigned int height
Number of rows in the image.
bool init
Set to true if the frame grabber has been initialized.
unsigned int width
Number of columns in the image.
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:787
Type * bitmap
points toward the bitmap
Definition: vpImage.h:139
bool loadUserSet(UserSetName user_set)
Loads the selected configuration into the camera's volatile memory and makes it the active configurat...
vpPylonGrabber & operator>>(vpImage< unsigned char > &I)
unsigned int getNumCameras()
float setBlackLevel(float blacklevel_value=0)
Pylon::CInstantCamera * getCameraHandler()
std::ostream & getCameraInfo(std::ostream &os)
float setFrameRate(float frame_rate)
float setGamma(bool gamma_on, float gamma_value=1)
bool setUserSetDefault(UserSetName user_set)
Sets the configuration set to be used as the default startup set.
UserSetName getUserSetDefault()
Gets the configuration set being used as the default startup set.
void close()
Stop active camera capturing images and disconnect the active camera.
bool selectUserSet(UserSetName user_set)
Selects the configuration set to load, save, or configure.
void setCameraIndex(unsigned int index)
bool saveUserSet(UserSetName user_set, bool set_default=false)
Saves the current active configuration set into the selected user set.
std::string getCameraSerial(unsigned int index)
void acquire(vpImage< unsigned char > &I)
float setExposure(bool exposure_on, bool exposure_auto, float exposure_value=0)
void setCameraSerial(const std::string &serial)
float setGain(bool gain_auto, float gain_value=0)
@ USERSET_DEFAULT
The default user set.
@ USERSET_UNKNOWN
User set not supported.
@ USERSET_USERSET1
User set 1.
@ USERSET_USERSET3
User set 3.
@ USERSET_USERSET2
User set 2.
VISP_EXPORT int wait(double t0, double t)