Running Cameras Synchronized

This guide shows how to synchronize the triggers for multiple cameras.

PTP Synchronized Triggers

B- and C-series cameras can synchronize their internal clocks using the PTP protocol. This allows to trigger them synchronously without an additional cable.

Note

This feature is only available when all involved cameras are B- or C-series cameras. If you want to synchronize other types of cameras you have to use a hardware trigger as described below.

Use the PrepareSynchronizedTrigger command to synchronize the camera clocks.

NxLibCommand prepare(cmdPrepareSynchronizedTrigger);
prepare.parameters()[itmCameras][0] = "1234";
prepare.parameters()[itmCameras][1] = "2345";
prepare.execute();

After the command was executed successfully, subsequent invocations of the Trigger command for the same set of cameras will automatically trigger them at the same time.

Note that this introduces a small delay compared to a normal trigger, since the command has to choose a point in time in the future at which all cameras will trigger and communicate this time to the cameras. The necessary delay is chosen automatically based on the measured round-trip time of the cameras.

In case of a problem with the synchronization, Trigger will automatically fall back to a normal software trigger. You can check whether a trigger was synchronized using the command’s result node. The exact requirements for a synchronized trigger are listed in the documentation of the PrepareSynchronizedTrigger command.

NxLibCommand trigger(cmdTrigger);
trigger.parameters()[itmCameras][0] = "1234";
trigger.parameters()[itmCameras][1] = "2345";
trigger.execute();

bool triggerWasSynchronized = trigger.result()[0][itmPtp][itmTriggered].asBool();
if (!triggerWasSynchronized) {
        std::string reason = trigger.result()[0][itmPtp][itmErrorText].asString();
}

Staggered Triggering

Use the TriggerDelay parameter to explicitly trigger cameras at different times, e.g. to avoid interference of their projectors.

By default the parameter is set to the minimum trigger delay supported by the camera model. This means that camera’s of the same model will trigger at the same time. You might have to adjust it when mixing cameras of different models.

For B- and C-series cameras you can use the Mode parameter of the PrepareSynchronizedTrigger command to set this up automatically. In addition to the trigger delay, this also chooses a suitable FlexViewInterval to interleave the FlexView frames of the individual cameras.

NxLibCommand prepare(cmdPrepareSynchronizedTrigger);
prepare.parameters()[itmCameras][0] = "1234";
prepare.parameters()[itmCameras][1] = "2345";
prepare.parameters()[itmMode] = valStaggered;
prepare.execute();

Hardware Trigger

Please read the topics Capturing with Hardware Trigger and Using Digital IOs first for more background on hardware triggered capture operation and IO usage.

We assume to have two cameras connected with the serial numbers “1234” and “2345”. The output of camera “1234” is electrically connected to the input of camera “2345”. We want to run camera “1234” in software trigger mode, and “2345” should run hardware synchronized to the software triggered images of “1234”.

NxLibItem root; // References the tree's root item at path "/"

// Replace "1234" and "2345" with your camera's serial numbers:
// References the camera's item at path "/Cameras/BySerialNo/<Serial Number>"
NxLibItem camera1 = root[itmCameras]["1234"];
NxLibItem camera2 = root[itmCameras]["2345"];

// Call the Open command to open the cameras
NxLibCommand open(cmdOpen);
open.parameters()[itmCameras][0] = "1234"; // Use the array parametrization to open both cameras at once
open.parameters()[itmCameras][1] = "2345";
open.execute();

// Configure trigger modes and outputs
// Camera "1234" should output a 10ms low-active flash signal
camera1[itmParameters][itmCapture][itmTriggerMode] = valSoftware; // This is actually already the default
camera1[itmParameters][itmIO][itmOutput][itmMode] = valLowActive;
camera1[itmParameters][itmIO][itmOutput][itmDuration] = 10.0;

// Camera "2345" will capture on the falling edge of its input signal
camera2[itmParameters][itmCapture][itmTriggerMode] = valFallingEdge;

for (int imageIndex = 0; imageIndex < 10; imageIndex++) {
	// Execute the Capture command with default parameters
	NxLibCommand(cmdCapture).execute();

	// Please note that the default parametrization of the Capture command is sufficient for synchronized operation,
	// because:
	// * Capture triggers all opened cameras and waits for all cameras to return an image
	// * Cameras configured for hardware triggering are triggered first, so they are always armed and waiting for
	//   the trigger signal before the software triggered camera start its exposure and outputs the trigger signal

	// Now compute the disparity map, point map, and process the data according to your needs
	// ...
}

Note

See Grabbing 3D Data for an example on how to process the data according to your needs.