Example of using JVM wrapper for Point Grey Spinnaker SDK.
Please address queries and questions to JavaCPP discussion group.
Acquisition_C
- how to enumerate cameras, start acquisition, and grab images.Enumeration_C
- how to enumerate interfaces and cameras.Sequencer_C
- shows how to use the sequencer to grab images with various settings.Utils
- helper functions that are reused by multiple examples. In original Spinnaker C examples corresponding C code is duplicated in each example. This reduces verbosity of the original C examples. TreatUtils
is another source of example code.
To reduce verbosity of the original C examples some repeating code was moved to spinnaker_c4j.Utils
Acquisition_C
- shows how to acquire images.ChunkData_C
- shows how to get chunk data on an image, either from the nodemap or from the image itself.Enumeration_C
- how to enumerate interfaces and cameras.Enumeration_C_QuickSpin
- shows how to enumerate- interfaces and cameras using the QuickSpin API.EnumerationEvents_C
- handling system and interface events, like camera disconnect.ImageControl_C_QuickSpin
- shows how to apply custom image settings to the camera using the QuickSpin API.NodeMapInfo_C
- shows how to retrieve node map information.SaveToAvi_C
- shows how to create a video from a vector of images.Sequencer_C
- shows how to use the sequencer to grab images with various settings.Trigger_C
- shows how to trigger the camera.helpers
- helper functions that are reused by multiple examples. In original Spinnaker C examples corresponding C code is duplicated in each example. This reduces verbosity of the original C examples. Treathelpers
is another source of example code.
Some parts of Spinnaker usage require explicit dealing with deallocating memory and resources
that are specific to Spinnaker API, like releasing camera handles.
Many routine usages of C pointers like wrappers LongPointer
may refer to Java garbage collector to clean associated
memory.
In the examples, we are using more direct style of "closing" those pointers when no longer in use.
In JavaCPP implementation a Pointer
implements AutoCloseable
.
In Scala code, we use scala.util.Using
to perform automatic resource management. Rather than simply having
val hDeviceSerialNumber = new spinNodeHandle()
val deviceSerialNumber = new BytePointer(MAX_BUFF_LEN)
val lenDeviceSerialNumber = new SizeTPointer(1)
.
..
you will see "Using" blocks like this
Using.Manager { use =>
val hDeviceSerialNumber = use(new spinNodeHandle())
val deviceSerialNumber = use(new BytePointer(MAX_BUFF_LEN))
val lenDeviceSerialNumber = use(new SizeTPointer(1))
.
..
}.get
At the end of each block, the pointers surrounded by use
will be automatically closed.
Method calls in the original C API return error values. Dealing with those error codes is quite verbose and repetitive in the original C code. Here is an original example:
err = spinSystemGetInstance(&hSystem);
if (err != SPINNAKER_ERR_SUCCESS)
{
spinErrorGetLastMessage(lastErrorMessage, &lenLastErrorMessage);
printf("Error: %s [%d]\n\n", lastErrorMessage, err);
return err;
}
In our examples, we use simple helper methods to handle the errors, so the above will look like this:
exitOnError(spinSystemGetInstance(hSystem), "Unable to retrieve system instance.")
Another typical situation is when an the original C example method returns an error from the SDK method call
if (err != SPINNAKER_ERR_SUCCESS)
{
spinErrorGetLastMessage(lastErrorMessage, &lenLastErrorMessage);
printf("Error: %s [%d]\n\n", lastErrorMessage, err);
return err;
}
In our example's implementation we use a helper method check
that will of that error code returned from SDK
indicates error and throws an exception containing detail error information. Resulting in simpler example code:
check(spinCameraInit(hCam), "Unable to initialize camera.")
Many interactions with Spinnaker C API require a large amount of boilerplate code.
The Examples are simplified, compared to the original C version, by putting frequently used code in a helper methods.
You will find those helper methods in package spinnaker_c.helpers
.
For instance a direct call to spinEnumerationEntryGetIntValue
to get long value:
val value: Long = Using.Manager { use =>
val enumEntryIntValue = use(new LongPointer(1)).put(0)
check(
spinEnumerationEntryGetIntValue(enumEntry, enumEntryIntValue),
"Failed to retrieve enumeration entry int value"
)
enumEntryIntValue.get
}.get
Using a helper method:
val value: Long = enumerationEntryGetIntValue(enumEntry)
build.sbt
- the main SBT configuration file.project/build.properties
- version of SBT to use.project/plugins.sbt
- plugins used for creation of Eclipse projects.