From 4f2d45df6be0b21b9a081bc0806a74a604138930 Mon Sep 17 00:00:00 2001 From: Jan Grewe Date: Wed, 12 Mar 2025 11:01:50 +0100 Subject: [PATCH] [dualcomwrapper] enable software triggering --- dualcamgrabber.cpp | 87 +++++++++++++++++++++++++--------------------- dualcamwrapper.cpp | 28 +++++++++++++-- dualcamwrapper.h | 3 ++ pylonrecorder.cpp | 2 +- 4 files changed, 77 insertions(+), 43 deletions(-) diff --git a/dualcamgrabber.cpp b/dualcamgrabber.cpp index 97ccf92..6fa5c80 100644 --- a/dualcamgrabber.cpp +++ b/dualcamgrabber.cpp @@ -13,46 +13,55 @@ void DualcamGrabber::run() { stop_request = false; size_t counter = 0; - if (wrapper->isOpen()) { - Pylon::CInstantCameraArray &cameras = wrapper->getCameraArray(); - wrapper->frameRate(static_cast(framerate), -1); - wrapper->exposureTime(exposure); - wrapper->gain(gain); + if (!wrapper->isOpen()) { + return; + } - cameras.StartGrabbing(); - Pylon::CGrabResultPtr frame0, frame1; - Pylon::CPylonImage leftImage; - Pylon::CPylonImage rightImage; - Pylon::CPylonImage stitchedImage; - std::string errorMessage = ""; + Pylon::CInstantCameraArray &cameras = wrapper->getCameraArray(); + wrapper->frameRate(static_cast(framerate), -1); + wrapper->exposureTime(exposure); + wrapper->gain(gain); - while (cameras.IsGrabbing() && !stop_request) { - auto before = high_resolution_clock::now(); - try { - cameras[0].RetrieveResult( 5000, frame0, Pylon::TimeoutHandling_ThrowException ); - cameras[1].RetrieveResult( 5000, frame1, Pylon::TimeoutHandling_ThrowException ); - leftImage.AttachGrabResultBuffer( frame0 ); - rightImage.AttachGrabResultBuffer( frame1 ); - } catch(const std::exception& e) { - qDebug() << "Grabbing frame failed! " << e.what(); - } - auto after = high_resolution_clock::now(); - if (leftImage.IsValid() && rightImage.IsValid()) { - try { - StitchImage::StitchToRight(leftImage, rightImage, &stitchedImage, errorMessage); - MyImage *img = new MyImage(stitchedImage.GetWidth(), stitchedImage.GetHeight()); - img->setFrame(stitchedImage); - buffer->push(img); - } catch(const std::exception& e) { - std::cerr << e.what() << '\n'; - } - } - auto stitch = high_resolution_clock::now(); - auto grab_duration = duration_cast(after - before); - auto stitch_duration = duration_cast(stitch - after); - std::cerr << "framecount: " << counter << " grab_duration (us): " << grab_duration.count() << "\t" << " stitching (us): " << stitch_duration.count() << std::endl; - counter += 1; + cameras.StartGrabbing(); + Pylon::CGrabResultPtr frame0, frame1; + Pylon::CPylonImage leftImage; + Pylon::CPylonImage rightImage; + Pylon::CPylonImage stitchedImage; + std::string errorMessage = ""; + + while (cameras.IsGrabbing() && !stop_request) { + auto before = high_resolution_clock::now(); + auto after1 = high_resolution_clock::now(); + try { + cameras[0].RetrieveResult( 5000, frame0, Pylon::TimeoutHandling_ThrowException ); + after1 = high_resolution_clock::now(); + cameras[1].RetrieveResult( 5000, frame1, Pylon::TimeoutHandling_ThrowException ); + leftImage.AttachGrabResultBuffer( frame0 ); + rightImage.AttachGrabResultBuffer( frame1 ); + } catch(const std::exception& e) { + qDebug() << "Grabbing frame failed! " << e.what(); + } + auto after = high_resolution_clock::now(); + if (leftImage.IsValid() && rightImage.IsValid()) { + try { + StitchImage::StitchToRight(leftImage, rightImage, &stitchedImage, errorMessage); + MyImage *img = new MyImage(stitchedImage.GetWidth(), stitchedImage.GetHeight()); + img->setFrame(stitchedImage); + buffer->push(img); + } catch(const std::exception& e) { + std::cerr << e.what() << '\n'; + } } - cameras.StopGrabbing(); - } + auto stitch = high_resolution_clock::now(); + auto grab_duration = duration_cast(after - before); + auto grab1_duration = duration_cast(after1 - before); + auto stitch_duration = duration_cast(stitch - after); + std::cerr << "framecount: " << counter << " grab_duration (us): " << grab_duration.count() << "\t" << " stitching (us): " << stitch_duration.count() << " grab1_duration (us): " << grab1_duration.count() << std::endl; + counter += 1; + auto done = high_resolution_clock::now(); + auto total_duration = duration_cast(done - before); + double rate = (1./((double)total_duration.count()/1000000)); + std::cerr << "total_duration (us): " << total_duration.count() << " rate: " << rate << std::endl; + } + cameras.StopGrabbing(); } diff --git a/dualcamwrapper.cpp b/dualcamwrapper.cpp index 37ff7d8..638655d 100644 --- a/dualcamwrapper.cpp +++ b/dualcamwrapper.cpp @@ -284,7 +284,7 @@ void DualcamWrapper::closeCameras() { } Pylon::CInstantCameraArray &DualcamWrapper::getCameraArray() { - return cameras; + return cameras; } // Pylon::CInstantCamera DualcamWrapper::getCamera(int camindex) { @@ -293,6 +293,28 @@ Pylon::CInstantCameraArray &DualcamWrapper::getCameraArray() { GenApi::INodeMap& DualcamWrapper::getNodemap(int camindex){ - GenApi::INodeMap &nodemap = cameras[camindex].GetNodeMap(); - return nodemap; + GenApi::INodeMap &nodemap = cameras[camindex].GetNodeMap(); + return nodemap; +} + +void DualcamWrapper::enableSoftwareTrigger(int camindex){ + GenApi::INodeMap &nodemap = getNodemap( camindex ); + // Enable triggered image acquisition for the Frame Start trigger + Pylon::CEnumParameter(nodemap, "TriggerMode").SetValue("On"); + // Set the trigger source to Line 1 + Pylon::CEnumParameter(nodemap, "TriggerSource").SetValue("Line1"); + // Set the trigger activation mode to level high + Pylon::CEnumParameter(nodemap, "TriggerActivation").SetValue("LevelHigh"); +} + +void DualcamWrapper::disableSoftwareTrigger(int camindex){ + GenApi::INodeMap& nodemap = getNodemap(camindex); + // Disable triggered image acquisition for the Frame Start trigger + Pylon::CEnumParameter(nodemap, "TriggerMode").SetValue("Off"); +} + +bool DualcamWrapper::softwareTriggerEnabeled(int camindex){ + GenApi::INodeMap& nodemap = getNodemap(camindex); + // Get the current state. + return Pylon::CEnumParameter(nodemap, "TriggerMode").GetValue() == "On"; } \ No newline at end of file diff --git a/dualcamwrapper.h b/dualcamwrapper.h index 7de977e..7200dd9 100644 --- a/dualcamwrapper.h +++ b/dualcamwrapper.h @@ -30,6 +30,9 @@ public: bool exposureTime(double exposure_time, int camindex=-1); double gain(int camindex); bool gain(double gain_db, int camindex=-1); + void enableSoftwareTrigger(int camindex); + void disableSoftwareTrigger(int camindex); + bool softwareTriggerEnabeled(int camindex); Pylon::CInstantCameraArray &getCameraArray(); private: diff --git a/pylonrecorder.cpp b/pylonrecorder.cpp index eb3c785..73383e9 100644 --- a/pylonrecorder.cpp +++ b/pylonrecorder.cpp @@ -684,7 +684,7 @@ void PylonRecorder::connectCamera() { dualcam = new DualcamWrapper(layout); bool success = dualcam->openCameras(message); if (success) { - qDebug()::cerr << "dual camera connected\n"; + qDebug() << "Dual cameras connected"; cameraConnectedLabel->setText("connected"); cameraConnectedLabel->setStyleSheet("QLabel { font-size: 10px;font-family: Arial;color: green;}"); cameraOpened = true;