At least four steps are necessary to capture a single image from a Balluff device. These steps are explained with the help of source examples from ImpactControlCenter.
Step 1: The Device Needs To Be Initialized
mvIMPACT.acquire.DeviceManager devMgr = new mvIMPACT.acquire.DeviceManager();
mvIMPACT.acquire.Device pDev = devMgr.getDevice( 0 );
pDev.open();
- Note
- You HAVE to keep a reference to at least one instance of mvIMPACT.acquire.DeviceManager as long as you want to work with devices! When the last reference gets destroyed by the garbage collector all devices will be closed automatically!
Step 2: Request The Acquisition Of An Image
mvIMPACT.acquire.FunctionInterface fi = new mvIMPACT.acquire.FunctionInterface( pDev );
fi.imageRequestSingle();
A live acquisition (running inside a thread function) could be implemented as follows:
ContinuousCapture.java:
import mvIMPACT.acquire.*;
public class ContinuousCapture
{
static
{
try
{
System.loadLibrary( "mvIMPACT_Acquire.java" );
}
catch( UnsatisfiedLinkError e )
{
System.err.println( "Native code library failed to load. Make sure the 'mvIMPACT_Acquire.java' library can be found in the systems search path.\n" + e );
System.exit( 1 );
}
}
public static void main( String[] args )
{
DeviceManager devMgr = new DeviceManager();
Device pDev = mvIMPACT.acquire.examples.helper.DeviceAccess.getDeviceFromUserInput( devMgr );
if( pDev == null )
{
System.out.print( "Unable to continue! " );
mvIMPACT.acquire.examples.helper.DeviceAccess.waitForENTER();
System.exit( 1 );
}
System.out.println( "Initialising the device. This might take some time..." );
try
{
pDev.open();
}
catch( ImpactAcquireException e )
{
System.out.println( "An error occurred while opening device " + pDev.getSerial().read() +
"(error code: " + e.getMessage() + ")." );
mvIMPACT.acquire.examples.helper.DeviceAccess.waitForENTER();
System.exit( 1 );
}
CaptureThread captureThread = new CaptureThread( pDev );
captureThread.start();
mvIMPACT.acquire.examples.helper.DeviceAccess.waitForENTER();
captureThread.terminate();
try
{
captureThread.join();
}
catch( Exception e )
{
System.out.println( e.getMessage() );
}
}
}
CaptureThread.java:
import mvIMPACT.acquire.*;
public class CaptureThread extends Thread
{
private static final boolean isWindows_ = System.getProperty( "os.name" ).startsWith( "Windows" );
private Device pDev_;
private boolean terminated_ = false;
public CaptureThread( Device pDev )
{
pDev_ = pDev;
}
public void run()
{
if( isWindows_ )
{
System.out.println( "\n\nSince you are running on a Windows platform you could use the display module belonging to this SDK. To try this simply remove the comments wherever the 'window_' variable is used. As Java does not support something like '#ifdef' we did not come up with anything smarter. Suggestions welcome!!!\n\n" );
}
Statistics statistics = new Statistics( pDev_ );
FunctionInterface fi = new FunctionInterface( pDev_ );
int result = TDMR_ERROR.DMR_NO_ERROR;
while( ( result = fi.imageRequestSingle() ) == TDMR_ERROR.DMR_NO_ERROR ) { };
if( result != TDMR_ERROR.DEV_NO_FREE_REQUEST_AVAILABLE )
{
System.out.println( String.format( "'FunctionInterface.imageRequestSingle' returned with an unexpected result: %d(%s)", result, ImpactAcquireException.getErrorCodeAsString( result ) ) );
}
mvIMPACT.acquire.examples.helper.DeviceAccess.manuallyStartAcquisitionIfNeeded( pDev_, fi );
Request pRequest = null;
Request pPreviousRequest = null;
int timeout_ms = 500;
int cnt = 0;
int requestNr = acquire.getINVALID_ID();
while( !terminated_ )
{
requestNr = fi.imageRequestWaitFor( timeout_ms );
pRequest = fi.isRequestNrValid( requestNr ) ? fi.getRequest( requestNr ) : null;
if( pRequest != null )
{
if( pRequest.isOK() )
{
++cnt;
if( cnt % 100 == 0 )
{
System.out.println( String.format( "Info from %s: %s: %s, %s: %s, %s: %s", pDev_.getSerial().read(),
statistics.getFramesPerSecond().name(), statistics.getFramesPerSecond().readS(),
statistics.getErrorCount().name(), statistics.getErrorCount().readS(),
statistics.getCaptureTime_s().name(), statistics.getCaptureTime_s().readS() ) );
}
}
else
{
System.out.println( "Error: " + pRequest.getRequestResult().readS() );
}
if( pPreviousRequest != null )
{
pPreviousRequest.unlock();
}
pPreviousRequest = pRequest;
fi.imageRequestSingle();
}
}
mvIMPACT.acquire.examples.helper.DeviceAccess.manuallyStopAcquisitionIfNeeded( pDev_, fi );
if( pRequest != null )
{
pRequest.unlock();
}
fi.imageRequestReset( 0, 0 );
}
public void terminate()
{
terminated_ = true;
}
}
- Note
- Images supplied to the user are locked for the driver. So if the user does not unlock the images, a permanent acquisition won't be possible as sooner or later all available requests will have been processed by the driver and have been returned to the user.
- See also
- Step 4.
Step 3: Wait Until The Image Has Been Captured
int requestNr = fi.imageRequestWaitFor( timeout_ms );
Step 4: Unlock The Image Buffer Once The Image Has Been Processed:
if( fi.isRequestNrValid( requestNr ) )
{
fi.imageRequestUnlock( requestNr );
}
- Note
- ImpactControlCenter acquires images with the help of a capture thread. In order to avoid performance losses, the image buffer is locked during either the live or single image acquisition.
So after displaying the image the unlock is necessary!