Impact 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 Balluff 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:2364
bool isValid(void) const
Checks if the internal component referenced by this object is still valid.
Definition mvIMPACT_acquire.h:1721
A class to locate components within the driver.
Definition mvIMPACT_acquire.h:8031
Grants access to devices that can be operated by this software interface.
Definition mvIMPACT_acquire.h:7159
This class and its functions represent an actual device detected by this interface in the current sys...
Definition mvIMPACT_acquire.h:6118
PropertyS product
A string property (read-only) containing the product name of this device.
Definition mvIMPACT_acquire.h:6536
PropertyS serial
A string property (read-only) containing the serial number of this device.
Definition mvIMPACT_acquire.h:6550
void open(void)
Opens a device.
Definition mvIMPACT_acquire.h:6419
HDEV hDev(void) const
A unique identifier for this device.
Definition mvIMPACT_acquire.h:6317
PropertyIDeviceInterfaceLayout interfaceLayout
An enumerated integer property which can be used to define which interface layout shall be used when ...
Definition mvIMPACT_acquire.h:6643
bool isOpen(void) const
Returns the current initialisation status in this process.
Definition mvIMPACT_acquire.h:6362
PropertyIAcquisitionStartStopBehaviour acquisitionStartStopBehaviour
An enumerated integer property defining the start/stop behaviour during acquisition of this driver in...
Definition mvIMPACT_acquire.h:6788
ZYX read(int index=0) const
Reads a value from a property.
Definition mvIMPACT_acquire.h:4907
const EnumPropertyI64 & write(ZYX value, int index=0) const
Writes one value to the property.
Definition mvIMPACT_acquire.h:5033
ZYX getMaxValue(void) const
Reads the maximum value from a property.
Definition mvIMPACT_acquire.h:4932
const EnumPropertyI & getTranslationDict(std::vector< std::pair< std::string, ZYX > > &sequence) const
This function queries the property's translation table.
Definition mvIMPACT_acquire.h:4103
const EnumPropertyI & write(ZYX value, int index=0) const
Writes one value to the property.
Definition mvIMPACT_acquire.h:4426
The function interface to devices supported by this interface.
Definition mvIMPACT_acquire.h:10746
int imageRequestSingle(ImageRequestControl *pImageRequestControl=0, int *pRequestUsed=0) const
Sends an image request to the mvIMPACT::acquire::Device driver.
Definition mvIMPACT_acquire.h:11491
int acquisitionStart(void) const
Manually starts the acquisition engine of this device driver instance.
Definition mvIMPACT_acquire.h:10980
Category for the acquisition and trigger control features.
Definition mvIMPACT_acquire_GenICam.h:2108
Category that contains the Action control features.
Definition mvIMPACT_acquire_GenICam.h:5555
Category that contains the Counter and Timer control features.
Definition mvIMPACT_acquire_GenICam.h:4287
Category that contains items that belong to the interface module of the transport layer.
Definition mvIMPACT_acquire_GenICam.h:16896
PropertyIBoolean mvActionAcknowledgeEnable
A boolean property. Enables or disables the ACK response for the action command.
Definition mvIMPACT_acquire_GenICam.h:17504
PropertyI64 gevActionDestinationIPAddress
An integer property. The IP address of the action command recipient.
Definition mvIMPACT_acquire_GenICam.h:17499
Method actionCommand
A method object. Sends the action command.
Definition mvIMPACT_acquire_GenICam.h:17469
PropertyI64 mvActionAcknowledgeTimeout
An integer property. Maximum wait time for the acknowledge o an action command(ms)
Definition mvIMPACT_acquire_GenICam.h:17514
PropertyI64 mvActionAcknowledgesReceived
An integer property. Number of devices that sent an acknowledge to the recent action command.
Definition mvIMPACT_acquire_GenICam.h:17519
PropertyI64 actionGroupMask
An integer property. The group mask for the action command.
Definition mvIMPACT_acquire_GenICam.h:17484
PropertyI64 mvActionAcknowledgesExpected
An integer property. Number of devices to send an acknowledge to the action command generated in the ...
Definition mvIMPACT_acquire_GenICam.h:17509
PropertyI64 actionDeviceKey
An integer property. The device key for the action command.
Definition mvIMPACT_acquire_GenICam.h:17474
PropertyI64 actionGroupKey
An integer property. The group key for the action command.
Definition mvIMPACT_acquire_GenICam.h:17479
PropertyI64 gevInterfaceSubnetIPAddress
An integer property. Indicates the IP address of the selected subnet entry of this interface.
Definition mvIMPACT_acquire_GenICam.h:17186
PropertyI64 gevInterfaceSubnetMask
An integer property. Indicates the subnet mask of the selected subnet entry of this interface.
Definition mvIMPACT_acquire_GenICam.h:17191
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:17524
Category that contains items that belong to the system module of the transport layer.
Definition mvIMPACT_acquire_GenICam.h:16181
static int64_type getSystemModuleCount(void)
Returns the number of GenTL producers detected in the current system.
Definition mvIMPACT_acquire_GenICam.h:16834
PropertyI64 interfaceSelector
An integer property. Selector for the different GenTL Producer interfaces.
Definition mvIMPACT_acquire_GenICam.h:16520
PropertyS interfaceID
A string property. GenTL producer wide unique identifier of the selected interface.
Definition mvIMPACT_acquire_GenICam.h:16525
A base class for exceptions generated by Impact Acquire.
Definition mvIMPACT_acquire.h:256
std::string getErrorString(void) const
Returns an error string containing information about the reason for the error.
Definition mvIMPACT_acquire.h:270
std::string getErrorCodeAsString(void) const
Returns a string representation of the error associated with the exception.
Definition mvIMPACT_acquire.h:288
int call(const std::vector< std::string > &params) const
Calls an underlying driver function.
Definition mvIMPACT_acquire.h:2859
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
@ DMR_NO_ERROR
The function call was executed successfully.
Definition mvDriverBaseEnums.h:2603
This namespace contains classes and functions belonging to the GenICam specific part of the image acq...
Definition mvIMPACT_acquire.h:23805
This namespace contains classes and functions belonging to the image acquisition module of this SDK.
Definition mvCommonDataTypes.h:34