The sample shows, how to configure the Sequencer Control according to the SFNC (Standard Features Naming Convention) however as the things that can be done using the Sequencer Control are very specific and application dependent this example might not work with every GenICam compliant device as some features are just assumed to be available. Look for these functions:
Finally the sample enters an endless loop that acquires images from "Set 0" and waits for user input to switch to "Set 1" and back.
The user can see that changing the sets worked, as the AOI and the frame rate in the cyclic information print changes once the sets are switched.
#include <array>
#include <iostream>
#include <thread>
#include <apps/Common/exampleHelper.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire_GenICam.h>
#ifdef _WIN32
# include <mvDisplay/Include/mvIMPACT_acquire_display.h>
# define USE_DISPLAY
#endif
using namespace std;
static bool s_boTerminated = false;
static bool s_boSwitchedToSet1 = false;
static void checkedMethodCall(
Device* pDev,
Method& method );
struct SequencerSetParameter
{
const int64_type setNr_;
const double exposureTime_us_;
const int64_type horizontalBinningOrDecimation_;
const int64_type verticalBinningOrDecimation_;
double expectedFrameRate_;
explicit SequencerSetParameter( const int64_type setNr, const double exposureTime_us, const int64_type horizontalBinningOrDecimation, const int64_type verticalBinningOrDecimation ) :
setNr_( setNr ), exposureTime_us_( exposureTime_us ), horizontalBinningOrDecimation_( horizontalBinningOrDecimation ), verticalBinningOrDecimation_( verticalBinningOrDecimation ), expectedFrameRate_( 0.0 ) {}
};
struct ThreadParameter
{
#ifdef USE_DISPLAY
#endif
explicit ThreadParameter(
Device* p ) : pDev( p ), fi( pDev ), statistics( pDev ), ac( pDev ), ifc( pDev ), sc( pDev ), dic( pDev )
#ifdef USE_DISPLAY
, displayWindow( "mvIMPACT_acquire sequencer sample, Device " + p->serial.read() )
#endif
{}
ThreadParameter( const ThreadParameter& src ) = delete;
ThreadParameter& operator=( const ThreadParameter& rhs ) = delete;
};
static array<SequencerSetParameter, 2> s_SequencerData =
{
SequencerSetParameter( 0, 1000., 2, 2 ),
SequencerSetParameter( 1, 200000., 1, 1 ),
};
void checkInput( ThreadParameter* pThreadParameter, const int& in )
{
switch( in )
{
case '1':
if( !s_boSwitchedToSet1 )
{
cout << "Setting UserOutput0 leads to switching to SequencerSet 1..." << endl;
pThreadParameter->dic.userOutputSelector.write( 0 );
pThreadParameter->dic.userOutputValue.write( bTrue );
s_boSwitchedToSet1 = true;
}
cin.get();
break;
case '0':
if( s_boSwitchedToSet1 )
{
cout << "Unsetting UserOutput0 leads to switching back to SequencerSet 0..." << endl;
pThreadParameter->dic.userOutputSelector.write( 0 );
pThreadParameter->dic.userOutputValue.write( bFalse );
s_boSwitchedToSet1 = false;
}
cin.get();
break;
default:
s_boTerminated = true;
break;
}
}
void configureDevice(
Device* pDev )
{
try
{
conditionalSetEnumPropertyByString( usc.userSetSelector, "Default" );
if( result != DMR_NO_ERROR )
{
cout <<
"An error occurred while restoring the factory default for device " << pDev->
serial.
read()
<< "(error code: " << ImpactAcquireException::getErrorCodeAsString( result ) << ")." << endl;
}
conditionalSetEnumPropertyByString( acqc.exposureMode, "Timed" );
conditionalSetEnumPropertyByString( acqc.exposureAuto, "Off" );
conditionalSetEnumPropertyByString( acqc.acquisitionMode, "Continuous" );
if( ac.gainSelector.isValid() )
{
vector<string> validGainSelectorValues;
ac.gainSelector.getTranslationDictStrings( validGainSelectorValues );
for( const auto& validGainSelectorValue : validGainSelectorValues )
{
conditionalSetEnumPropertyByString( ac.gainSelector, validGainSelectorValue );
conditionalSetEnumPropertyByString( ac.gainAuto, "Off" );
}
}
else
{
conditionalSetEnumPropertyByString( ac.gainAuto, "Off" );
}
conditionalSetEnumPropertyByString( acqc.mvAcquisitionFrameRateLimitMode, "mvDeviceMaxSensorThroughput" );
conditionalSetEnumPropertyByString( acqc.mvAcquisitionFrameRateEnable, "Off" );
ss.requestCount.write( 50 );
ip.colorProcessing.write( cpmRaw );
if( ip.tapSortEnable.isValid() )
{
ip.tapSortEnable.write( bFalse );
}
}
{
cout <<
"An error occurred while configuring the device " << pDev->
serial.
read()
<< "Press [ENTER] to end the application..." << endl;
cin.get();
exit( 1 );
}
}
void configureSequencerSet( ThreadParameter* pThreadParameter, const SequencerSetParameter& ssp )
{
pThreadParameter->sc.sequencerSetSelector.write( ssp.setNr_ );
pThreadParameter->ac.exposureTime.write( ssp.exposureTime_us_ );
if( pThreadParameter->ifc.binningHorizontal.isValid() )
{
pThreadParameter->ifc.binningHorizontal.write( ssp.horizontalBinningOrDecimation_ );
}
else if( pThreadParameter->ifc.decimationHorizontal.isValid() )
{
pThreadParameter->ifc.decimationHorizontal.write( ssp.horizontalBinningOrDecimation_ );
}
if( pThreadParameter->ifc.binningVertical.isValid() )
{
pThreadParameter->ifc.binningVertical.write( ssp.verticalBinningOrDecimation_ );
}
else if( pThreadParameter->ifc.decimationVertical.isValid() )
{
pThreadParameter->ifc.decimationVertical.write( ssp.verticalBinningOrDecimation_ );
}
pThreadParameter->ifc.height.write( pThreadParameter->ifc.heightMax.read() );
pThreadParameter->sc.sequencerPathSelector.write( 0LL );
pThreadParameter->sc.sequencerTriggerSource.writeS( "ExposureEnd" );
pThreadParameter->sc.sequencerSetNext.write( 0LL );
pThreadParameter->sc.sequencerPathSelector.write( 1LL );
if( 0 == ssp.setNr_ )
{
pThreadParameter->sc.sequencerTriggerSource.writeS( "UserOutput0" );
pThreadParameter->sc.sequencerTriggerActivation.writeS( "LevelHigh" );
pThreadParameter->sc.sequencerSetNext.write( 1LL );
}
else
{
pThreadParameter->sc.sequencerTriggerSource.writeS( "Off" );
pThreadParameter->sc.sequencerSetNext.write( 0LL );
}
checkedMethodCall( pThreadParameter->pDev, pThreadParameter->sc.sequencerSetSave );
}
void configureSequencer( ThreadParameter* pThreadParameter )
{
try
{
pThreadParameter->sc.sequencerMode.writeS( "Off" );
pThreadParameter->sc.sequencerConfigurationMode.writeS( "On" );
pThreadParameter->sc.sequencerFeatureSelector.writeS( "ExposureTime" );
pThreadParameter->sc.sequencerFeatureEnable.write( bTrue );
pThreadParameter->sc.sequencerFeatureSelector.writeS( "CounterDuration" );
pThreadParameter->sc.sequencerFeatureEnable.write( bFalse );
for_each( s_SequencerData.begin(), s_SequencerData.end(), [pThreadParameter]( SequencerSetParameter & setParameter )
{
configureSequencerSet( pThreadParameter, setParameter );
setParameter.expectedFrameRate_ = pThreadParameter->ac.mvResultingFrameRate.read();
} );
pThreadParameter->sc.sequencerSetStart.write( 0 );
pThreadParameter->sc.sequencerConfigurationMode.writeS( "Off" );
pThreadParameter->sc.sequencerMode.writeS( "On" );
}
{
cout << "An error occurred while setting up the sequencer for device " << pThreadParameter->pDev->serial.read()
s_boTerminated = true;
}
}
{
if( result != DMR_NO_ERROR )
{
cout <<
"An error was returned while calling function '" << method.
displayName() <<
"' on device " << pDev->
serial.
read()
<<
"(" << pDev->
product.
read() <<
"): " << ImpactAcquireException::getErrorCodeAsString( result ) << endl;
}
}
void liveThread( ThreadParameter* pThreadParameter )
{
configureDevice( pThreadParameter->pDev );
configureSequencer( pThreadParameter );
while( ( result =
static_cast<TDMR_ERROR>( pThreadParameter->fi.imageRequestSingle() ) ) == DMR_NO_ERROR ) {};
if( result != DEV_NO_FREE_REQUEST_AVAILABLE )
{
cout << "'FunctionInterface.imageRequestSingle' returned with an unexpected result: " << result
}
manuallyStartAcquisitionIfNeeded( pThreadParameter->pDev, pThreadParameter->fi );
unsigned int cnt = {0};
const unsigned int timeout_ms = 2500;
while( !s_boTerminated )
{
int requestNr = pThreadParameter->fi.imageRequestWaitFor( timeout_ms );
pRequest = pThreadParameter->fi.isRequestNrValid( requestNr ) ? pThreadParameter->fi.getRequest( requestNr ) : nullptr;
if( pRequest != nullptr )
{
{
++cnt;
if( cnt % 100 == 0 )
{
cout << "Info from " << pThreadParameter->pDev->serial.read()
<< ": " << pThreadParameter->statistics.framesPerSecond.name() << ": " << pThreadParameter->statistics.framesPerSecond.readS()
<< ", " << pThreadParameter->statistics.errorCount.name() << ": " << pThreadParameter->statistics.errorCount.readS()
<< ", " << pThreadParameter->statistics.captureTime_s.name() << ": " << pThreadParameter->statistics.captureTime_s.readS()
}
#ifdef USE_DISPLAY
pThreadParameter->displayWindow.GetImageDisplay().SetImage( pRequest );
pThreadParameter->displayWindow.GetImageDisplay().Update();
#endif
}
else
{
}
if( pPreviousRequest != nullptr )
{
}
pPreviousRequest = pRequest;
pThreadParameter->fi.imageRequestSingle();
}
}
manuallyStopAcquisitionIfNeeded( pThreadParameter->pDev, pThreadParameter->fi );
#ifdef USE_DISPLAY
pThreadParameter->displayWindow.GetImageDisplay().RemoveImage();
#endif
if( pRequest )
{
}
pThreadParameter->fi.imageRequestReset( 0, 0 );
}
bool isDeviceSupportedBySample(
const Device*
const pDev )
{
{
return false;
}
vector<TDeviceInterfaceLayout> availableInterfaceLayouts;
return find( availableInterfaceLayouts.begin(), availableInterfaceLayouts.end(), dilGenICam ) != availableInterfaceLayouts.end();
}
int main( void )
{
Device* pDev = getDeviceFromUserInput( devMgr, isDeviceSupportedBySample );
if( !pDev )
{
std::cout << "Unable to continue! Press [ENTER] to end the application" << endl;
cin.get();
return 1;
}
try
{
std::cout << "Initialising the device. This might take some time..." << endl << endl;
}
{
std::cout <<
"An error occurred while opening the device " << pDev->
serial.
read()
<< "Press [ENTER] to end the application..." << endl;
cin.get();
return 2;
}
cout << endl
<< "Press [1] [ENTER] to switch to sequencer set 1." << endl
<< "Press [0] [ENTER] to switch to sequencer set 0." << endl
<< "Press [ENTER] to end the application." << endl << endl;
ThreadParameter threadParam( pDev );
thread myThread( liveThread, &threadParam );
while( s_boTerminated == false )
{
char in;
cin >> in;
checkInput( &threadParam, in );
}
myThread.join();
return 0;
}
std::string displayName(void) const
Returns the display name of the component referenced by this object.
Definition: mvIMPACT_acquire.h:1100
bool isValid(void) const
Checks if the internal component referenced by this object is still valid.
Definition: mvIMPACT_acquire.h:1603
Grants access to devices that can be operated by this software interface.
Definition: mvIMPACT_acquire.h:6964
This class and its functions represent an actual device detected by this interface in the current sys...
Definition: mvIMPACT_acquire.h:5948
PropertyS product
A string property (read-only) containing the product name of this device.
Definition: mvIMPACT_acquire.h:6342
PropertyS serial
A string property (read-only) containing the serial number of this device.
Definition: mvIMPACT_acquire.h:6351
void open(void)
Opens a device.
Definition: mvIMPACT_acquire.h:6238
PropertyIDeviceInterfaceLayout interfaceLayout
An enumerated integer property which can be used to define which interface layout shall be used when ...
Definition: mvIMPACT_acquire.h:6444
PropertyIAcquisitionStartStopBehaviour acquisitionStartStopBehaviour
An enumerated integer property defining the start/stop behaviour during acquisition of this driver in...
Definition: mvIMPACT_acquire.h:6595
const EnumPropertyI & getTranslationDictValues(std::vector< ZYX > &sequence) const
This function queries a list of valid values for this property.
Definition: mvIMPACT_acquire.h:4136
const EnumPropertyI & write(ZYX value, int index=0) const
Writes one value to the property.
Definition: mvIMPACT_acquire.h:4296
The function interface to devices supported by this interface.
Definition: mvIMPACT_acquire.h:10458
Category for the acquisition and trigger control features.
Definition: mvIMPACT_acquire_GenICam.h:2095
Category that contains the Analog control features.
Definition: mvIMPACT_acquire_GenICam.h:3059
Category that contains the digital input and output control features.
Definition: mvIMPACT_acquire_GenICam.h:3890
Category for the Sequencer Control features.
Definition: mvIMPACT_acquire_GenICam.h:9778
Category that contains the User Set control features.
Definition: mvIMPACT_acquire_GenICam.h:9605
Base class for image processing related properties.
Definition: mvIMPACT_acquire.h:12882
A base class for exceptions generated by mvIMPACT Acquire.
Definition: mvIMPACT_acquire.h:248
std::string getErrorCodeAsString(void) const
Returns a string representation of the error associated with the exception.
Definition: mvIMPACT_acquire.h:280
A class to call arbitrary driver functions.
Definition: mvIMPACT_acquire.h:2656
int call(const std::vector< std::string > ¶ms) const
Calls an underlying driver function.
Definition: mvIMPACT_acquire.h:2736
std::string read(int index=0) const
Reads a value from a property.
Definition: mvIMPACT_acquire.h:5159
std::string readS(int index=0, const std::string &format="") const
Reads data from this property as a string.
Definition: mvIMPACT_acquire.h:3213
Contains information about a captured buffer.
Definition: mvIMPACT_acquire.h:8423
PropertyI imageHeight
An integer property (read-only) containing the height of the image in pixels.
Definition: mvIMPACT_acquire.h:10035
bool isOK(void) const
Convenience function to check if a request has been processed successfully.
Definition: mvIMPACT_acquire.h:9212
PropertyIRequestResult requestResult
An enumerated integer property (read-only) defining the result of this request.
Definition: mvIMPACT_acquire.h:9515
PropertyI imageWidth
An integer property (read-only) containing the width of the image in pixels.
Definition: mvIMPACT_acquire.h:10024
int unlock(void)
Unlocks the request for the driver again.
Definition: mvIMPACT_acquire.h:9352
Contains basic statistical information.
Definition: mvIMPACT_acquire.h:14186
A base class for accessing settings that control the overall behaviour of a device driver.
Definition: mvIMPACT_acquire.h:14393
A class that can be used to display images in a window.
Definition: mvIMPACT_acquire_display.h:582
TDMR_ERROR
Errors reported by the device manager.
Definition: mvDriverBaseEnums.h:2187
@ DMR_NO_ERROR
The function call was executed successfully.
Definition: mvDriverBaseEnums.h:2192
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: mvImageBuffer.h:41