Spinnaker SDK C++
4.1.0.338
 
 

 
Loading...
Searching...
No Matches
Trigger.cpp

Trigger.cpp shows how to trigger the camera.

Trigger.cpp shows how to trigger the camera. It relies on information provided in the Enumeration, Acquisition, and NodeMapInfo examples.

It can also be helpful to familiarize yourself with the ImageFormatControl and Exposure examples. As they are somewhat shorter and simpler, either provides a strong introduction to camera customization.

This example shows the process of configuring, using, and cleaning up a camera for use with both a software and a hardware trigger.

Please leave us feedback at: https://www.surveymonkey.com/r/TDYMVAPI More source code examples at: https://github.com/Teledyne-MV/Spinnaker-Examples Need help? Check out our forum at: https://teledynevisionsolutions.zendesk.com/hc/en-us/community/topics

//=============================================================================
// Copyright (c) 2024 FLIR Integrated Imaging Solutions, Inc. All Rights Reserved.
//
// This software is the confidential and proprietary information of FLIR
// Integrated Imaging Solutions, Inc. ("Confidential Information"). You
// shall not disclose such Confidential Information and shall use it only in
// accordance with the terms of the license agreement you entered into
// with FLIR Integrated Imaging Solutions, Inc. (FLIR).
//
// FLIR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
// SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE, OR NON-INFRINGEMENT. FLIR SHALL NOT BE LIABLE FOR ANY DAMAGES
// SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
// THIS SOFTWARE OR ITS DERIVATIVES.
//=============================================================================
#include "Spinnaker.h"
#include <iostream>
#include <sstream>
using namespace Spinnaker;
using namespace Spinnaker::GenApi;
using namespace Spinnaker::GenICam;
using namespace std;
// Use the following enum and global constant to select whether a software or
// hardware trigger is used.
{
};
// This function configures the camera to use a trigger. First, trigger mode is
// set to off in order to select the trigger source. Once the trigger source
// has been selected, trigger mode is then enabled, which has the camera
// capture only a single image upon the execution of the chosen trigger.
int ConfigureTrigger(INodeMap& nodeMap)
{
int result = 0;
cout << endl << endl << "*** CONFIGURING TRIGGER ***" << endl << endl;
cout << "Note that if the application / user software triggers faster than frame time, the trigger may be dropped "
"/ skipped by the camera."
<< endl
<< "If several frames are needed per trigger, a more reliable alternative for such case, is to use the "
"multi-frame mode."
<< endl
<< endl;
{
cout << "Software trigger chosen..." << endl;
}
else if (chosenTrigger == HARDWARE)
{
cout << "Hardware trigger chosen..." << endl;
}
try
{
//
// Ensure trigger mode off
//
// *** NOTES ***
// The trigger must be disabled in order to configure whether the source
// is software or hardware.
//
CEnumerationPtr ptrTriggerMode = nodeMap.GetNode("TriggerMode");
if (!IsReadable(ptrTriggerMode))
{
cout << "Unable to disable trigger mode (node retrieval). Aborting..." << endl;
return -1;
}
CEnumEntryPtr ptrTriggerModeOff = ptrTriggerMode->GetEntryByName("Off");
if (!IsReadable(ptrTriggerModeOff))
{
cout << "Unable to disable trigger mode (enum entry retrieval). Aborting..." << endl;
return -1;
}
ptrTriggerMode->SetIntValue(ptrTriggerModeOff->GetValue());
cout << "Trigger mode disabled..." << endl;
//
// Set TriggerSelector to FrameStart
//
// *** NOTES ***
// For this example, the trigger selector should be set to frame start.
// This is the default for most cameras.
//
CEnumerationPtr ptrTriggerSelector = nodeMap.GetNode("TriggerSelector");
if (!IsReadable(ptrTriggerSelector) ||
!IsWritable(ptrTriggerSelector))
{
cout << "Unable to get or set trigger selector (node retrieval). Aborting..." << endl;
return -1;
}
CEnumEntryPtr ptrTriggerSelectorFrameStart = ptrTriggerSelector->GetEntryByName("FrameStart");
if (!IsReadable(ptrTriggerSelectorFrameStart))
{
cout << "Unable to get trigger selector (enum entry retrieval). Aborting..." << endl;
return -1;
}
ptrTriggerSelector->SetIntValue(ptrTriggerSelectorFrameStart->GetValue());
cout << "Trigger selector set to frame start..." << endl;
//
// Select trigger source
//
// *** NOTES ***
// The trigger source must be set to hardware or software while trigger
// mode is off.
//
CEnumerationPtr ptrTriggerSource = nodeMap.GetNode("TriggerSource");
if (!IsReadable(ptrTriggerSource) ||
!IsWritable(ptrTriggerSource))
{
cout << "Unable to get or set trigger mode (node retrieval). Aborting..." << endl;
return -1;
}
{
// Set trigger mode to software
CEnumEntryPtr ptrTriggerSourceSoftware = ptrTriggerSource->GetEntryByName("Software");
if (!IsReadable(ptrTriggerSourceSoftware))
{
cout << "Unable to set trigger mode (enum entry retrieval). Aborting..." << endl;
return -1;
}
ptrTriggerSource->SetIntValue(ptrTriggerSourceSoftware->GetValue());
cout << "Trigger source set to software..." << endl;
}
else if (chosenTrigger == HARDWARE)
{
// Set trigger mode to hardware ('Line0')
CEnumEntryPtr ptrTriggerSourceHardware = ptrTriggerSource->GetEntryByName("Line0");
if (!IsReadable(ptrTriggerSourceHardware))
{
cout << "Unable to set trigger mode (enum entry retrieval). Aborting..." << endl;
return -1;
}
ptrTriggerSource->SetIntValue(ptrTriggerSourceHardware->GetValue());
cout << "Trigger source set to hardware..." << endl;
}
//
// Turn trigger mode on
//
// *** LATER ***
// Once the appropriate trigger source has been set, turn trigger mode
// on in order to retrieve images using the trigger.
//
CEnumEntryPtr ptrTriggerModeOn = ptrTriggerMode->GetEntryByName("On");
if (!IsReadable(ptrTriggerModeOn))
{
cout << "Unable to enable trigger mode (enum entry retrieval). Aborting..." << endl;
return -1;
}
ptrTriggerMode->SetIntValue(ptrTriggerModeOn->GetValue());
// NOTE: Blackfly and Flea3 GEV cameras need 1 second delay after trigger mode is turned on
cout << "Trigger mode turned back on..." << endl << endl;
}
{
cout << "Error: " << e.what() << endl;
result = -1;
}
return result;
}
// This function retrieves a single image using the trigger. In this example,
// only a single image is captured and made available for acquisition - as such,
// attempting to acquire two images for a single trigger execution would cause
// the example to hang. This is different from other examples, whereby a
// constant stream of images are being captured and made available for image
// acquisition.
int GrabNextImageByTrigger(INodeMap& nodeMap, CameraPtr pCam)
{
int result = 0;
try
{
//
// Use trigger to capture image
//
// *** NOTES ***
// The software trigger only feigns being executed by the Enter key;
// what might not be immediately apparent is that there is not a
// continuous stream of images being captured; in other examples that
// acquire images, the camera captures a continuous stream of images.
// When an image is retrieved, it is plucked from the stream.
//
{
// Get user input
cout << "Press the Enter key to initiate software trigger." << endl;
getchar();
// Execute software trigger
CCommandPtr ptrSoftwareTriggerCommand = nodeMap.GetNode("TriggerSoftware");
if (!IsWritable(ptrSoftwareTriggerCommand))
{
cout << "Unable to execute trigger. Aborting..." << endl;
return -1;
}
ptrSoftwareTriggerCommand->Execute();
// NOTE: Blackfly and Flea3 GEV cameras need 2 second delay after software trigger
}
else if (chosenTrigger == HARDWARE)
{
// Execute hardware trigger
cout << "Use the hardware to trigger image acquisition." << endl;
}
}
{
cout << "Error: " << e.what() << endl;
result = -1;
}
return result;
}
// This function returns the camera to a normal state by turning off trigger
// mode.
int ResetTrigger(INodeMap& nodeMap)
{
int result = 0;
try
{
//
// Turn trigger mode back off
//
// *** NOTES ***
// Once all images have been captured, turn trigger mode back off to
// restore the camera to a clean state.
//
CEnumerationPtr ptrTriggerMode = nodeMap.GetNode("TriggerMode");
if (!IsReadable(ptrTriggerMode))
{
cout << "Unable to disable trigger mode (node retrieval). Non-fatal error..." << endl;
return -1;
}
CEnumEntryPtr ptrTriggerModeOff = ptrTriggerMode->GetEntryByName("Off");
if (!IsReadable(ptrTriggerModeOff))
{
cout << "Unable to disable trigger mode (enum entry retrieval). Non-fatal error..." << endl;
return -1;
}
ptrTriggerMode->SetIntValue(ptrTriggerModeOff->GetValue());
cout << "Trigger mode disabled..." << endl << endl;
}
{
cout << "Error: " << e.what() << endl;
result = -1;
}
return result;
}
// This function prints the device information of the camera from the transport
// layer; please see NodeMapInfo example for more in-depth comments on printing
// device information from the nodemap.
int PrintDeviceInfo(INodeMap& nodeMap)
{
int result = 0;
cout << endl << "*** DEVICE INFORMATION ***" << endl << endl;
try
{
FeatureList_t features;
CCategoryPtr category = nodeMap.GetNode("DeviceInformation");
if (IsReadable(category))
{
category->GetFeatures(features);
FeatureList_t::const_iterator it;
for (it = features.begin(); it != features.end(); ++it)
{
CNodePtr pfeatureNode = *it;
cout << pfeatureNode->GetName() << " : ";
CValuePtr pValue = (CValuePtr)pfeatureNode;
cout << (IsReadable(pValue) ? pValue->ToString() : "Node not readable");
cout << endl;
}
}
else
{
cout << "Device control information not readable." << endl;
}
}
{
cout << "Error: " << e.what() << endl;
result = -1;
}
return result;
}
// This function acquires and saves 10 images from a device; please see
// Acquisition example for more in-depth comments on acquiring images.
int AcquireImages(CameraPtr pCam, INodeMap& nodeMap, INodeMap& nodeMapTLDevice)
{
int result = 0;
cout << endl << "*** IMAGE ACQUISITION ***" << endl << endl;
try
{
// Set acquisition mode to continuous
CEnumerationPtr ptrAcquisitionMode = nodeMap.GetNode("AcquisitionMode");
if (!IsReadable(ptrAcquisitionMode) ||
!IsWritable(ptrAcquisitionMode))
{
cout << "Unable to get or set acquisition mode to continuous (node retrieval). Aborting..." << endl << endl;
return -1;
}
CEnumEntryPtr ptrAcquisitionModeContinuous = ptrAcquisitionMode->GetEntryByName("Continuous");
if (!IsReadable(ptrAcquisitionModeContinuous))
{
cout << "Unable to get acquisition mode to continuous (entry 'continuous' retrieval). Aborting..." << endl
<< endl;
return -1;
}
int64_t acquisitionModeContinuous = ptrAcquisitionModeContinuous->GetValue();
ptrAcquisitionMode->SetIntValue(acquisitionModeContinuous);
cout << "Acquisition mode set to continuous..." << endl;
// Begin acquiring images
pCam->BeginAcquisition();
cout << "Acquiring images..." << endl;
// Retrieve device serial number for filename
gcstring deviceSerialNumber("");
CStringPtr ptrStringSerial = nodeMapTLDevice.GetNode("DeviceSerialNumber");
if (IsReadable(ptrStringSerial))
{
deviceSerialNumber = ptrStringSerial->GetValue();
cout << "Device serial number retrieved as " << deviceSerialNumber << "..." << endl;
}
cout << endl;
// Retrieve, convert, and save images
const int unsigned k_numImages = 10;
//
// Create ImageProcessor instance for post processing images
//
ImageProcessor processor;
//
// Set default image processor color processing method
//
// *** NOTES ***
// By default, if no specific color processing algorithm is set, the image
// processor will default to NEAREST_NEIGHBOR method.
//
processor.SetColorProcessing(SPINNAKER_COLOR_PROCESSING_ALGORITHM_HQ_LINEAR);
for (unsigned int imageCnt = 0; imageCnt < k_numImages; imageCnt++)
{
try
{
// Retrieve the next image from the trigger
result = result | GrabNextImageByTrigger(nodeMap, pCam);
// Retrieve the next received image
ImagePtr pResultImage = pCam->GetNextImage(1000);
if (pResultImage->IsIncomplete())
{
cout << "Image incomplete with image status " << pResultImage->GetImageStatus() << "..." << endl
<< endl;
}
else
{
// Print image information
cout << "Grabbed image " << imageCnt << ", width = " << pResultImage->GetWidth()
<< ", height = " << pResultImage->GetHeight() << endl;
// Convert image to mono 8
ImagePtr convertedImage = processor.Convert(pResultImage, PixelFormat_Mono8);
// Create a unique filename
ostringstream filename;
filename << "Trigger-";
if (deviceSerialNumber != "")
{
filename << deviceSerialNumber.c_str() << "-";
}
filename << imageCnt << ".jpg";
// Save image
convertedImage->Save(filename.str().c_str());
cout << "Image saved at " << filename.str() << endl;
}
// Release image
pResultImage->Release();
cout << endl;
}
{
cout << "Error: " << e.what() << endl;
result = -1;
}
}
// End acquisition
pCam->EndAcquisition();
}
{
cout << "Error: " << e.what() << endl;
result = -1;
}
return result;
}
// This function acts as the body of the example; please see NodeMapInfo example
// for more in-depth comments on setting up cameras.
{
int result = 0;
int err = 0;
try
{
// Retrieve TL device nodemap and print device information
INodeMap& nodeMapTLDevice = pCam->GetTLDeviceNodeMap();
result = PrintDeviceInfo(nodeMapTLDevice);
// Initialize camera
pCam->Init();
// Retrieve GenICam nodemap
INodeMap& nodeMap = pCam->GetNodeMap();
// Configure trigger
err = ConfigureTrigger(nodeMap);
if (err < 0)
{
return err;
}
// Acquire images
result = result | AcquireImages(pCam, nodeMap, nodeMapTLDevice);
// Reset trigger
result = result | ResetTrigger(nodeMap);
// Deinitialize camera
pCam->DeInit();
}
{
cout << "Error: " << e.what() << endl;
result = -1;
}
return result;
}
// Example entry point; please see Enumeration example for more in-depth
// comments on preparing and cleaning up the system.
int main(int /*argc*/, char** /*argv*/)
{
// Since this application saves images in the current folder
// we must ensure that we have permission to write to this folder.
// If we do not have permission, fail right away.
FILE* tempFile = fopen("test.txt", "w+");
if (tempFile == nullptr)
{
cout << "Failed to create file in current folder. Please check "
"permissions."
<< endl;
cout << "Press Enter to exit..." << endl;
getchar();
return -1;
}
fclose(tempFile);
remove("test.txt");
int result = 0;
// Print application build information
cout << "Application build date: " << __DATE__ << " " << __TIME__ << endl << endl;
// Retrieve singleton reference to system object
SystemPtr system = System::GetInstance();
// Print out current library version
const LibraryVersion spinnakerLibraryVersion = system->GetLibraryVersion();
cout << "Spinnaker library version: " << spinnakerLibraryVersion.major << "." << spinnakerLibraryVersion.minor
<< "." << spinnakerLibraryVersion.type << "." << spinnakerLibraryVersion.build << endl
<< endl;
// Retrieve list of cameras from the system
CameraList camList = system->GetCameras();
unsigned int numCameras = camList.GetSize();
cout << "Number of cameras detected: " << numCameras << endl << endl;
// Finish if there are no cameras
if (numCameras == 0)
{
// Clear camera list before releasing system
camList.Clear();
// Release system
system->ReleaseInstance();
cout << "Not enough cameras!" << endl;
cout << "Done! Press Enter to exit..." << endl;
getchar();
return -1;
}
// Run example on each camera
for (unsigned int i = 0; i < numCameras; i++)
{
cout << endl << "Running example for camera " << i << "..." << endl;
result = result | RunSingleCamera(camList.GetByIndex(i));
cout << "Camera " << i << " example complete..." << endl << endl;
}
// Clear camera list before releasing system
camList.Clear();
// Release system
system->ReleaseInstance();
cout << endl << "Done! Press Enter to exit..." << endl;
getchar();
return result;
}
int AcquireImages(CameraPtr pCam, INodeMap &nodeMap, INodeMap &nodeMapTLDevice)
Definition Acquisition.cpp:199
int main(int, char **)
Definition Acquisition.cpp:527
int RunSingleCamera(CameraPtr pCam)
Definition Acquisition.cpp:479
int PrintDeviceInfo(INodeMap &nodeMap)
Definition Acquisition.cpp:441
const unsigned int k_numImages
Definition AcquisitionMultipleCamerasWriteToFile.cpp:55
int ConfigureTrigger(INodeMap &nodeMap)
Definition BufferHandling.cpp:103
int GrabNextImageByTrigger(INodeMap &nodeMap)
Definition BufferHandling.cpp:170
int ResetTrigger(INodeMap &nodeMap)
Definition BufferHandling.cpp:197
triggerType
Definition Trigger.cpp:49
@ SOFTWARE
Definition Trigger.cpp:50
@ HARDWARE
Definition Trigger.cpp:51
const triggerType chosenTrigger
Definition Trigger.cpp:54
Used to hold a list of camera objects.
Definition CameraList.h:42
void Clear()
Clears the list of cameras and destroys their corresponding reference counted objects.
CameraPtr GetByIndex(unsigned int index) const
Returns a pointer to a camera object at the "index".
unsigned int GetSize() const
Returns the size of the camera list.
A reference tracked pointer to a camera object.
Definition CameraPtr.h:44
The Exception object represents an error that is returned from the library.
Definition Exception.h:51
virtual const char * what() const
virtual override for what().
Encapsulates a GenApi pointer dealing with the dynamic_cast automatically.
Definition Pointer.h:75
Definition GCString.h:43
Image post processing class for converting a source image to another pixel format.
Definition ImageProcessor.h:159
void SetColorProcessing(ColorProcessingAlgorithm colorAlgorithm)
Sets the color processing algorithm used at the time of the Convert() call, therefore the most recent...
ImagePtr Convert(const ImagePtr &srcImage, PixelFormatEnums destFormat) const
Converts the source image buffer to the specified destination pixel format and returns the result in ...
A reference tracked pointer to an image object.
Definition ImagePtr.h:46
A reference tracked pointer to a system object.
Definition SystemPtr.h:44
bool IsWritable(EAccessMode AccessMode)
Tests if writable.
Definition INode.h:277
bool IsReadable(EAccessMode AccessMode)
Tests if readable.
Definition INode.h:253
interface SPINNAKER_API_ABSTRACT INodeMap
Interface to access the node map.
Definition INodeMap.h:54
Definition Autovector.h:36
Definition GCString.h:31
Definition BasePtr.h:24
Provides easier access to the current version of Spinnaker.
Definition SpinnakerDefs.h:658
unsigned int minor
Minor version of the library.
Definition SpinnakerDefs.h:663
unsigned int major
Major version of the library.
Definition SpinnakerDefs.h:660
unsigned int type
Version type of the library.
Definition SpinnakerDefs.h:666
unsigned int build
Build number of the library.
Definition SpinnakerDefs.h:669