Impact Acquire SDK C++
exampleHelper.h

The exampleHelper header offers some useful functions for

- device and
- property handling

and is used in nearly all examples.

Program location
The source file exampleHelper.h can be found under:
%INSTALLDIR%\apps\Common\
Note
If you have installed the package without example applications, this file will not be available. On Windows® the sample application can be installed or removed from the target system at any time by simply restarting the installation package.
What the header file offers
The header file offers following functions for device handling like

for property handling like:

The property handling functions use at a basic level the read and write functions:

and for some input handling:

Source code
/*
* @description: Example applications for Impact Acquire
* @copyright: Copyright (C) 2009 - 2023 Balluff GmbH
* @authors: APIs and drivers development team at Balluff GmbH
* @initial date: 2009-02-25
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
//-----------------------------------------------------------------------------
#ifndef exampleHelperH
#define exampleHelperH exampleHelperH
//-----------------------------------------------------------------------------
#include <algorithm>
#include <iostream>
#include <set>
#include <string>
#include <common/designData.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
//-----------------------------------------------------------------------------
template<class _Ty>
class DisplayDictEntry
//-----------------------------------------------------------------------------
{
public:
void operator()( const std::pair<std::string, _Ty>& data ) const
{
std::cout << " [" << data.second << "]: " << data.first << std::endl;
}
};
//-----------------------------------------------------------------------------
class DisplayComponent
//-----------------------------------------------------------------------------
{
public:
void operator()( const Component& data ) const
{
if( data.isValid() )
{
std::cout << " " << data.name() << "(" << data.typeAsString() << ")" << std::endl;
}
}
};
//-----------------------------------------------------------------------------
class DisplayProperty
//-----------------------------------------------------------------------------
{
public:
void operator()( const std::pair<std::string, mvIMPACT::acquire::Property>& data ) const
{
if( data.second.isValid() )
{
std::cout << data.first << ": " << data.second.readSArray() << "(" << data.second.flagsAsString() << ")" << std::endl;
}
}
};
//-----------------------------------------------------------------------------
template<class _Ty>
void DisplayPropertyDictionary( const mvIMPACT::acquire::Property& p )
//-----------------------------------------------------------------------------
{
_Ty prop( p );
#if defined(_MSC_VER) && (_MSC_VER < 1300) // is 'old' VC 6 Microsoft compiler?
std::vector<std::pair<std::string, _Ty::value_type> > dict;
prop.getTranslationDict( dict );
std::for_each( dict.begin(), dict.end(), DisplayDictEntry<_Ty::value_type>() );
#else
std::vector<std::pair<std::string, typename _Ty::value_type> > dict;
prop.getTranslationDict( dict );
std::for_each( dict.begin(), dict.end(), DisplayDictEntry<typename _Ty::value_type>() );
#endif // #ifdef _MSC_VER
}
//-----------------------------------------------------------------------------
/// \brief Checks is a certain value for property is supported.
template<class _Tx>
bool supportsEnumStringValue( const _Tx& prop, const std::string& value )
//-----------------------------------------------------------------------------
{
if( prop.hasDict() )
{
typename std::vector<std::string> sequence;
prop.getTranslationDictStrings( sequence );
return std::find( sequence.begin(), sequence.end(), value ) != sequence.end();
}
return false;
}
//-----------------------------------------------------------------------------
/// \brief Checks is a certain value for property is supported.
template<class _Tx, typename _Ty>
bool supportsValue( const _Tx& prop, const _Ty& value )
//-----------------------------------------------------------------------------
{
if( prop.hasDict() )
{
typename std::vector<_Ty> sequence;
prop.getTranslationDictValues( sequence );
return std::find( sequence.begin(), sequence.end(), value ) != sequence.end();
}
if( prop.hasMinValue() && ( prop.getMinValue() > value ) )
{
return false;
}
if( prop.hasMaxValue() && ( prop.getMaxValue() < value ) )
{
return false;
}
return true;
}
//-----------------------------------------------------------------------------
/// \brief Sets a property to a certain value if this value is supported.
template<typename _Ty, typename _Tx>
void conditionalSetProperty( const _Ty& prop, const _Tx& value, bool boSilent = false )
//-----------------------------------------------------------------------------
{
if( prop.isValid() && prop.isWriteable() && supportsValue( prop, value ) )
{
prop.write( value );
if( !boSilent )
{
std::cout << "Property '" << prop.name() << "' set to '" << prop.readS() << "'." << std::endl;
}
}
}
//-----------------------------------------------------------------------------
/// \brief Sets a property to a certain value if this value is supported.
template<typename _Ty>
void conditionalSetEnumPropertyByString( const _Ty& prop, const std::string& value, bool boSilent = false )
//-----------------------------------------------------------------------------
{
if( prop.isValid() && prop.isWriteable() && supportsEnumStringValue( prop, value ) )
{
prop.writeS( value );
if( !boSilent )
{
std::cout << "Property '" << prop.name() << "' set to '" << prop.readS() << "'." << std::endl;
}
}
}
//-----------------------------------------------------------------------------
/// This function makes heavy use of strings. In real world applications
/// this can be avoided if optimal performance is crucial. All properties can be modified
/// via strings, but most properties can also be modified with numerical (int / double )
/// values, which is much faster, but not as descriptive for a sample application
inline void displayPropertyData( const mvIMPACT::acquire::Property& prop )
//-----------------------------------------------------------------------------
{
const std::string name( prop.name() );
std::cout << std::endl
<< "Property '" << name << "'(display name: '" << prop.displayName() << "', type: " << prop.typeAsString() << ") currently specifies the following flags: " << prop.flagsAsString() << std::endl
<< std::endl;
const std::string doc( prop.docString() );
if( !doc.empty() )
{
std::cout << "The following documentation has been reported by the driver for this feature: " << std::endl
<< doc << std::endl
<< std::endl;
}
if( prop.selectedFeatureCount() > 0 )
{
std::vector<Component> selectedFeatureList;
prop.selectedFeatures( selectedFeatureList );
std::cout << "The following features are selected by this feature(Whenever the current feature is modified, all selected features might change):" << std::endl;
std::for_each( selectedFeatureList.begin(), selectedFeatureList.end(), DisplayComponent() );
std::cout << std::endl;
}
if( prop.selectingFeatureCount() > 0 )
{
std::vector<Component> selectingFeatureList;
prop.selectingFeatures( selectingFeatureList );
std::cout << "The following features select this feature(Whenever a selecting features is modified, a selected one might change):" << std::endl;
std::for_each( selectingFeatureList.begin(), selectingFeatureList.end(), DisplayComponent() );
std::cout << std::endl;
}
if( prop.hasMinValue() )
{
std::cout << "The minimum value of '" << name << "' is " << prop.readS( mvIMPACT::acquire::plMinValue ) << std::endl;
}
if( prop.hasMaxValue() )
{
std::cout << "The maximum value of '" << name << "' is " << prop.readS( mvIMPACT::acquire::plMaxValue ) << std::endl;
}
if( prop.hasStepWidth() )
{
std::cout << "The increment of '" << name << "' is " << prop.readS( mvIMPACT::acquire::plStepWidth ) << std::endl;
}
if( prop.hasDict() )
{
std::cout << "'" << name << "' defines a dictionary. Valid values are: " << std::endl;
{
DisplayPropertyDictionary<mvIMPACT::acquire::PropertyI>( prop );
}
else if( type == mvIMPACT::acquire::ctPropInt64 )
{
DisplayPropertyDictionary<mvIMPACT::acquire::PropertyI64>( prop );
}
else if( type == mvIMPACT::acquire::ctPropFloat )
{
DisplayPropertyDictionary<mvIMPACT::acquire::PropertyF>( prop );
}
else
{
std::cout << "Error! Unhandled enum prop type: " << prop.typeAsString() << std::endl;
}
}
std::cout << "The current value of '" << name << "' is: '" << prop.readS() << "'" << std::endl;
}
//-----------------------------------------------------------------------------
inline bool displayPropertyDataWithValidation( const mvIMPACT::acquire::Property& prop, const std::string& name )
//-----------------------------------------------------------------------------
{
if( !prop.isValid() )
{
std::cout << "Property '" << name << "' is not supported/available." << std::endl;
return false;
}
displayPropertyData( prop );
return true;
}
//-----------------------------------------------------------------------------
// Start the acquisition manually if this was requested(this is to prepare the driver for data capture and tell the device to start streaming data)
inline void manuallyStartAcquisitionIfNeeded( mvIMPACT::acquire::Device* pDev, const mvIMPACT::acquire::FunctionInterface& fi )
//-----------------------------------------------------------------------------
{
{
{
std::cout << "'FunctionInterface.acquisitionStart' returned with an unexpected result: " << result
<< "(" << mvIMPACT::acquire::ImpactAcquireException::getErrorCodeAsString( result ) << ")" << std::endl;
}
}
}
//-----------------------------------------------------------------------------
// Stop the acquisition manually if this was requested
inline void manuallyStopAcquisitionIfNeeded( mvIMPACT::acquire::Device* pDev, const mvIMPACT::acquire::FunctionInterface& fi )
//-----------------------------------------------------------------------------
{
{
{
std::cout << "'FunctionInterface.acquisitionStop' returned with an unexpected result: " << result
<< "(" << mvIMPACT::acquire::ImpactAcquireException::getErrorCodeAsString( result ) << ")" << std::endl;
}
}
}
//-----------------------------------------------------------------------------
/// This function makes heavy use of strings. In real world applications
/// this can be avoided if optimal performance is crucial. All properties can be modified
/// via strings, but most properties can also be modified with numerical (int / double )
/// values, which is much faster, but not as descriptive for a sample application
inline void modifyPropertyValue( const mvIMPACT::acquire::Property& prop, const std::string& param = "", const std::string& index = "" )
//-----------------------------------------------------------------------------
{
try
{
const std::string name( prop.name() );
if( prop.isWriteable() )
{
int valIndex = 0;
if( param.empty() )
{
std::cout << "Enter the new value for '" << name << "': ";
std::string val;
std::cin >> val;
// remove the '\n' from the stream
std::cin.get();
if( prop.valCount() > 1 )
{
std::cout << "'" << name << "' defines " << prop.valCount() << " values. Enter the index (zero-based) of the value to modify: ";
std::cin >> valIndex;
// remove the '\n' from the stream
std::cin.get();
}
prop.writeS( val, valIndex );
}
else
{
if( !index.empty() )
{
valIndex = atoi( index.c_str() );
}
prop.writeS( param, valIndex );
}
}
else
{
std::cout << "'" << name << "' is read-only, thus can't be modified." << std::endl;
}
}
{
std::cout << "An exception occurred: " << e.getErrorString() << "(error code: " << e.getErrorCodeAsString() << ")" << std::endl;
}
}
//-----------------------------------------------------------------------------
inline void displayAndModifyPropertyDataWithValidation( const mvIMPACT::acquire::Property& prop, const std::string& name )
//-----------------------------------------------------------------------------
{
if( displayPropertyDataWithValidation( prop, name ) )
{
modifyPropertyValue( prop );
}
std::cout << std::endl;
}
//-----------------------------------------------------------------------------
inline std::ostream& operator<<( std::ostream& out, const mvIMPACT::acquire::Property& prop )
//-----------------------------------------------------------------------------
{
out << prop.name() << ": " << prop.readS();
return out;
}
//-----------------------------------------------------------------------------
/// \brief Allows string comparison with a defined character to ignore
/**
* This function allows a tolerant string compare. If \a candidate ends with \a wildcard
* \a candidate can be shorter then \a searchString as the rest of the string will be
* ignored. This is a helper function used internally by <b>DeviceManager</b> objects.
*
* Examples:
*
* \code
* wildcard = '*'
* s1 = "blablabla"
* match( s1, "bl*bl*bla", '*' ); // will return 0
* // will return 0 ('*' is the default value for parameter 3 )
* match( s1, "bl*" );
* // the next call will return -1 as the first character MUST
* // be either a 'b' or the wildcard character.
* match( s1, "a*" );
* \endcode
* \return
* - 0 if successful
* - -1 otherwise
*/
template<class _Elem, class _Traits, class _Ax>
int match( const std::basic_string<_Elem, _Traits, _Ax>& searchString, const std::basic_string<_Elem, _Traits, _Ax>& candidate, _Elem wildcard )
//-----------------------------------------------------------------------------
{
typename std::basic_string<_Elem, _Traits, _Ax>::size_type searchLength = searchString.length();
// determine search length
if( candidate.length() < searchString.length() )
{
if( candidate.empty() )
{
return -1;
}
if( candidate[candidate.length() - 1] != wildcard )
{
return -1;
}
searchLength = candidate.length() - 1;
}
// search
for( typename std::basic_string<_Elem, _Traits, _Ax>::size_type i = 0; i < searchLength; i++ )
{
if( ( candidate[i] != searchString[i] ) && ( candidate[i] != wildcard ) )
{
return -1;
}
}
return 0;
}
typedef bool( *SUPPORTED_DEVICE_CHECK )( const mvIMPACT::acquire::Device* const );
//-----------------------------------------------------------------------------
inline mvIMPACT::acquire::Device* getDeviceFromUserInput( const mvIMPACT::acquire::DeviceManager& devMgr, SUPPORTED_DEVICE_CHECK pSupportedDeviceCheckFn = 0, bool boSilent = false, bool boAutomaticallyUseGenICamInterface = true )
//-----------------------------------------------------------------------------
{
const unsigned int devCnt = devMgr.deviceCount();
if( devCnt == 0 )
{
std::cout << "No compliant device found!" << std::endl;
return 0;
}
std::set<unsigned int> validDeviceNumbers;
// display every device detected that matches
for( unsigned int i = 0; i < devCnt; i++ )
{
Device* pDev = devMgr[i];
if( pDev )
{
if( !pSupportedDeviceCheckFn || pSupportedDeviceCheckFn( pDev ) )
{
std::cout << "[" << i << "]: " << pDev->serial.read() << " (" << pDev->product.read() << ", " << pDev->family.read();
if( pDev->interfaceLayout.isValid() )
{
if( boAutomaticallyUseGenICamInterface )
{
// 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 );
}
std::cout << ", interface layout: " << pDev->interfaceLayout.readS();
}
if( pDev->acquisitionStartStopBehaviour.isValid() )
{
// if this device offers a user defined acquisition start/stop behaviour
// enable it as this allows finer control about the streaming behaviour
conditionalSetProperty( pDev->acquisitionStartStopBehaviour, assbUser, true );
std::cout << ", acquisition start/stop behaviour: " << pDev->acquisitionStartStopBehaviour.readS();
}
if( pDev->interfaceLayout.isValid() && !pDev->interfaceLayout.isWriteable() && pDev->isInUse() )
{
std::cout << ", !!!ALREADY IN USE!!!";
}
std::cout << ")" << std::endl;
validDeviceNumbers.insert( i );
}
}
}
if( validDeviceNumbers.empty() )
{
std::cout << devMgr.deviceCount() << " devices have been detected:" << std::endl;
for( unsigned int i = 0; i < devCnt; i++ )
{
Device* pDev = devMgr[i];
if( pDev )
{
std::cout << " [" << i << "]: " << pDev->serial.read() << " (" << pDev->product.read() << ", " << pDev->family.read() << ")" << std::endl;
}
}
std::cout << "However none of these devices seems to be supported by this sample." << std::endl << std::endl;
return 0;
}
// get user input
std::cout << std::endl << "Please enter the number in front of the listed device followed by [ENTER] to open it: ";
unsigned int devNr = 0;
std::cin >> devNr;
// remove the '\n' from the stream
std::cin.get();
if( validDeviceNumbers.find( devNr ) == validDeviceNumbers.end() )
{
std::cout << "Invalid selection!" << std::endl;
return 0;
}
if( !boSilent )
{
std::cout << "Using device number " << devNr << "." << std::endl;
}
return devMgr[devNr];
}
//-----------------------------------------------------------------------------
inline std::vector<mvIMPACT::acquire::Device*>::size_type getValidDevices( const mvIMPACT::acquire::DeviceManager& devMgr, std::vector<mvIMPACT::acquire::Device*>& v, SUPPORTED_DEVICE_CHECK pSupportedDeviceCheckFn = 0 )
//-----------------------------------------------------------------------------
{
const unsigned int devCnt = devMgr.deviceCount();
// display every device detected that matches
for( unsigned int i = 0; i < devCnt; i++ )
{
Device* pDev = devMgr[i];
if( pDev )
{
if( !pSupportedDeviceCheckFn || pSupportedDeviceCheckFn( pDev ) )
{
v.push_back( pDev );
}
}
}
return v.size();
}
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__APPLE__)
# include <fcntl.h>
# include <stdio.h>
# include <sys/types.h>
# include <termios.h>
# include <unistd.h>
//-----------------------------------------------------------------------------
/// \brief Checks if something was written to a certain file descriptor
/** \return
* - 0 if timeout did elapse
* - 1 otherwise
*/
inline unsigned waitForInput( int maxWait_sec, int fd )
//-----------------------------------------------------------------------------
{
fd_set rfds;
struct timeval tv;
FD_ZERO( &rfds );
#ifndef __clang_analyzer__ // See https://bugs.llvm.org/show_bug.cgi?id=8920
FD_SET( fd, &rfds );
#endif // #ifndef __clang_analyzer__
tv.tv_sec = maxWait_sec;
tv.tv_usec = 0;
return select( fd + 1, &rfds, NULL, NULL, &tv );
}
//-----------------------------------------------------------------------------
/** \return
* - 1 if a key has been pressed since the last call to this function
* - 0 otherwise
*/
inline int checkKeyboardInput( void )
//-----------------------------------------------------------------------------
{
struct termios oldt, newt;
tcgetattr( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
const int oldf = fcntl( STDIN_FILENO, F_GETFL, 0 );
fcntl( STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK );
const int ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
fcntl( STDIN_FILENO, F_SETFL, oldf );
if( ch != EOF )
{
// ungetc(ch, stdin);
return 1;
}
return 0;
}
#endif // #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__APPLE__)
#endif // exampleHelperH
std::string displayName(void) const
Returns the display name of the component referenced by this object.
Definition mvIMPACT_acquire.h:1217
std::string name(void) const
Returns the name of the component referenced by this object.
Definition mvIMPACT_acquire.h:1206
unsigned int selectedFeatureCount(void) const
Returns the number of features selected by the current one.
Definition mvIMPACT_acquire.h:1928
std::string docString(void) const
Returns a string containing general information about the component referenced by this object.
Definition mvIMPACT_acquire.h:1623
unsigned int selectedFeatures(std::vector< Component > &v) const
Retrieves the list of components that are selected by the current one.
Definition mvIMPACT_acquire.h:1965
TComponentType type(void) const
Returns the type of the referenced component.
Definition mvIMPACT_acquire.h:1785
bool isWriteable(void) const
Checks if the caller has write/modify access to the component.
Definition mvIMPACT_acquire.h:1755
bool isValid(void) const
Checks if the internal component referenced by this object is still valid.
Definition mvIMPACT_acquire.h:1721
std::string flagsAsString(const std::string &separator=" | ") const
Returns the flags associated with this component as a string.
Definition mvIMPACT_acquire.h:1645
std::string typeAsString(void) const
Returns the type of the referenced component as a string.
Definition mvIMPACT_acquire.h:1809
unsigned int selectingFeatures(std::vector< Component > &v) const
Retrieves the list of components that are selecting the current one.
Definition mvIMPACT_acquire.h:1990
unsigned int selectingFeatureCount(void) const
Returns the number of features selecting the current one.
Definition mvIMPACT_acquire.h:1942
Grants access to devices that can be operated by this software interface.
Definition mvIMPACT_acquire.h:7159
unsigned int deviceCount(void) const
Returns the number of devices currently present in the system.
Definition mvIMPACT_acquire.h:7388
This class and its functions represent an actual device detected by this interface in the current sys...
Definition mvIMPACT_acquire.h:6118
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:4300
The function interface to devices supported by this interface.
Definition mvIMPACT_acquire.h:10746
int acquisitionStop(void) const
Manually stops the acquisition engine of this device driver instance.
Definition mvIMPACT_acquire.h:11006
int acquisitionStart(void) const
Manually starts the acquisition engine of this device driver instance.
Definition mvIMPACT_acquire.h:10980
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
A base class for properties.
Definition mvIMPACT_acquire.h:3134
std::string readS(int index=0, const std::string &format="") const
Reads data from this property as a string.
Definition mvIMPACT_acquire.h:3340
bool hasMaxValue(void) const
Checks if a maximum value is defined for this property.
Definition mvIMPACT_acquire.h:3305
bool hasMinValue(void) const
Checks if a minimum value is defined for this property.
Definition mvIMPACT_acquire.h:3317
unsigned int valCount(void) const
Returns the current number of values managed by this property.
Definition mvIMPACT_acquire.h:3506
bool hasStepWidth(void) const
Checks if a step width is defined for this property.
Definition mvIMPACT_acquire.h:3329
const Property & writeS(const std::string &value, int index=0) const
Assigns a new value to this property.
Definition mvIMPACT_acquire.h:3550
bool hasDict(void) const
Returns whether this property defines a translation dictionary or not.
Definition mvIMPACT_acquire.h:3274
TDMR_ERROR
Errors reported by the device manager.
Definition mvDriverBaseEnums.h:2601
TComponentType
Allowed components handled by this module.
Definition mvPropHandlingDatatypes.h:327
@ DMR_NO_ERROR
The function call was executed successfully.
Definition mvDriverBaseEnums.h:2603
@ assbUser
The user can control the start and stop of the data transfer from the device.
Definition mvDriverBaseEnums.h:170
@ ctPropInt64
Defines a property for 64 bit integer values.
Definition mvPropHandlingDatatypes.h:356
@ ctPropFloat
Defines a property for floating point values.
Definition mvPropHandlingDatatypes.h:350
@ ctPropInt
Defines a property for 32 bit integer values.
Definition mvPropHandlingDatatypes.h:348
@ plStepWidth
Set/Get the step width value for this mvIMPACT::acquire::Property.
Definition mvIMPACT_acquire.h:3033
@ plMinValue
Set/Get the minimum value for this mvIMPACT::acquire::Property.
Definition mvIMPACT_acquire.h:3026
@ plMaxValue
Set/Get the maximum value for this mvIMPACT::acquire::Property.
Definition mvIMPACT_acquire.h:3019