mvIMPACT Acquire SDK C++
GigEVisionActionFeatures.cpp

The GigEVisionActionFeatures program is a simple example which illustrates how GigE Vision™ actions can be used to trigger events like starting an image in multiple cameras and instantaneously receive a confirmation about it.

How it works:
  1. Let the user decide which devices to use. Make sure to use devices on the same Ethernet interface.
  2. Prepare the two cameras for being able to properly react to the action commands.
  3. Prepare the interface for being able to send the action command.
  4. Arm the acquisition in the two cameras.
  5. Fire the action command from the same interface.
  6. Depending on the responses, request the images.

The explanation regarding the action commands and the usage of action command acknowledges can be found in chapter Actions and their MATRIX VISION extensions .

Source code
#include <iostream>
#include <vector>
#include <apps/Common/exampleHelper.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire_GenICam.h>
using namespace std;
using namespace mvIMPACT::acquire;
//-----------------------------------------------------------------------------
bool findDeviceInGenTLTree( const Device* pDev, int64_type& systemIndex, int64_type& interfaceIndex )
//-----------------------------------------------------------------------------
{
systemIndex = -1;
interfaceIndex = -1LL;
// find the GenTL interface this device claims to be connected to
PropertyI64 interfaceID;
DeviceComponentLocator locator( pDev->hDev() );
locator.bindComponent( interfaceID, "InterfaceID" );
if( !interfaceID.isValid() )
{
return false;
}
const std::string interfaceDeviceHasBeenFoundOn( interfaceID.readS() );
for( int64_type i = 0; i < systemModuleCount; i++ )
{
if( !sm.interfaceSelector.isValid() ) // CPPUNIT_ASSERT( sm.interfaceSelector.isValid() );
{
return false;
}
const int64_type interfaceSelectorMax = sm.interfaceSelector.getMaxValue();
for( int64_type index = 0; index <= interfaceSelectorMax; index++ )
{
if( !sm.interfaceSelector.write( index ) )// CPPUNIT_ASSERT_NO_THROW( sm.interfaceSelector.write( index ) );
{
return false;
}
const std::string val( sm.interfaceID.read() );
if( val == interfaceDeviceHasBeenFoundOn )
{
interfaceIndex = index;
systemIndex = i;
break;
}
}
}
return ( systemIndex != -1 ) && ( interfaceIndex != -1 );
}
//-----------------------------------------------------------------------------
void printNotSupportedAndWait( const Device* pDev, const std::string additionalInfo )
//-----------------------------------------------------------------------------
{
cout << "Device " << pDev->serial.read() << "(" << pDev->product << ") is not supported by this sample";
if( additionalInfo.empty() )
{
cout << endl;
}
else
{
cout << ":" << endl;
cout << additionalInfo << endl;
}
cout << "Press [ENTER] to end the application" << endl;
cin.get();
}
//-----------------------------------------------------------------------------
bool isCameraSuitableForSample( const Device* pDev, int64_type& systemIndex, int64_type& interfaceIndex )
//-----------------------------------------------------------------------------
{
if( pDev == nullptr )
{
return false;
}
if( !pDev->interfaceLayout.isValid() )
{
return false;
}
vector<pair<string, TDeviceInterfaceLayout> > dict;
if( dict.empty() )
{
return false;
}
// if this device offers the 'GenICam' interface switch it on, as this will
// allow are better control over GenICam compliant devices
conditionalSetProperty( pDev->interfaceLayout, dilGenICam, true );
// if this device offers a user defined acquisition start/stop behavior
// enable it as this allows finer control about the streaming behavior
conditionalSetProperty( pDev->acquisitionStartStopBehaviour, assbUser, true );
int64_type sI = -1;
int64_type iI = -1;
if( !findDeviceInGenTLTree( pDev, sI, iI ) )
{
printNotSupportedAndWait( pDev, "Device not found in GenTL tree." );
return false;
}
if( ( systemIndex == -1 ) && ( interfaceIndex == -1 ) )
{
systemIndex = sI;
interfaceIndex = iI;
}
else if( ( systemIndex != sI ) || ( interfaceIndex != iI ) )
{
printNotSupportedAndWait( pDev, "Error: Both devices must be on the same interface." );
return false;
}
SystemModule sm( systemIndex );
InterfaceModule im( sm, interfaceIndex );
if( im.interfaceType.readS() != "GEV" )
{
printNotSupportedAndWait( pDev, "Error: Only GEV interfaces are supported." );
return false;
}
return true;
}
//-----------------------------------------------------------------------------
void resetDeviceTriggers( Device* pDev0, Device* pDev1 )
//-----------------------------------------------------------------------------
{
AcquisitionControl acC0( pDev0 );
AcquisitionControl acC1( pDev1 );
acC0.triggerMode.writeS( "Off" );
acC1.triggerMode.writeS( "Off" );
}
//-----------------------------------------------------------------------------
bool prepareCam0ForActionTriggering( Device* pDev )
//-----------------------------------------------------------------------------
{
if( !pDev->isOpen() )
{
pDev->open();
}
ActionControl ac( pDev );
if( !ac.actionSelector.isValid() || !ac.actionDeviceKey.isValid() || !ac.actionGroupKey.isValid() || !ac.actionGroupMask.isValid() )
{
printNotSupportedAndWait( pDev, "Not all Action features found in device." );
return false;
}
ac.actionDeviceKey.write( 0x1 );
ac.actionSelector.write( 0 );
ac.actionGroupKey.write( 0x1 );
ac.actionGroupMask.write( 0x1 );
AcquisitionControl acC( pDev );
if( !acC.triggerSelector.isValid() || !acC.triggerSource.isValid() || !acC.triggerMode.isValid() )
{
printNotSupportedAndWait( pDev, "Not the necessary Trigger features found in device." );
return false;
}
acC.triggerSelector.writeS( "FrameStart" );
acC.triggerSource.writeS( "Action1" );
acC.triggerMode.writeS( "On" );
return true;
}
//-----------------------------------------------------------------------------
bool prepareCam1ForActionTriggering( Device* pDev )
//-----------------------------------------------------------------------------
{
if( !pDev->isOpen() )
{
pDev->open();
}
ActionControl ac( pDev );
if( !ac.actionSelector.isValid() || !ac.actionDeviceKey.isValid() || !ac.actionGroupKey.isValid() || !ac.actionGroupMask.isValid() )
{
printNotSupportedAndWait( pDev, "Not all Action features found in device." );
return false;
}
ac.actionDeviceKey.write( 0x1 );
ac.actionSelector.write( 0 );
ac.actionGroupKey.write( 0x1 );
ac.actionGroupMask.write( 0x1 );
if( !ctc.timerSelector.isValid() || !ctc.timerReset.isValid() || !ctc.timerDuration.isValid() || !ctc.timerTriggerSource.isValid() )
{
printNotSupportedAndWait( pDev, "Not the necessary Timer features found in device." );
return false;
}
ctc.timerSelector.writeS( "Timer1" );
ctc.timerReset.call();
ctc.timerDuration.write( 500000 );
ctc.timerTriggerSource.writeS( "Action1" );
AcquisitionControl acC( pDev );
if( !acC.triggerSelector.isValid() || !acC.triggerSource.isValid() || !acC.triggerMode.isValid() )
{
printNotSupportedAndWait( pDev, "Not the necessary Trigger features found in device." );
return false;
}
acC.triggerSelector.writeS( "FrameStart" );
acC.triggerSource.writeS( "Timer1End" );
acC.triggerMode.writeS( "On" );
return true;
}
//-----------------------------------------------------------------------------
void prepareAcquisition( const FunctionInterface& fi )
//-----------------------------------------------------------------------------
{
}
//-----------------------------------------------------------------------------
void prepareInterfaceForActionTriggering( const InterfaceModule& im )
//-----------------------------------------------------------------------------
{
im.actionGroupKey.write( 0x1 );
const uint64_type subnetMask = im.gevInterfaceSubnetMask.read();
const int64_type broadcast = ( ( im.gevInterfaceSubnetIPAddress.read() & subnetMask ) | ~subnetMask ) & 0x00000000ffffffff;
im.mvActionAcknowledgeEnable.write( TBoolean::bTrue );
}
//-----------------------------------------------------------------------------
int main( void )
//-----------------------------------------------------------------------------
{
const DeviceManager devMgr;
int64_type systemIndex = -1;
int64_type interfaceIndex = -1;
try
{
cout << "Please select the first camera that you want to use:" << endl;
Device* pDev0 = getDeviceFromUserInput( devMgr );
cout << "Using camera with " << pDev0->serial << endl;
if( !isCameraSuitableForSample( pDev0, systemIndex, interfaceIndex ) )
{
return 1;
}
cout << "Please select the second camera on the same interface that you want to use:" << endl;
Device* pDev1 = getDeviceFromUserInput( devMgr );
cout << "Using camera with " << pDev1->serial << endl;
if( !isCameraSuitableForSample( pDev1, systemIndex, interfaceIndex ) )
{
return 2;
}
if( !prepareCam0ForActionTriggering( pDev0 ) || !prepareCam1ForActionTriggering( pDev1 ) )
{
return 3;
}
// Prepare the acknowledged Action. Any device on the same interface may signal the Action command
const SystemModule sm( systemIndex );
const InterfaceModule im( sm, interfaceIndex );
prepareInterfaceForActionTriggering( im );
// Prepare acquisition
FunctionInterface fi0( pDev0 );
prepareAcquisition( fi0 );
FunctionInterface fi1( pDev1 );
prepareAcquisition( fi1 );
// Invoke the action
{
cout << "Action was not successful. " << im.mvActionAcknowledgesReceived.read() << " of ";
cout << im.mvActionAcknowledgesExpected.read() << " expected acknowledges have arrived ";
cout << "and " << im.mvActionAcknowledgesFailed.read() << " had a non-SUCCESS status code" << endl;
cout << "Aborting image reception." << endl;
return 4;
}
// Now fetch the images because we know that the commands have been delivered correctly
const int iReq0 = fi0.imageRequestWaitFor( 1000 );
if( !fi0.isRequestNrValid( iReq0 ) ) // check if the image has been captured without any problems
{
cout << "*** Error waiting for image no. 1: " << ImpactAcquireException::getErrorCodeAsString( iReq0 ) << "(" << iReq0 << ")" << endl;
}
const int iReq1 = fi1.imageRequestWaitFor( 1500 );
if( !fi1.isRequestNrValid( iReq1 ) ) // check if the image has been captured without any problems
{
cout << "*** Error waiting for image no. 2: " << ImpactAcquireException::getErrorCodeAsString( iReq1 ) << "(" << iReq1 << ")" << endl;
}
// Allow the cameras to be triggered normally again
resetDeviceTriggers( pDev0, pDev1 );
}
catch( const ImpactAcquireException& e )
{
cout << "Something went wrong: " << e.getErrorString() << "(" << e.getErrorCodeAsString() << ")" << endl;
cout << "Press [ENTER] to end the application" << endl;
cin.get();
return 10;
}
cout << "Press [ENTER] to end the application" << endl;
cin.get();
return 0;
}
bool bindComponent(Component &access, const std::string &name, int searchMode=0, int maxSearchDepth=INT_MAX) const
Binds an access object to an internal driver object.
Definition: mvIMPACT_acquire.h:2245
bool isValid(void) const
Checks if the internal component referenced by this object is still valid.
Definition: mvIMPACT_acquire.h:1603
A class to locate components within the driver.
Definition: mvIMPACT_acquire.h:7828
Grants access to devices that can be operated by this software interface.
Definition: mvIMPACT_acquire.h:6960
This class and its functions represent an actual device detected by this interface in the current sys...
Definition: mvIMPACT_acquire.h:5944
PropertyS product
A string property (read-only) containing the product name of this device.
Definition: mvIMPACT_acquire.h:6338
PropertyS serial
A string property (read-only) containing the serial number of this device.
Definition: mvIMPACT_acquire.h:6347
void open(void)
Opens a device.
Definition: mvIMPACT_acquire.h:6234
HDEV hDev(void) const
A unique identifier for this device.
Definition: mvIMPACT_acquire.h:6132
PropertyIDeviceInterfaceLayout interfaceLayout
An enumerated integer property which can be used to define which interface layout shall be used when ...
Definition: mvIMPACT_acquire.h:6440
bool isOpen(void) const
Returns the current initialisation status in this process.
Definition: mvIMPACT_acquire.h:6177
PropertyIAcquisitionStartStopBehaviour acquisitionStartStopBehaviour
An enumerated integer property defining the start/stop behaviour during acquisition of this driver in...
Definition: mvIMPACT_acquire.h:6591
ZYX read(int index=0) const
Reads a value from a property.
Definition: mvIMPACT_acquire.h:4772
const EnumPropertyI64 & write(ZYX value, int index=0) const
Writes one value to the property.
Definition: mvIMPACT_acquire.h:4898
ZYX getMaxValue(void) const
Reads the maximum value from a property.
Definition: mvIMPACT_acquire.h:4797
const EnumPropertyI & getTranslationDict(std::vector< std::pair< std::string, ZYX > > &sequence) const
This function queries the property's translation table.
Definition: mvIMPACT_acquire.h:3973
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:10439
int imageRequestSingle(ImageRequestControl *pImageRequestControl=0, int *pRequestUsed=0) const
Sends an image request to the mvIMPACT::acquire::Device driver.
Definition: mvIMPACT_acquire.h:11218
int acquisitionStart(void) const
Manually starts the acquisition engine of this device driver instance.
Definition: mvIMPACT_acquire.h:10707
Category for the acquisition and trigger control features.
Definition: mvIMPACT_acquire_GenICam.h:2105
Category that contains the Action control features.
Definition: mvIMPACT_acquire_GenICam.h:5679
Category that contains the Counter and Timer control features.
Definition: mvIMPACT_acquire_GenICam.h:4324
Category that contains items that belong to the interface module of the transport layer.
Definition: mvIMPACT_acquire_GenICam.h:16994
PropertyIBoolean mvActionAcknowledgeEnable
A boolean property. Enables or disables the ACK response for the action command.
Definition: mvIMPACT_acquire_GenICam.h:17602
PropertyI64 gevActionDestinationIPAddress
An integer property. The IP address of the action command recipient.
Definition: mvIMPACT_acquire_GenICam.h:17597
Method actionCommand
A method object. Sends the action command.
Definition: mvIMPACT_acquire_GenICam.h:17567
PropertyI64 mvActionAcknowledgeTimeout
An integer property. Maximum wait time for the acknowledge o an action command(ms)
Definition: mvIMPACT_acquire_GenICam.h:17612
PropertyI64 mvActionAcknowledgesReceived
An integer property. Number of devices that sent an acknowledge to the recent action command.
Definition: mvIMPACT_acquire_GenICam.h:17617
PropertyI64 actionGroupMask
An integer property. The group mask for the action command.
Definition: mvIMPACT_acquire_GenICam.h:17582
PropertyI64 mvActionAcknowledgesExpected
An integer property. Number of devices to send an acknowledge to the action command generated in the ...
Definition: mvIMPACT_acquire_GenICam.h:17607
PropertyI64 actionDeviceKey
An integer property. The device key for the action command.
Definition: mvIMPACT_acquire_GenICam.h:17572
PropertyI64 actionGroupKey
An integer property. The group key for the action command.
Definition: mvIMPACT_acquire_GenICam.h:17577
PropertyI64 gevInterfaceSubnetIPAddress
An integer property. Indicates the IP address of the selected subnet entry of this interface.
Definition: mvIMPACT_acquire_GenICam.h:17284
PropertyI64 gevInterfaceSubnetMask
An integer property. Indicates the subnet mask of the selected subnet entry of this interface.
Definition: mvIMPACT_acquire_GenICam.h:17289
PropertyI64 mvActionAcknowledgesFailed
An integer property. Number of devices that sent an acknowledge with an error code to the recent acti...
Definition: mvIMPACT_acquire_GenICam.h:17622
Category that contains items that belong to the system module of the transport layer.
Definition: mvIMPACT_acquire_GenICam.h:16272
static int64_type getSystemModuleCount(void)
Returns the number of GenTL producers detected in the current system.
Definition: mvIMPACT_acquire_GenICam.h:16932
PropertyI64 interfaceSelector
An integer property. Selector for the different GenTL Producer interfaces.
Definition: mvIMPACT_acquire_GenICam.h:16611
PropertyS interfaceID
A string property. GenTL producer wide unique identifier of the selected interface.
Definition: mvIMPACT_acquire_GenICam.h:16616
A base class for exceptions generated by mvIMPACT Acquire.
Definition: mvIMPACT_acquire.h:248
std::string getErrorString(void) const
Returns an error string containing information about the reason for the error.
Definition: mvIMPACT_acquire.h:262
std::string getErrorCodeAsString(void) const
Returns a string representation of the error associated with the exception.
Definition: mvIMPACT_acquire.h:280
int call(const std::vector< std::string > &params) 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
@ DMR_NO_ERROR
The function call was executed successfully.
Definition: mvDriverBaseEnums.h:2265
This namespace contains classes and functions belonging to the GenICam specific part of the image acq...
Definition: mvIMPACT_acquire.h:22543
This namespace contains classes and functions belonging to the image acquisition module of this SDK.
Definition: mvImageBuffer.h:42