The GenICamCommonSettingsUsage example is intended as an example for people who do not have that much experience with the Impact Acquire SDK or did not use the classes which wrap the GenICam™ properties of a device yet. It shows the basic procedure of handling device settings, how a device is being configured with the most common settings and which steps are important to configure a device in an efficient way.
At first the Default UserSet is loaded to make sure the device works on a specific set of settings before starting. This is a good idea once you want to bring the device to a defined state after using different settings e.g. once you used different software before.
In the next step the exposure time is modified after it is verified that the property is supported by the device and it is currently writable.
Afterwards the AOI of the device is set to half of the sensor's size.
To simulate an external trigger the timers of the device are used to generate trigger signals for the device. Since it is possible that not every device supports as much timers or TimerTriggerSource
values, some more complex checks are necessary to make sure everything works as expected.
cout << endl;
cout << "To avoid some cabling work, we will use an internal timer for triggering in this sample!" << endl;
cout << "The trigger frequency will be configured to half of the max frequency the sensor would be capable of in your setup." << endl;
vector<string> availableTimers;
if( ctc.timerSelector.isValid() )
{
ctc.timerSelector.getTranslationDictStrings( availableTimers );
}
if( ctc.timerSelector.isValid() && ctc.timerSelector.isWriteable() && ( availableTimers.size() >= 2 ) && acq.triggerSelector.isValid() && acq.mvResultingFrameRate.isValid() )
{
ctc.timerSelector.writeS( "Timer1" );
vector<string> availableTriggerSources;
ctc.timerTriggerSource.getTranslationDictStrings( availableTriggerSources );
if( find( availableTriggerSources.begin(), availableTriggerSources.end(), "Timer2End" ) != availableTriggerSources.end() && acq.mvResultingFrameRate.isValid() )
{
const double dPeriod = 1000000. / ( acq.mvResultingFrameRate.read() / 2. );
if( dPeriod >= 300. )
{
ctc.timerDuration.write( 1000. );
ctc.timerTriggerSource.writeS( "Timer2End" );
ctc.timerTriggerSource.writeS( "Timer1End" );
ctc.timerSelector.writeS( "Timer2" );
ctc.timerDuration.write( dPeriod - 1000. );
acq.triggerSelector.writeS( "FrameStart" );
acq.triggerSource.writeS( "Timer1Start" );
acq.triggerMode.writeS( "On" );
}
}
else
{
cout << "This device does not support expected timer trigger sources! The device will work in free run mode instead!" << endl;
}
}
else
{
cout << "This device does not support timers! The device will work in free run mode instead!" << endl;
}
Category that contains the Counter and Timer control features.
Definition mvIMPACT_acquire_GenICam.h:4294
The next step shows how the analog gain of the device's sensor can be modified. In this sample the value is set to its maximum.
As the last configuration step the digital I/Os of the device are shown and summarized by iterating over all string elements within the property lineSelector
which defines the input or output line of the digital I/Os. The first digital output is configured to use the mvExposureAndAcquisitionActive signal to make sure the digital output is set to 'high' once the device acquires images and exposes one.
#include <iostream>
#include <ios>
#include <memory>
#include <sstream>
#include <thread>
#include <apps/Common/exampleHelper.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire_GenICam.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire_helper.h>
#ifdef _WIN32
# include <mvDisplay/Include/mvIMPACT_acquire_display.h>
# define USE_DISPLAY
#else
# include <stdio.h>
# include <unistd.h>
#endif
using namespace std;
struct ThreadParameter
{
unsigned int requestsCaptured_;
#ifdef USE_DISPLAY
#endif
#ifdef USE_DISPLAY
, displayWindow_(
"mvIMPACT_acquire sample, Device " + pDev_->
serial.
read() )
#endif
{}
ThreadParameter( const ThreadParameter& src ) = delete;
ThreadParameter& operator=( const ThreadParameter& rhs ) = delete;
};
static bool canRestoreFactoryDefault(
Device* pDev )
{
if( !usc.userSetSelector.isValid() || !usc.userSetLoad.isValid() )
{
return false;
}
vector<string> validUserSetSelectorStrings;
usc.userSetSelector.getTranslationDictStrings( validUserSetSelectorStrings );
return find( validUserSetSelectorStrings.begin(), validUserSetSelectorStrings.end(), "Default" ) != validUserSetSelectorStrings.end();
}
void myThreadCallback( shared_ptr<Request> pRequest, ThreadParameter& threadParameter )
{
++threadParameter.requestsCaptured_;
if( threadParameter.requestsCaptured_ % 100 == 0 )
{
const Statistics& s = threadParameter.statistics_;
cout << "Info from " << threadParameter.pDev_->serial.read()
<< ", LineStatusAll: " << threadParameter.dio_.lineStatusAll.read() << endl;
}
if( pRequest->isOK() )
{
#ifdef USE_DISPLAY
threadParameter.displayWindow_.GetImageDisplay().SetImage( pRequest );
threadParameter.displayWindow_.GetImageDisplay().Update();
#else
cout << "Image captured: " << pRequest->imageOffsetX.read() << "x" << pRequest->imageOffsetY.read() << "@" << pRequest->imageWidth.read() << "x" << pRequest->imageHeight.read() << endl;
#endif
}
else
{
cout << "Error: " << pRequest->requestResult.readS() << endl;
}
}
bool isDeviceSupportedBySample(
const Device*
const pDev )
{
{
return false;
}
vector<TDeviceInterfaceLayout> availableInterfaceLayouts;
return find( availableInterfaceLayouts.begin(), availableInterfaceLayouts.end(), dilGenICam ) != availableInterfaceLayouts.end();
}
int main( void )
{
cout << "--------------------------------------------!!! ATTENTION !!!--------------------------------------------" << endl;
cout << "Please be aware that the digital outputs of the device might be enabled during the test." << endl
<< "This might lead to unexpected behavior in case of devices which are connected to one of the digital outputs," << endl
<< "so only proceed if you are sure that this will not cause any issue with connected hardware!!" << endl;
cout << "---------------------------------------------------------------------------------------------------------" << endl;
cout << "" << endl;
Device* pDev = getDeviceFromUserInput( devMgr, isDeviceSupportedBySample );
if( pDev == nullptr )
{
cout << "Unable to continue! Press [ENTER] to end the application" << endl;
cin.get();
return 1;
}
cout << "Initialising the device. This might take some time..." << endl;
cout << endl;
try
{
}
{
cout <<
"An error occurred while opening the device " << pDev->
serial.
read()
<< "Press [ENTER] to end the application..." << endl;
cin.get();
return 1;
}
cout << "The device will be configured now!\n" << endl;
if( canRestoreFactoryDefault( pDev ) )
{
if( usc.userSetSelector.isValid() && usc.userSetSelector.isWriteable() && usc.userSetLoad.isValid() && usc.userSetLoad.isMeth() )
{
cout << "Loading the device's default user set to avoid undefined settings!\n" << endl;
usc.userSetSelector.writeS( "Default" );
usc.userSetLoad.call();
}
}
else
{
cout << "The device seems not to support the default user set!" << endl;
}
const double dExposureTime = {10000.};
if( acq.exposureTime.isValid() && acq.exposureTime.isWriteable() )
{
cout << "Currently the exposure time is set to " << acq.exposureTime.read() << " us. Changing to " << dExposureTime << " us" << endl;
cout << endl;
acq.exposureTime.write( dExposureTime );
}
if( ifc.width.isValid() && ifc.height.isValid() )
{
cout << "The sensor has a max resolution of about " << ifc.width.getMaxValue() << "x" << ifc.height.getMaxValue() << " pixels" << endl;
cout << "The resolution will now be adjusted to the half of width and height. The resulting AOI will be: " << ifc.width.getMaxValue() / 2 << "x" << ifc.height.getMaxValue() / 2 << " pixels" << endl;
if( !ifc.width.isWriteable() || !ifc.height.isWriteable() )
{
cout << "Width or Height are not writable at the moment." << endl;
}
else
{
ifc.width.write( ifc.width.getMaxValue() / 2 );
ifc.height.write( ifc.height.getMaxValue() / 2 );
}
}
cout << endl;
cout << "To avoid some cabling work, we will use an internal timer for triggering in this sample!" << endl;
cout << "The trigger frequency will be configured to half of the max frequency the sensor would be capable of in your setup." << endl;
vector<string> availableTimers;
if( ctc.timerSelector.isValid() )
{
ctc.timerSelector.getTranslationDictStrings( availableTimers );
}
if( ctc.timerSelector.isValid() && ctc.timerSelector.isWriteable() && ( availableTimers.size() >= 2 ) && acq.triggerSelector.isValid() && acq.mvResultingFrameRate.isValid() )
{
ctc.timerSelector.writeS( "Timer1" );
vector<string> availableTriggerSources;
ctc.timerTriggerSource.getTranslationDictStrings( availableTriggerSources );
if( find( availableTriggerSources.begin(), availableTriggerSources.end(), "Timer2End" ) != availableTriggerSources.end() && acq.mvResultingFrameRate.isValid() )
{
const double dPeriod = 1000000. / ( acq.mvResultingFrameRate.read() / 2. );
if( dPeriod >= 300. )
{
ctc.timerDuration.write( 1000. );
ctc.timerTriggerSource.writeS( "Timer2End" );
ctc.timerTriggerSource.writeS( "Timer1End" );
ctc.timerSelector.writeS( "Timer2" );
ctc.timerDuration.write( dPeriod - 1000. );
acq.triggerSelector.writeS( "FrameStart" );
acq.triggerSource.writeS( "Timer1Start" );
acq.triggerMode.writeS( "On" );
}
}
else
{
cout << "This device does not support expected timer trigger sources! The device will work in free run mode instead!" << endl;
}
}
else
{
cout << "This device does not support timers! The device will work in free run mode instead!" << endl;
}
if( anc.gain.isValid() && anc.gain.isWriteable() )
{
anc.gain.write( anc.gain.getMaxValue() );
}
cout << "\nAvailable Digital IOs:" << endl;
vector<string> availableIOs;
dio.lineSelector.getTranslationDictStrings( availableIOs );
bool boConfiguredFirstOutput = false;
for( auto& line : availableIOs )
{
dio.lineSelector.writeS( line );
if( !boConfiguredFirstOutput && dio.lineMode.readS() == "Output" )
{
dio.lineSource.writeS( "mvExposureAndAcquisitionActive" );
boConfiguredFirstOutput = true;
}
cout << line << " - " << ( dio.lineMode.isValid() ? dio.lineMode.readS() : string( "UNSUPPORTED" ) )
<< " - LineStatus: " << ( dio.lineStatus.isValid() ? dio.lineStatus.readS() : string( "UNSUPPORTED" ) )
<< " - LineSource: " << ( dio.lineSource.isValid() ? dio.lineSource.readS() : string( "UNSUPPORTED" ) )
<< endl;
}
cout << "Press [ENTER] to end the application" << endl;
ThreadParameter threadParam( pDev, dio );
requestProvider.acquisitionStart( myThreadCallback, std::ref( threadParam ) );
cin.get();
requestProvider.acquisitionStop();
return 0;
}
std::string name(void) const
Returns the name of the component referenced by this object.
Definition mvIMPACT_acquire.h:1206
bool isValid(void) const
Checks if the internal component referenced by this object is still valid.
Definition mvIMPACT_acquire.h:1721
Grants access to devices that can be operated by this software interface.
Definition mvIMPACT_acquire.h:7171
This class and its functions represent an actual device detected by this interface in the current sys...
Definition mvIMPACT_acquire.h:6118
PropertyS serial
A string property (read-only) containing the serial number of this device.
Definition mvIMPACT_acquire.h:6551
void open(void)
Opens a device.
Definition mvIMPACT_acquire.h:6420
PropertyIDeviceInterfaceLayout interfaceLayout
An enumerated integer property which can be used to define which interface layout shall be used when ...
Definition mvIMPACT_acquire.h:6644
PropertyIAcquisitionStartStopBehaviour acquisitionStartStopBehaviour
An enumerated integer property defining the start/stop behaviour during acquisition of this driver in...
Definition mvIMPACT_acquire.h:6800
const EnumPropertyI & getTranslationDictValues(std::vector< ZYX > &sequence) const
This function queries a list of valid values for this property.
Definition mvIMPACT_acquire.h:4266
const EnumPropertyI & write(ZYX value, int index=0) const
Writes one value to the property.
Definition mvIMPACT_acquire.h:4426
Category that contains the User Set control features.
Definition mvIMPACT_acquire_GenICam.h:9632
A base class for exceptions generated by Impact Acquire.
Definition mvIMPACT_acquire.h:256
std::string getErrorCodeAsString(void) const
Returns a string representation of the error associated with the exception.
Definition mvIMPACT_acquire.h:288
std::string read(int index=0) const
Reads a value from a property.
Definition mvIMPACT_acquire.h:5323
std::string readS(int index=0, const std::string &format="") const
Reads data from this property as a string.
Definition mvIMPACT_acquire.h:3340
Contains basic statistical information.
Definition mvIMPACT_acquire.h:14509
PropertyF framesPerSecond
A float property (read-only) containing the current number of frames captured per second.
Definition mvIMPACT_acquire.h:14586
PropertyF captureTime_s
A float property (read-only) containing the overall time an image request spent in the device drivers...
Definition mvIMPACT_acquire.h:14560
PropertyI errorCount
An integer property (read-only) containing the overall count of image requests which returned with an...
Definition mvIMPACT_acquire.h:14568
A class that can be used to display images in a window.
Definition mvIMPACT_acquire_display.h:606
A helper class that can be used to implement a simple continuous acquisition from a device.
Definition mvIMPACT_acquire_helper.h:432
This namespace contains classes and functions belonging to the GenICam specific part of the image acq...
Definition mvIMPACT_acquire.h:23830
This namespace contains classes and functions that can be used to display images.
This namespace contains classes and functions belonging to the image acquisition module of this SDK.
Definition mvCommonDataTypes.h:34