Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
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 
51 BEGIN_VISP_NAMESPACE
56 vpPylonGrabberUsb::vpPylonGrabberUsb() : m_camera(), m_index(0), m_numCameras(0), m_connected(false)
57 {
58  getNumCameras();
59 }
60 
65 
70 {
71  Pylon::CTlFactory &TlFactory = Pylon::CTlFactory::GetInstance();
72  Pylon::DeviceInfoList_t lstDevices;
73  Pylon::DeviceInfoList_t filter; // Filter for USB cameras.
74  Pylon::CBaslerUsbDeviceInfo usb_devinfo;
75  filter.push_back(usb_devinfo);
76  TlFactory.EnumerateDevices(lstDevices, filter);
77 
78  m_numCameras = lstDevices.size();
79  return m_numCameras;
80 }
81 
87 std::ostream &vpPylonGrabberUsb::getCameraInfo(std::ostream &os)
88 {
89  connect();
90 
91  Pylon::CDeviceInfo deviceInfo = m_camera.GetDeviceInfo();
92  // Get the camera control object.
93  GenApi::INodeMap &control = m_camera.GetNodeMap();
94 
95  GenApi::CIntegerPtr widthMax = control.GetNode("WidthMax");
96  GenApi::CIntegerPtr heightMax = control.GetNode("HeightMax");
97 
98  os << "Camera information: " << std::endl;
99  os << " Serial number : " << deviceInfo.GetSerialNumber() << std::endl;
100  os << " Camera model : " << deviceInfo.GetModelName() << std::endl;
101  os << " Camera vendor : " << deviceInfo.GetVendorName() << std::endl;
102  os << " Resolution : " << widthMax->GetValue() << "x" << heightMax->GetValue() << std::endl;
103  os << " Firmware version : " << deviceInfo.GetDeviceVersion() << std::endl;
104 
105  return os;
106 }
107 
114 Pylon::CInstantCamera *vpPylonGrabberUsb::getCameraHandler()
115 {
116  connect();
117 
118  if (m_connected == true) {
119  return &m_camera;
120  }
121  else {
122  return nullptr;
123  }
124 }
125 
133 {
134  connect();
135 
136  float frame_rate = m_camera.AcquisitionFrameRate.GetValue();
137  return frame_rate;
138 }
139 
147 {
148  connect();
149 
150  if (GenApi::IsReadable(m_camera.Gain))
151  return m_camera.Gain.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.BlackLevel))
172  return m_camera.BlackLevel.GetValue();
173  else
174  throw vpException(vpException::notImplementedError, "Don't know how to get blacklevel.");
175 }
176 
189 {
190  connect();
191 
192  if (GenApi::IsReadable(m_camera.ExposureTime))
193  return m_camera.ExposureTime.GetValue() * 0.001;
194  else
195  throw vpException(vpException::notImplementedError, "Don't know how to get exposure.");
196 }
197 
205 {
206  connect();
207 
208  float gamma = m_camera.Gamma.GetValue();
209  return gamma;
210 }
211 
218 std::string vpPylonGrabberUsb::getCameraSerial(unsigned int index)
219 {
220  getNumCameras();
221 
222  if (index >= m_numCameras) {
223  throw(vpException(vpException::badValue, "The camera with index %u is not present. Only %d cameras connected.",
224  index, m_numCameras));
225  }
226 
227  Pylon::CTlFactory &TlFactory = Pylon::CTlFactory::GetInstance();
228  Pylon::DeviceInfoList_t lstDevices; // List of connected cameras
229  Pylon::DeviceInfoList_t filter; // Filter for USB cameras.
230  Pylon::CBaslerUsbDeviceInfo usb_devinfo;
231  filter.push_back(usb_devinfo);
232  TlFactory.EnumerateDevices(lstDevices, filter);
233 
234  std::ostringstream os;
235  os << lstDevices[index].GetSerialNumber();
236  return os.str();
237 }
238 
249 {
250  connect();
251 
252  bool success = selectUserSet(user_set);
253 
254  if (success) {
255  m_camera.UserSetLoad.Execute();
256  vpTime::wait(200); // How long you have to wait?
257  success = m_camera.UserSetLoad.IsDone();
258  }
259 
260  return success;
261 }
262 
270 {
271  connect();
272 
273  Basler_UsbCameraParams::UserSetDefaultEnums user_set = m_camera.UserSetDefault.GetValue();
274 
275  switch (user_set) {
276  case Basler_UsbCameraParams::UserSetDefault_Default:
277  return USERSET_DEFAULT;
278  break;
279  case Basler_UsbCameraParams::UserSetDefault_UserSet1:
280  return USERSET_USERSET1;
281  break;
282  case Basler_UsbCameraParams::UserSetDefault_UserSet2:
283  return USERSET_USERSET2;
284  break;
285  case Basler_UsbCameraParams::UserSetDefault_UserSet3:
286  return USERSET_USERSET3;
287  break;
288  default:
289  return USERSET_UNKNOWN;
290  }
291 }
292 
309 void vpPylonGrabberUsb::setCameraIndex(unsigned int index)
310 {
311  if (index >= m_numCameras) {
312  throw(vpException(vpException::badValue, "The camera with index %u is not present. Only %d cameras connected.",
313  index, m_numCameras));
314  }
315 
316  m_index = index;
317 }
318 
325 void vpPylonGrabberUsb::setCameraSerial(const std::string &serial)
326 {
327  m_numCameras = getNumCameras();
328  for (unsigned int i = 0; i < m_numCameras; i++) {
329  if (getCameraSerial(i) == serial) {
330  m_index = i;
331  return;
332  }
333  }
334  throw(vpException(vpException::badValue, "The camera with serial id %s is not present.", serial.c_str()));
335 }
336 
344 float vpPylonGrabberUsb::setFrameRate(float frame_rate)
345 {
346  connect();
347 
348  m_camera.AcquisitionFrameRate.SetValue(frame_rate);
349 
350  return m_camera.AcquisitionFrameRate.GetValue();
351 }
352 
366 float vpPylonGrabberUsb::setGain(bool gain_auto, float gain_value)
367 {
368  connect();
369 
370  if (gain_auto)
371  m_camera.GainAuto.SetValue(Basler_UsbCameraParams::GainAuto_Continuous);
372  else
373  m_camera.GainAuto.SetValue(Basler_UsbCameraParams::GainAuto_Off);
374 
375  if (GenApi::IsWritable(m_camera.Gain)) {
376  m_camera.Gain.SetValue(gain_value);
377  return m_camera.Gain.GetValue();
378  }
379  else
380  throw vpException(vpException::notImplementedError, "Don't know how to set gain.");
381 }
382 
397 float vpPylonGrabberUsb::setBlackLevel(float blacklevel_value)
398 {
399  connect();
400 
401  if (GenApi::IsWritable(m_camera.BlackLevel)) {
402  m_camera.BlackLevel.SetValue(blacklevel_value);
403  return m_camera.BlackLevel.GetValue();
404  }
405  else
406  throw vpException(vpException::notImplementedError, "Don't know how to set blacklevel.");
407 }
408 
426 float vpPylonGrabberUsb::setExposure(bool exposure_on, bool exposure_auto, float exposure_value)
427 {
428  connect();
429 
430  if (exposure_on)
431  m_camera.ExposureMode.SetValue(Basler_UsbCameraParams::ExposureMode_Timed);
432  else
433  m_camera.ExposureMode.SetValue(Basler_UsbCameraParams::ExposureMode_TriggerWidth);
434 
435  if (exposure_auto)
436  m_camera.ExposureAuto.SetValue(Basler_UsbCameraParams::ExposureAuto_Continuous);
437  else
438  m_camera.ExposureAuto.SetValue(Basler_UsbCameraParams::ExposureAuto_Off);
439 
440  if (GenApi::IsWritable(m_camera.ExposureTime)) {
441  m_camera.ExposureTime.SetValue(exposure_value * 1000);
442  return m_camera.ExposureTime.GetValue() * 0.001;
443  }
444  else
445  throw vpException(vpException::notImplementedError, "Don't know how to set exposure.");
446 }
447 
460 float vpPylonGrabberUsb::setGamma(bool gamma_on, float gamma_value)
461 {
462  connect();
463 
464  if (GenApi::IsWritable(m_camera.Gamma)) {
465  if (gamma_on)
466  m_camera.Gamma.SetValue(gamma_value);
467  else
468  m_camera.Gamma.SetValue(1);
469  return m_camera.Gamma.GetValue();
470  }
471  else
472  throw vpException(vpException::notImplementedError, "Don't know how to set gamma.");
473 }
474 
486 bool vpPylonGrabberUsb::saveUserSet(UserSetName user_set, bool set_default)
487 {
488  connect();
489 
490  bool success = selectUserSet(user_set);
491 
492  if (success) {
493  m_camera.UserSetSave.Execute();
494  vpTime::wait(200); // How long you have to wait?
495  success = m_camera.UserSetSave.IsDone();
496  }
497 
498  if (success && set_default)
499  success = setUserSetDefault(user_set);
500 
501  return success;
502 }
503 
514 {
515  connect();
516 
517  switch (user_set) {
518  case USERSET_DEFAULT:
519  m_camera.UserSetDefault.SetValue(Basler_UsbCameraParams::UserSetDefault_Default);
520  return true;
521  break;
522  case USERSET_USERSET1:
523  m_camera.UserSetDefault.SetValue(Basler_UsbCameraParams::UserSetDefault_UserSet1);
524  return true;
525  break;
526  case USERSET_USERSET2:
527  m_camera.UserSetDefault.SetValue(Basler_UsbCameraParams::UserSetDefault_UserSet2);
528  return true;
529  break;
530  case USERSET_USERSET3:
531  m_camera.UserSetDefault.SetValue(Basler_UsbCameraParams::UserSetDefault_UserSet3);
532  return true;
533  break;
534  default:
535  return false;
536  }
537 }
538 
545 {
546  connect();
547 
548  if (!m_camera.IsGrabbing()) {
549  m_camera.StartGrabbing(1);
550  }
551  if (m_connected && m_camera.IsGrabbing())
552  init = true;
553  else
554  init = false;
555 }
556 
563 {
564  if (m_camera.IsGrabbing()) {
565  m_camera.StopGrabbing();
566  }
567  if (m_connected && m_camera.IsGrabbing())
568  init = true;
569  else
570  init = false;
571 }
572 
579 {
580  if (m_connected == false) {
581  m_numCameras = getNumCameras();
582  if (m_numCameras == 0) {
583  throw(vpException(vpException::fatalError, "No camera found"));
584  }
585 
586  if (!m_camera.IsPylonDeviceAttached()) {
587  Pylon::CTlFactory &TlFactory = Pylon::CTlFactory::GetInstance();
588  Pylon::DeviceInfoList_t lstDevices;
589  Pylon::DeviceInfoList_t filter; // Filter for USB cameras.
590  Pylon::CBaslerUsbDeviceInfo usb_devinfo;
591  filter.push_back(usb_devinfo);
592  TlFactory.EnumerateDevices(lstDevices, filter);
593 
594  m_camera.Attach(TlFactory.CreateDevice(lstDevices[m_index]));
595  }
596  // Connect to a camera
597  m_camera.Open();
598  m_connected = true;
599  }
600  if (m_connected && m_camera.IsGrabbing())
601  init = true;
602  else
603  init = false;
604 }
605 
612 {
613  if (m_connected == true) {
614  m_camera.Close();
615  m_connected = false;
616  }
617  if (m_connected && m_camera.IsGrabbing())
618  init = true;
619  else
620  init = false;
621 }
622 
632 {
633  stopCapture();
634  disconnect();
635 }
636 
643 {
644  open();
645 
646  Pylon::CGrabResultPtr grabResult;
647  // Retrieve an image
648  if (!m_camera.RetrieveResult(2000, grabResult)) {
649  throw(vpException(vpException::fatalError, "Cannot retrieve image from camera with serial %s",
650  getCameraSerial(m_index).c_str()));
651  }
652 
653  if (grabResult->GrabSucceeded()) {
654  height = grabResult->GetHeight();
655  width = grabResult->GetWidth();
656  I.resize(height, width);
657 
658  Pylon::CImageFormatConverter imageConvert;
659  imageConvert.OutputPixelFormat = Pylon::PixelType_Mono8;
660  imageConvert.OutputPaddingX = 0;
661  // Create a converted image
662  imageConvert.Convert(I.bitmap, sizeof(unsigned char) * width * height, (Pylon::IImage &)grabResult);
663  }
664 }
665 
672 {
673  open();
674 
675  Pylon::CGrabResultPtr grabResult;
676  // Retrieve an image
677  if (!m_camera.RetrieveResult(2000, grabResult)) {
678  throw(vpException(vpException::fatalError, "Cannot retrieve image from camera with serial %s",
679  getCameraSerial(m_index).c_str()));
680  }
681 
682  if (grabResult->GrabSucceeded()) {
683  height = grabResult->GetHeight();
684  width = grabResult->GetWidth();
685  I.resize(height, width);
686 
687  Pylon::CImageFormatConverter imageConvert;
688  imageConvert.OutputPixelFormat = Pylon::PixelType_BGRA8packed;
689  imageConvert.OutputPaddingX = 0;
690  // Create a converted image
691  Pylon::CPylonImage destImage;
692  imageConvert.Convert(destImage, (Pylon::IImage &)grabResult);
693  Pylon::SBGRA8Pixel *pixel = (Pylon::SBGRA8Pixel *)destImage.GetBuffer();
694  for (unsigned int i = 0; i < height; i++) {
695  for (unsigned int j = 0; j < width; j++) {
696  unsigned int p_index = i * width + j;
697  I[i][j].R = pixel[p_index].R;
698  I[i][j].G = pixel[p_index].G;
699  I[i][j].B = pixel[p_index].B;
700  I[i][j].A = pixel[p_index].A;
701  }
702  }
703  }
704 }
705 
711 {
712  open();
713  acquire(I);
714 }
715 
721 {
722  open();
723  acquire(I);
724 }
725 
738 {
739  connect();
740  startCapture();
741 }
742 
752 {
753  connect();
754 
755  switch (user_set) {
756  case USERSET_DEFAULT:
757  m_camera.UserSetSelector.SetValue(Basler_UsbCameraParams::UserSetSelector_Default);
758  return true;
759  break;
760  case USERSET_USERSET1:
761  m_camera.UserSetSelector.SetValue(Basler_UsbCameraParams::UserSetSelector_UserSet1);
762  return true;
763  break;
764  case USERSET_USERSET2:
765  m_camera.UserSetSelector.SetValue(Basler_UsbCameraParams::UserSetSelector_UserSet2);
766  return true;
767  break;
768  case USERSET_USERSET3:
769  m_camera.UserSetSelector.SetValue(Basler_UsbCameraParams::UserSetSelector_UserSet3);
770  return true;
771  break;
772  default:
773  return false;
774  }
775 }
776 
782 {
783  acquire(I);
784  return *this;
785 }
786 
792 {
793  acquire(I);
794  return *this;
795 }
796 END_VISP_NAMESPACE
797 #else
798 // Work around to avoid warning:
799 // libvisp_pylon.a(vpPylonGrabberUsb.cpp.o) has no symbols
800 void dummy_vpPylonGrabberUsb() { };
801 #endif // #ifdef VISP_HAVE_PYLON
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:73
@ notImplementedError
Not implemented.
Definition: vpException.h:69
@ fatalError
Fatal error.
Definition: vpException.h:72
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:542
Type * bitmap
points toward the bitmap
Definition: vpImage.h:135
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)