CPP API Manual¶
Introduction to the API¶
Is this the best API for you?¶
The Vimba C++ API has an elaborate class architecture. It is designed as a highly efficient and sophisticated API for advanced object-oriented programming including the STL (standard template library), shared pointers, and interface classes. If you prefer an API with less design patterns, we recommend the Vimba C API.
See also
To understand the API, read the SDK Manual first: It contains essential information.
Tip
For more information about design patterns, we recommend the book Design Patterns. Elements of Reusable Object-Oriented Software.
To get the best possible performance, you need knowledge about multithreading. We recommend the book C++ Concurrency in Action.
Compatibility¶
To ensure backward compatibility, the C++ API release build is compatible with Visual Studio 2015. If you use a higher version, we recommend you to rebuild the C++ API by compiling the source files with your Visual Studio version. You can also use other IDEs that implement the C++11 standard (or higher) if you compile the C++ API source files with these IDEs.
Note
The C++ API provides release and debug build DLL files. If you build your application in debug mode, use the debug DLL file VimbaCPPd.dll.
C++ API diagram¶
The image below shows a simplified C++ API UML diagram. To ease understanding the concept, only the most important items are listed. For classes that you access through their pointers, the diagram shows these pointers instead of the corresponding class names.
API usage¶
For a quick start, we recommend using the examples.
See also
By default, the examples are located at:
C:/Users/Public/Documents/Allied Vision/Vimba_x.x (Windows)
Vimba install directory/VimbaCPP/Examples (Linux)
Entry point¶
The entry point to Vimba C++ API is the VimbaSystem
singleton.
The VimbaSystem class allows both to control the API’s behavior and to
query for interfaces and cameras.
To obtain a
reference to it, call the static function VimbaSystem::GetInstance
. All
Vimba C++ classes reside in the namespace AVT::VmbAPI
, so employ the using
declaration using AVT::VmbAPI
.
API version¶
Even if new features are introduced to the C++ API, your software
remains backward compatible. Use VimbaSystem::QueryVersion
to check
the version number of the C API. You can run this function without
initializing the API.
API startup and shutdown¶
To start and shut down the C++ API, use these paired functions:
VimbaSystem::Startup
initializes the API.VimbaSystem::Shutdown
shuts down the API and destroys all used objects in the API (when all observers have finished execution).
VimbaSystem::Startup
and VimbaSystem::Shutdown
must always be paired.
Calling the pair several times within the same program is possible,
but not recommended.
Successive calls of VimbaSystem::Startup
or VimbaSystem::Shutdown
are
ignored and the first VimbaSystem::Shutdown
after a VimbaSystem::Startup
closes the API.
Note
Always shut down the API when your application closes. Shutting down the API is necessary under all circumstances to unload the transport layers. If they still are loaded although the application is closed, they access invalid memory.
Note
VimbaSystem::Shutdown
blocks until all callbacks have finished execution.
Listing cameras¶
See also
For a quick start, see the ListCameras example.
The function VimbaSystem::GetCameras
enumerates all cameras recognized by the underlying transport layers.
With this command, the programmer can fetch the list of all connected camera objects. Before opening
cameras, camera objects contain all static details of a physical camera that do not change throughout
the object’s lifetime such as:
Camera ID
Camera model
Name or ID of the connected interface
The order in which the detected cameras are listed is determined by the order of camera discovery and therefore not deterministic. Moreover, the order may change depending on your system configuration and the accessories (for example, hubs or long cables).
GigE cameras¶
For GigE cameras, discovery has to be initiated by the host software.
This is done automatically if you register a camera list observer of
type ICameraListObserv
with VimbaSystem.
In this case, a call to VimbaSystem::GetCameras
or
VimbaSystem::GetCameraByID
returns immediately.
If no camera list observer is registered, a call to
VimbaSystem::GetCameras
or
VimbaSystem::GetCameraByID
takes some time because the responses to
the initiated discovery command must be waited for.
USB and 1394 cameras¶
Changes to the plugged cameras are detected automatically. Consequently,
any changes to the camera list are announced via discovery events and
the call to VimbaSystem::GetCameras
returns immediately.
Camera Link cameras¶
The specifications of Camera Link and GenCP do not support plug & play or
discovery events. To detect changes to the camera list, shutdown and startup
the API by calling VimbaSystem::Shutdown
and VimbaSystem::Startup
consecutively.
MIPI CSI-2 cameras¶
Cameras with MIPI CSI-2 interface are detected when the board is booted. To avoid damage to the hardware, do not plug in or out a camera while the board is powered.
std:: string name;
CameraPtrVector cameras;
VimbaSystem &system = VimbaSystem :: GetInstance ();
if ( VmbErrorSuccess == system.Startup () )
{
if ( VmbErrorSuccess == system.GetCameras( cameras ) )
{
for ( CameraPtrVector :: iterator iter = cameras.begin ();
cameras.end() != iter;
++iter )
{
if ( VmbErrorSuccess == (*iter)->GetName( name ) )
{
std::cout << name << std::endl;
}
}
}
}
Function |
Purpose |
---|---|
GetID( std::string& ) const |
Unique ID |
GetName( std::string& ) const |
Name |
GetModel( std::string& ) const |
Model name |
GetSerialNumber( std::string& ) const |
Serial number |
GetPermittedAccess( VmbAccessModeType& ) const |
Mode to open the camera |
GetInterfaceID( std::string& ) const |
ID of the interface the camera is connected to |
Note
VimbaSystem::Shutdown
blocks until all callbacks have finished execution.
Notifications of changed camera states¶
For being notified whenever a camera is detected, disconnected, or changes its open state, use
VimbaSystem::RegisterCameraListObserver
(GigE and USB only). This call registers a
camera list observer (of type ICameraListObserver) with the VimbaSystem that gets executed on the
according event. The observer function to be registered has to be of type ICameraListObserver*
.
Note
Functions that must not be called within your camera list observer:
VimbaSystem::Startup
VimbaSystem::Shutdown
VimbaSystem::GetCameras
VimbaSystem::GetCameraByID
VimbaSystem::RegisterCameraListObserver
VimbaSystem::UnregisterCameraListObserver
Feature::SetValue
Feature::RunCommand
Opening and closing a camera¶
A camera must be opened to control it and to capture images.
Call Camera::Open
with the camera list entry of your choice, or use function
VimbaSystem::OpenCameraByID
with the ID of the camera. In both cases, also provide the desired
access mode for the camera.
The API provides several access modes:
VmbAccessModeFull
: read and write access. Use this mode to configure the camera features and to acquire images (Goldeye CL cameras: configuration only).VmbAccessModeConfig
: enables configuring the IP address of your GigE camera. Not available for 5 GigE cameras - please use ForceIP.VmbAccessModeRead
: read-only access. Setting features is not possible. However, for GigE cameras that are already in use by another application, the acquired images can be transferred to the API(Multicast).
CameraPtrVector cameras;
VimbaSystem &system = VimbaSystem :: GetInstance ();
if ( VmbErrorSuccess == system.Startup () )
{
if ( VmbErrorSuccess == system.GetCameras( cameras ) )
{
for ( CameraPtrVector :: iterator iter = cameras.begin ();
cameras.end() != iter;
++iter )
{
if ( VmbErrorSuccess == (*iter)->Open( VmbAccessModeFull ) )
{
std::cout << "Camera opened" << std::endl;
}
}
}
}
The following code snippet shows how to open a GigE camera by its IP address. Opening the camera by its serial number or MAC address is also possible.
CameraPtr camera;
VimbaSystem &system = VimbaSystem :: GetInstance ();
if ( VmbErrorSuccess == system.Startup () )
{
if ( VmbErrorSuccess == system.OpenCameraByID( "192.168.0.42",
VmbAccessModeFull ,
camera ) )
{
std::cout << "Camera opened" << std::endl;
}
}
The following code snippet shows how to close a camera using Camera::Close
.
// The "camera" object points to an opened camera
if ( VmbErrorSuccess == camera.Close () )
{
std::cout << "Camera closed" << std::endl;
}
Acessing features¶
See also
To quickly learn how to list features, see the ListFeatures example.
Feature types¶
The C++ API provides several feature types, which all have their specific properties and functionalities. The API provides its own set of access functions for every feature data type. The table below lists the Vimba API functions of the Feature class used to access feature values.
Note
VimbaSystem::Shutdown
blocks until all callbacks have finished execution.
Type |
Set |
Get |
Range/Increment |
---|---|---|---|
Enum |
SetValue( string ) |
GetValue( string& ) |
GetValues( StringVector& ) |
SetValue( int ) |
GetValue( int& ) |
GetValues( IntVector& ) |
|
GetEntry( EnumEntry& ) |
GetEntries( EntryVector& ) |
||
Int |
SetValue( int ) |
GetValue( int& ) |
GetRange( int&, int& ) |
GetIncrement( int& ) |
|||
Float |
SetValue( double ) |
GetValue( double& ) |
GetRange( double&, double& ) |
GetIncrement( double& ) |
|||
String |
SetValue( string ) |
GetValue( string& ) |
|
Bool |
SetValue( bool ) |
GetValue( bool& ) |
|
Command |
RunCommand( ) |
IsCommandDone( bool& ) |
|
Raw |
SetValue( uchar ) |
GetValue( UcharVector& ) |
GetValue
, a feature’s value can be queried.SetValue
, a feature’s value can be set.Integer and double features support GetRange
. These functions return
the minimum and maximum value that a feature can have. Integer features
also support the GetIncrement
function to query the step size of
feature changes. Valid values for integer features are min <= val <= min +
[(max-min)/increment] * increment (the maximum value might not be valid).
Enumeration features support GetValues that returns a vector of valid
enumerations as strings or integers. These values can be used to set the
feature according to the result of IsValueAvailable
. If a non-empty
vector is supplied, the original content is overwritten and the size of
the vector is adjusted to fit all elements. An enumeration feature can
also be used in a similar way as an integer feature.
Since not all the features are available all the time, the current
accessibility of features may be queried via IsReadable()
and
IsWritable()
, and the availability of Enum values can be queried
with IsValueAvailable( string )
or IsValueAvailable( int )
.
With Camera::GetFeatures
, you can list all features available for a camera.
This list remains static while the camera is opened. The Feature class
of the entries in this list also provides information about the features
that always stay the same for this camera. Use the member
functions of class Feature to access them as shown in the following
code snippets:
FeaturePtr feature;
VmbInt64_t width;
if ( VmbErrorSuccess == camera ->GetFeatureByName( "Width", feature )
{
if ( VmbErrorSuccess == feature ->GetValue( width ) )
{
std::out << width << std::endl;
}
}
Writing features to a camera and running a command feature:
FeaturePtr feature;
if ( VmbErrorSuccess == camera ->GetFeatureByName( "AcquisitionMode", feature )
{
if ( VmbErrorSuccess == feature ->SetValue( "Continuous" ) )
{
if ( VmbErrorSuccess == camera ->GetFeatureByName( "AcquisitionStart",
feature ) )
{
if ( VmbErrorSuccess == feature ->RunCommand () )
{
std::out << "Acquisition started" << std::endl;
}
}
}
}
The following table introduces the basic features of all cameras.
A feature has a name, a type, and access flags such
as read-permitted and write-permitted.
To get notified when a feature’s value changes, use Feature::RegisterObserver
(see Using Events). The observer to be registered has to implement
the interface IFeatureObserver
. This interface declares the member function
FeatureChanged
. In the implementation of this function, you can react on
updated feature values as it will get called by the API on the according event.
Function |
Purpose |
---|---|
GetName( std::string& ) |
Name of the feature |
GetDisplayName( std::string& ) |
Name to display in GUI |
GetDataType( VmbFeatureDataType& ) |
Data type of the feature. Gives information |
GetFlags( VmbFeatureFlagsType& ) |
Static feature flags, containing information |
GetCategory( std::string& ) |
Category the feature belongs to, used for |
GetPollingTime( VmbUint32_t& ) |
The suggested time to poll the feature |
GetUnit( std::string& ) |
The unit of the feature, if available |
GetRepresentation( std::string& ) |
The scale to represent the feature, used |
GetVisibility( VmbFeatureVisibilityType& ) |
The audience the feature is for |
GetToolTip( std::string& ) |
Short description of the feature, used |
GetDescription( std::string& ) |
Description of the feature, used |
GetSFNCNamespace( std::string& ) |
The SFNC namespace of the feature |
GetAffectedFeatures( FeaturePtrVector& ) |
Features that change if the feature is changed |
GetSelectedFeatures( FeaturePtrVector& ) |
Features that are selected by the feature |
Feature |
Type |
Access |
Description |
---|---|---|---|
AcquisitionMode |
Enumeration |
R/W |
Values: Continuous, |
AcquisitionStart |
Command |
Start acquiring images. |
|
AcquisitionStop |
Command |
Stop acquiring images. |
|
PixelFormat |
Enumeration |
R/W |
Image format (Mono8 etc.) |
Width |
Uint32 |
R/W |
Image width, in pixels. |
Height |
Uint32 |
R/W |
Image height, in pixels. |
PayloadSize |
Uint32 |
R |
Number of bytes in the camera payload, incl. image. |
Note
VimbaSystem::Shutdown
blocks until all callbacks have finished execution.
Note
Functions that must not be called within the feature observer:
VimbaSystem::Startup
VimbaSystem::Shutdown
VimbaSystem::GetCameras
VimbaSystem::GetCameraByID
VimbaSystem::RegisterCameraListObserver
VimbaSystem::UnregisterCameraListObserver
Feature::SetValue
Feature::RunCommand
Acquiring images¶
See also
The SDK Manual describes synchronous and asynchronous image acquisition.
See also
For a quick start, see the SynchronousGrab example.
Image Capture vs. Image Acquisition¶
Image capture and image acquisition are two independent operations:
The API captures images
The camera acquires images.
To obtain an image from your camera, setup the API to capture images before starting the acquisition on the camera:
Note
The C++ API provides convenience functions, which are optimized for ease of use. We recommend using the convenience functions for projects where quick and easy programming is more important than best performance of your vision application.
Asynchronous image acquisition¶
The following code snippet is a minimalistic example of asynchrounous image acquisition.
#include "Vimba.h"
namespace AVT {
namespace VmbAPI {
// Constructor for the FrameObserver class
FrameObserver :: FrameObserver(CameraPtr pCamera) : IFrameObserver(pCamera ){}
// Frame callback notifies about incoming frames
void FrameObserver :: FrameReceived(const FramePtr pFrame)
{
// Send notification to working thread
// Do not apply image processing within this callback (performance)
// When the frame has been processed , requeue it
m_pCamera ->QueueFrame(pFrame );
}
void Vimba :: RunExample(void)
{
VmbInt64_t nPLS; // Payload size value
FeaturePtr pFeature; // Generic feature pointer
VimbaSystem &sys = VimbaSystem :: GetInstance (); // Create and get Vimba singleton
CameraPtrVector cameras; // Holds camera handles
CameraPtr camera;
FramePtrVector frames (15); // Frame array
// Start the API, get and open cameras
sys.Startup ();
sys.GetCameras(cameras );
camera = cameras [0];
camera ->Open(VmbAccessModeFull );
// Get the image size for the required buffer
// Allocate memory for frame buffer
// Register frame observer/callback for each frame
// Announce frame to the API
camera ->GetFeatureByName("PayloadSize", pFeature );
pFeature ->GetValue(nPLS);
for(FramePtrVector :: iterator iter=frames.begin (); frames.end ()!= iter; ++iter)
{
(*iter). reset(new Frame(nPLS ));
(*iter)->RegisterObserver(IFrameObserverPtr(new FrameObserver(camera )));
camera ->AnnounceFrame (*iter);
}
// Start the capture engine (API)
camera ->StartCapture ();
for(FramePtrVector :: iterator iter=frames.begin (); frames.end ()!= iter; ++iter)
{
// Put frame into the frame queue
camera ->QueueFrame (*iter);
}
// Start the acquisition engine (camera)
camera ->GetFeatureByName("AcquisitionStart", pFeature );
pFeature ->RunCommand ();
// Program runtime , e.g., Sleep (2000);
// Stop the acquisition engine (camera)
camera ->GetFeatureByName("AcquisitionStop", pFeature );
pFeature ->RunCommand ();
// Stop the capture engine (API)
// Flush the frame queue
// Revoke all frames from the API
camera ->EndCapture ();
camera ->FlushQueue ();
camera ->RevokeAllFrames ();
for(FramePtrVector :: iterator iter=frames.begin (); frames.end ()!= iter; ++iter)
{
// Unregister the frame observer/callback
(*iter)->UnregisterObserver ();
}
camera ->Close ();
sys.Shutdown (); // Always pair sys.Startup and sys.Shutdown
}
}} // namespace AVT::VmbAPI
Image capture¶
To enable image capture, frame buffers must be allocated and the API must be
prepared for incoming frames. This is done in convenience function
Camera::StartContinuousAcquisition
(Camera::StopContinuousAcquisition
stops acquisition). Note that these convenience functions perform all steps
listed in figure Typical asynchronous application with the C++ API for each single image. Therefore, they do not
provide best performance if your vision application requires frequently
starting and stopping image acquisition. In this case, it is unnecessary
to prepare image acquisisition and to clean up for each image. Instead, you
can prepare image acquisition once, toggle between the start and stop
functions, and clean up after your images are captured.
Asynchronous image capture step by step:
Open the camera as described in section Opening and closing a camera.
Query the necessary buffer size through the feature PayloadSize. Allocate frames of this size.
Announce the frames.
Start the capture engine.
Queue the frame you have just created with
Camera::QueueFrame
, so that the buffer can be filled when the acquisition has started.
The API is now ready. Start and stop image acquisition on the camera as described in section Image Acquisition.
Register a frame observer that gets executed when capturing is complete. The frame observer has to be of type IFrameObserver. Within the frame observer, queue the frame again after you have processed it.
Stop the capture engine with
Camera::EndCapture
.Call
Camera::FlushQueue
to cancel all frames on the queue. If the API has done the memory allocation, this memory is not released untilRevokeAllFrames
,RevokeFrame
,EndCapture
, orClose
functions have been called.Revoke the frames with Camera::RevokeAllFrames to clear the buffers.
Synchronous image capture (blocking your execution thread) step by step:
Open the camera as described in section Opening and closing a camera.
How you proceed depends on the number of frames and the performance you need:
Single frame: You can use the convenience function
Camera::AcquireSingleImage
to receive one image frame.Multiple frames: You can use the convenience function
Camera::AcquireMultipleImages
to receive several image frames (determined by the size of your vector of FramePtrs).
Note
If your application requires a low CPU load or exact triggering, we recommend a different approach: Set the feature AcquisitionMode to MultiFrame or Continuous and run the command AcquisitionStart (see section Image Acquisition).
To assure correct continuous image capture, use at least two or three frames. The appropriate number of frames to be queued in your application depends on the frames per second the camera delivers and on the speed with which you are able to re-queue frames (also taking into consideration the operating system load). The image frames are filled in the same order in which they were queued.
Note
Always check that Frame::GetReceiveStatus
returns
VmbFrameStatusComplete
when a frame is returned to ensure
the data is valid.
Note
Functions that must not be called within the frame observer:
VimbaSystem::Startup
VimbaSystem::Shutdown
VimbaSystem::OpenCameraByID
Camera::Open
Camera::Close
Camera::AcquireSingleImage
Camera::AcquireMultipleImages
Camera::StartContinuousImageAcquisition
Camera::StopContinuousImageAcquisition
Camera::StartCapture
Camera::EndCapture
Camera::AnnounceFrame
Camera::RevokeFrame
Camera::RevokeAllFrames
Image Acquisition¶
If you have decided to use one of the convenience functions
Camera::AcquireSingleImage
, Camera::AcquireMultipleImages
, or
Camera::StartContinuousImageAcquisition
, no further actions are necessary.
Only if you have setup capture step by step as described in section Image capture, you have to start image acquisition on your camera:
Set the feature AcquisitionMode (for example, to Continuous).
Run the command AcquisitionStart.
To stop image acquisition, run command AcquisitionStop. The code snippet below shows a simplified streaming example without error handling.
VmbErrorType err; // Every Vimba function returns an error code that
// should always be checked for VmbErrorSuccess
VimbaSystem &sys; // A reference to the VimbaSystem singleton
CameraPtrVector cameras; // A list of known cameras
FramePtrVector frames( 3 ); // A list of frames for streaming. We chose
// to queue 3 frames.
IFrameObserverPtr pObserver( new MyFrameObserver () ); // Our implementation
// of a frame observer
FeaturePtr pFeature; // Any camera feature
VmbInt64_t nPLS; // The payload size of one frame
sys = VimbaSystem :: GetInstance ();
err = sys.Startup ():
err = sys.GetCameras( cameras );
err = cameras [0]->Open( VmbAccessModeFull );
err = cameras [0]-> GetFeatureByName( "PayloadSize", pFeature ); (A)
err = pFeature ->GetValue( nPLS ) (A)
for ( FramePtrVector :: iterator iter = frames.begin ();
frames.end() != iter;
++iter )
{
( *iter ). reset( new Frame( nPLS ) ); (B)
err = ( *iter )->RegisterObserver( pObserver ) ); (C)
err = cameras [0]-> AnnounceFrame( *iter ); (1)
}
err = cameras [0]-> StartCapture (); (2)
for ( FramePtrVector :: iterator iter = frames.begin ();
frames.end() != iter;
++iter )
{
err = cameras [0]-> QueueFrame( *iter ); (3)
}
err = GetFeatureByName( "AcquisitionStart", pFeature ); (4)
err = pFeature ->RunCommand (); (4)
// Program runtime ...
// When finished , tear down the acquisition chain , close camera and API
err = GetFeatureByName( "AcquisitionStop", pFeature );
err = pFeature ->RunCommand ();
err = cameras [0]-> EndCapture ();
err = cameras [0]-> FlushQueue ();
err = cameras [0]-> RevokeAllFrames ();
err = cameras [0]->Close ();
err = sys.Shutdown ();
// 1. define observer that reacts on new frames
class FrameObserver : public IFrameObserver
{
...
public:
// In your contructor call the constructor of the base class
// and pass a camera object
FrameObserver( CameraPtr pCamera ) : IFrameObserver( pCamera )
{
// Put your initialization code here
}
void FrameReceived( const FramePtr pFrame )
{
VmbFrameStatusType eReceiveStatus;
if( VmbErrorSuccess == pFrame ->GetReceiveStatus( eReceiveStatus ) )
{
if ( VmbFrameStatusComplete == eReiveStatus )
{
// Put your code here to react on a successfully received frame
}
else
{
// Put your code here to react on an unsuccessfully received frame
}
}
// When you are finished copying the frame , re -queue it
m_pCamera ->QueueFrame( pFrame );
}
};
{
VmbErrorType res;
FramePtr pFrame;
CameraPtr pCamera;
// 2. Register the observer before queuing the frame
res = pFrame.RegisterObserver( IFrameObserverPtr( new FrameObserver( pCamera ) ) );
}
Transforming images¶
To transform images received via the API into common image formats, use the Image Transform Library.
See also
For a quick start, see the AsynchrounousGrab example, which contains an image transformation.
Using Events¶
Events serve a multitude of purposes and can have several origins: The Vimba System, an Interface, and cameras.
In the C++ API, notifications are issued as a result to a feature invalidation
of either its value or its state. Consequently, to get notified about any
feature change, register an observer of the desired type
(ICameraListObserver
, IInterfaceListObserver
, or IFeatureObserver
)
with the appropriate RegisterXXXObserver method (RegisterCameraListObserver
,
RegisterInterfaceListObserver
, or RegisterObserver
), which gets called
if there is a change to that feature.
Three examples are listed in this section:
Camera list notifications
Tracking invalidations of features
Explicit camera event features
For camera list notifications (GigE, USB, and 1394 only), see the code snippet below:
// 1. define observer that reacts on camera list changes
class CamObserver : public ICameraListObserver
{
...
public:
void CameraListChanged( CameraPtr pCam , UpdateTriggerType reason )
{
// Next to the camera pointer a reason why the observer's function was triggered
// is passed in. Possible values are:
// UpdateTriggerPluggedIn (0), a new camera was discovered
// UpdateTriggerPluggedOut (1), a known camera disappeared from the bus
// UpdateTriggerOpenStateChanged (3), a known camera was opened or closed
// by another application
if ( UpdateTriggerPluggedIn == reason || UpdateTriggerPluggedOut == reason )
{
// Put your code here to react on the changed camera list
// E.g., by sending a Windows event message or
// triggering a Qt or boost signal to update your view
}
else
{
// React on a changed open state
}
}
};
{
VmbErrorType res;
VimbaSystem &sys = VimbaSystem :: GetInstance ();
FeaturePtr pFeature;
// 2. Register the observer; automatic discovery for GigE is turned on
res = sys.RegisterCameraListObserver( ICameraListObserverPtr( new CamObserver () ) );
}
// 1. define observer
class WidthObserver : public IFeatureObserver
{
...
public:
void FeatureChanged ( const FeaturePtr &feature )
{
if ( feature != NULL )
{
VmbError_t res;
std:: string strName("");
res = feature ->GetDisplayName(strName );
std::cout << strName << " changed" << std::endl;
}
}
};
{
...
// 2. register the observer for that event
res = GetFeatureByName( "Width", pFeature );
res = pFeature ->RegisterObserver( IFeatureObserverPtr( new WidthObserver () ));
// as an example , binning is changed , so the observer will be run
res = GetFeatureByName( "BinningHorizontal", pFeature );
pFeature ->SetValue (8);
}
GigE cameras additionally provide the Camera events feature. Camera events (for changed camera states) are also handled with the same mechanism of feature invalidation.
// 1. define observer
class EventObserver : public IFeatureObserver
{
...
public:
void FeatureChanged ( const FeaturePtr &feature )
{
if ( feature != NULL )
{
VmbError_t res;
std:: string strName("");
res = feature ->GetDisplayName(strName );
std::cout "Event " << strName << " occurred" << std::endl;
}
};
{
...
// 2. register the observer for the camera event
res = GetFeatureByName( "EventAcquisitionStart", pFeature );
res = pFeature ->RegisterObserver( IFeatureObserverPtr( new EventObserver () ));
// 3. select "AcquisitionStart" (or a different) event
res = GetFeatureByName( "EventSelector", pFeature );
res = pFeature ->SetValue( "AcquisitionStart" );
// 4. switch on the event notification (or switch it off with "Off")
res = GetFeatureByName( "EventNotification", pFeature );
res = pFeature ->SetValue( "On" );
}
Saving and loading settings¶
See also
For a quick start, see the LoadSaveSettings example.
Additionally to the user sets stored inside the cameras, you can save the
feature values as an XML file to your host PC. For example, you can configure
your camera with Vimba Viewer, save the settings as a file, and load them with
the API. To do this, use the functions LoadCameraSettings
and
SaveCameraSettings
.
To control which features are saved, use either the function LoadSaveSettingsSetup
or the struct below.
Note
Saving and loading all features including look-up tables may take several minutes.
You can manually edit the XML file if you want only certain features to be restored.
Struct Entry |
Purpose |
---|---|
VmbFeaturePersist_t persistType |
Controls which features are saved. Valid values: |
VmbCameraPersistFlags_t |
Optional flags, see above |
Vmbuint32_t maxIterations |
Number of iterations. LoadCameraSettings iterates |
Triggering¶
Note
Before triggering, startup the API and open the camera(s).
Tip
To easily configure the camera’s trigger settings, use Vimba Viewer and save/load the settings.
External trigger¶
The following code snippet shows how to trigger your camera with an external device.
// Startup the API, get cameras and open cameras as usual
// Trigger cameras according to their interface
// Configure trigger input line and selector , switch trigger on
( *iter )->GetInterfaceType( pinterface );
switch( pinterface )
{
case VmbInterfaceEthernet:
( *iter )->GetFeatureByName( "TriggerSelector", pFeature );
pFeature ->SetValue( "FrameStart" );
( *iter )->GetFeatureByName( "TriggerSource", pFeature );
pFeature ->SetValue( "Line1" );
( *iter )->GetFeatureByName( "TriggerMode", pFeature );
pFeature ->SetValue( "On" );
break;
// USB: VmbInterfaceUsb
// CSI -2: VmbInterfaceCSI2
case VmbInterfaceUsb:
( *iter )->GetFeatureByName( "LineSelector", pFeature );
pFeature ->SetValue( "Line0" );
( *iter )->GetFeatureByName( "LineMode", pFeature );
pFeature ->SetValue( "Input" );
( *iter )->GetFeatureByName( "TriggerSource", pFeature );
pFeature ->SetValue( "Line0" );
( *iter )->GetFeatureByName( "TriggerMode", pFeature );
pFeature ->SetValue( "On" );
break;
}
Trigger over Ethernet – Action Commands¶
See also
For a quick start, see the ActionCommands example.
See also
Find more details in the application note: Trigger over Ethernet (ToE) - Action Commands
Triggering via the AcquisitionStart
command is supported by all cameras.
However, it is less precise than triggering with an external device connected
to the camera’s I/O port. Some GigE cameras additionally support Action Commands.
With Action Commands, you can broadcast a trigger signal simultaneously to
multiple GigE cameras via GigE cable.
Action Commands must be set first to the camera(s) and then to the TL,
which sends the Action Commands to the camera(s). As trigger source,
select Action0 or Action1.
ActionControl parameters
The following ActionControl parameters must be configured on the camera(s) and on the TL.
ActionDeviceKey must be equal on the camera and on the host PC. Before a camera accepts an Action Command, it verifies if the received key is identical with its configured key. Note that ActionDeviceKey must be set each time the camera is opened. Range (camera and host PC): 0 to 4294967295
ActionGroupKey means that each camera can be assigned to exactly one group for Action0 and a different group for Action1. All grouped cameras perform an action at the same time. If this key is identical on the sender and the receiving camera, the camera performs the assigned action. Range (camera and host PC): 0 to 4294967295
ActionGroupMask serves as filter that specifies which cameras within a group react on an Action Command. It can be used to create sub-groups. Range (camera): 0 to 4294967295 Range (host PC): 1 to 4294967295
Executing the feature ActionCommands sends the ActionControl parameters to the cameras and triggers the assigned action, for example, image acquisition. Before an Action Command is executed, each camera validates the received ActionControl parameter values against its configured values. If they are not equal, the camera ignores the command.
// Additionally to this code snippet:
// Configure the trigger settings and add image streaming
int deviceKey = 11, groupKey = 22, groupMask = 33;
FeaturePtr feature;
// Startup Vimba
VimbaSystem& system = VimbaSystem :: GetInstance ();
system.Startup ();
// Get cameras
CameraPtrVector cameras;
system.GetCameras( cameras );
for( int i=0; i<cameras.size (); ++i )
{
// Open camera
CameraPtr camera = cameras.at(i);
camera ->Open ();
// Set Action Command to camera
camera ->GetFeatureByName( "ActionDeviceKey", feature );
feature ->SetValue( deviceKey );
camera ->GetFeatureByName( "ActionGroupKey", feature );
feature ->SetValue( groupKey );
camera ->GetFeatureByName( "ActionGroupMask", feature );
feature ->SetValue( groupMask );
}
// Set Action Command to camera
camera ->GetFeatureByName( "ActionDeviceKey", feature );
feature ->SetValue( deviceKey );
camera ->GetFeatureByName( "ActionGroupKey", feature );
feature ->SetValue( groupKey );
camera ->GetFeatureByName( "ActionGroupMask", feature );
feature ->SetValue( groupMask );
// Set Action Command to Vimba API
system ->GetFeatureByName( "ActionDeviceKey", feature );
feature ->SetValue( deviceKey );
system ->GetFeatureByName( "ActionGroupKey", feature );
feature ->SetValue( groupKey );
system ->GetFeatureByName( "ActionGroupMask", feature );
feature ->SetValue( groupMask );
// Send Action Command
system ->GetFeatureByName( "ActionCommand", feature )
feature ->RunCommand ();
for( int i=0; i<cameras.size (); ++i )
{
// Close camera
CameraPtr camera = cameras.at(i);
camera ->Close ();
}
// Shutdown Vimba
system.Shutdown ();
Listing interfaces¶
You can list all found interfaces such as frame grabbers or NICs.
VimbaSystem::GetInterfaces
enumerates all interfaces recognized by
the underlying transport layers.
std:: string name; InterfacePtrVector interfaces; VimbaSystem &system = VimbaSystem :: GetInstance (); if ( VmbErrorSuccess == system.Startup () ) { if ( VmbErrorSuccess == system.GetInterfaces( interfaces ) ) { for ( InterfacePtrVector :: iterator iter = interfaces.begin (); interfaces.end() != iter; ++iter ) { if ( VmbErrorSuccess == (*iter)->GetName( name ) ) { std::cout << name << std::endl; } } } }
The Interface class provides the member functions to obtain information about an interface listed in the following table.
Function (returning VmbErrorType) |
Purpose |
---|---|
GetID( std::string& ) const |
The unique ID |
GetName( std::string& ) const The name |
The name |
GetType( VmbInterfaceType& ) const |
The camera interface type |
GetSerialNumber( std::string& ) const |
The serial number (not in use) |
GetPermittedAccess( VmbAccessModeType& ) const |
The mode to open the interface |
Error codes¶
For error codes and other technical issues, see Troubleshooting.