Visual Servoing Platform version 3.5.0
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
55vpPylonGrabberGigE::vpPylonGrabberGigE() : m_camera(), m_index(0), m_numCameras(0), m_connected(false)
56{
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
86std::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
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
222std::string vpPylonGrabberGigE::getCameraSerial(unsigned int index)
223{
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
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
329void 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
348float 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
370float 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
403float 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
434float 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
470float 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
495bool 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
809void dummy_vpPylonGrabberGigE(){};
810#endif // #ifdef VISP_HAVE_PYLON
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:97
@ notImplementedError
Not implemented.
Definition: vpException.h:93
@ fatalError
Fatal error.
Definition: vpException.h:96
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:800
Type * bitmap
points toward the bitmap
Definition: vpImage.h:143
void close()
Stop active camera capturing images and disconnect the active camera.
void setCameraIndex(unsigned int index)
bool loadUserSet(UserSetName user_set)
Loads the selected configuration into the camera's volatile memory and makes it the active configurat...
float setBlackLevel(float blacklevel_value=0)
std::string getCameraSerial(unsigned int index)
bool setUserSetDefault(UserSetName user_set)
Sets the configuration set to be used as the default startup set.
Pylon::CInstantCamera * getCameraHandler()
void acquire(vpImage< unsigned char > &I)
unsigned int getNumCameras()
float setExposure(bool exposure_on, bool exposure_auto, float exposure_value=0)
void setCameraSerial(const std::string &serial)
UserSetName getUserSetDefault()
Gets the configuration set being used as the default startup set.
float setGamma(bool gamma_on, float gamma_value=1)
float setFrameRate(float frame_rate)
bool selectUserSet(UserSetName user_set)
Selects the configuration set to load, save, or configure.
vpPylonGrabber & operator>>(vpImage< unsigned char > &I)
std::ostream & getCameraInfo(std::ostream &os)
float setGain(bool gain_auto, float gain_value=0)
bool saveUserSet(UserSetName user_set, bool set_default=false)
Saves the current active configuration set into the selected user set.
@ 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)