PMDSDK / PMDMDK User Manual: Unterschied zwischen den Versionen

Aus BECOM Systems Support
Zur Navigation springen Zur Suche springen
en>Peter
K (1 Version importiert)
 
K (1 Version importiert)
 
(kein Unterschied)

Aktuelle Version vom 31. Oktober 2023, 09:03 Uhr


Introduction and General Description

This section describes how to get started with the PMDSDK or PMDMDK. The Api is accessed via a library which is included in an application. All the neccessary functions, a short explanation and some examples are provided here, in order to make it easy for developers to get started with the basic and advanced functions of the Argos3D - P100 Camera.


Building Applications for Microsoft Windows

Files needed:

  • pmdsdk2.h: Contains declarations of the functions in the dll
  • pmdaccess2.lib: The improt library to be linked to the application
  • pmdaccess2.dll: The library containing the functions for accessing the camera
  • pmdsdk2common.h: This header file contains some defines, typedefs and enums and is indirectly included by pmdsdk2.h
  • pmddatadescription.h: This header file contains some defines, typedefs and structs and is indirectly included by pmdsdk2.h
  • A source plugin file: For example "digicam.W32.pap"
  • A processing plugin file: For example "digicamproc.W32.ppp"

Building Applications for Linux

Files needed:

  • pmdsdk2.h: Contains declarations of the functions in the dll
  • libpmdaccess2.so: The library containing the functions for accessing the camera
  • pmdsdk2common.h: This header file contains some defines, typedefs and enums and is indirectly included by pmdsdk2.h
  • pmddatadescription.h: This header file contains some defines, typedefs and structs and is indirectly included by pmdsdk2.h
  • A source plugin file: For example "digicam.L32.pap"
  • A processing plugin file: For example "digicamproc.L32.ppp"

Building Matlab Applications for Windows

The PMDMDK is a wrapper to use the PMDSDK in MATLAB. It can be used by adding the 'PMDMDK' path to your Matlab script or copying all of its files to a location that MATLAB can find.
Files included:

  • pmdaccess2.dll: The library containing the functions for accessing the camera
  • A source plugin file: For example "digicam.W32.pap"
  • A processing plugin file: For example "digicamproc.W32.ppp"
  • The precompiled MATLAB executables: For example "*.mexw32"

General Api Description

Using the PMDSDK

A connection to a camera (or source plugin) is established and held up via a handle. This handle is needed for all function calls. Information such as error codes are stored per handle, meaning that more than one connection to more than one camera can be handled by the PMDSDK or PMDMDK. Common to all functions is the code which is returned. The code is always PMD_OK on success. On failure an error code provides more information.

A typical usecase involves the following commands:

// establish a connection and get a handle
PMDHandle hndl;
int result = pmdOpen(&hndl, "digicam", "", "digicamproc", "");
if (result != PMD_OK) {
  // abort
}

// fetch a frame from usb controller
result = pmdUpdate(hndl);
if (result != PMD_OK) {
  // error
}

// get basic information about the current frame
PMDDataDescription dd;
result = pmdGetSourceDataDescription(hndl, &dd);
if (result != PMD_OK) {
  // error
}
int Xres = dd.img.numColumns;
int Yres = dd.img.numRows;
printf("Pixels in current frame %d\n", Xres * Yres);

// get distance data in meters (same procedure with pmdGetAmplitudes
float[] dist = new float[Xres * Yres];
int result = GetDistances(hndl, dist, sizeof(float)*Xres*Yres);
if (result != PMD_OK) {
  // error
}
printf("Center pixel sees an obstacle at %f meters\n", dist[Xres/2 + Yres/2 * Xres]);

// ...or get raw pixel data including header data (here only distances)
int sizeData = 0;
pmdGetSourceDataSize(hndl, &sizeData);
unsigned char[] data = new char[sizeData];
int result = pmdGetSourceData(hndl, (void *) data, sizeData);
if (result != PMD_OK) {
  // error
}
uint32[] header = new uint32[128];
for (int i = 0; i < 128; i++) {
  header[i] = (data[4*i] << 24) & (data[4*i + 1] << 16) & (data[4*i + 2] << 8) & data[4*i + 3];
}
ushort[] distances = new ushort[Xres * Yres];
for (int i = 0; i < Xres * Yres; i++) {
  distances[i] = data[512 + 2*i] & (data[512 + 2*i + 1] << 8);
}
printf("Center pixel raw distance is %d\n", distances[Xres/2 + Yres/2 * Xres]);

// close handle when finished
pmdClose(hndl);

Using the PMDMDK

The functions of the PMDMDK are very similar to those of the PMDSDK. Each function of the PMDSDK has its counterpart in the PMDMDK. There are however, a few important things to know.

  • In the PMDMDK, no error codes are returned by the functions. If an error occurs, an exception is raised instead.
  • There are no by-reference parameters in the PMDMDK. Output data is always returned in one or more return values.
  • pmdGetSourceDataDescription() returns a Matlab structure containing the fields of a PMDDataDescription. The fields std and gen appear as sub structures.
  • Size parameters are not necessary and must be omitted for all functions. The PMDMDK does automatic memory management.

A typical usecase involves the following commands:

addpath('PMDMDK')
% establish a connection and get a handle
hndl =  pmdOpen('PMDMDK\digicam',' ','PMDMDK\digicamproc',' ');

% fetch a frame from usb controller
pmdUpdate(hndl);

% get basic information about the current frame
dd = pmdGetSourceDataDescription(hndl);

Xres = dd.std.numColumns;
Yres = dd.std.numRows;
fprintf('Pixels in current frame %d\n', Xres * Yres);

% get distance data in meters (same procedure with pmdGetAmplitudes)
dist = pmdGetDistances(hndl);
fprintf('Center pixel sees an obstacle at %f meters\n', dist(Xres/2, Yres/2));

% ...or get raw pixel data including header data (here only distances)
raw = zeros(1, Xres*Yres);
sizeData = pmdGetSourceDataSize(hndl);
data = pmdGetSourceData(hndl);
raw = reshape(typecast(data(513:(512+2*Xres*Yres)),'uint16'),Xres,Yres);
header = typecast(data(1:512),'uint32');

fprintf('Center pixel raw distance is %f\n', raw(Xres/2, Yres/2));

% close handle when finished
pmdClose(hndl);

Reference Manual

This section describes the commands in the library, how to use them to obtain image data from the camera and how to change its configuration.
Example code is written both in C++ and Matlab.

PMDSDK Commands

pmdOpen

Parameter Type Description
handle PMDHandle * Empty PMDHandle structure. On success, this value will contain the handle for subsequent operations
rplugin const char * Camera (source) plugin. The extension can be omitted. It can be relative or absolute.
rparam const char * Parameter for the camera (source) plugin
pplugin const char * Processing plugin. The extension can be omitted. It can be relative or absolute. Can be Null, then no processing plugin is loaded
pparam const char * Parameter for the processing plugin
returns int PMD_OK on success, errorcode otherwise

The pmdOpen command connects the camera and provides a handle for subsequent operation. The parameters 'rplugin' and 'pplugin' must be provided as references to actual files (provided by Bluetechnix).

PMDSDK Example

PMDHandle hndl = 0;
int result = pmdOpen(&hndl, "digicam", "", "digicamproc", "");
if (result != PMD_OK) {
  // error, handle is not valid
}

PMDMDK Example

hndl = pmdOpen('PMDMDK\digicam', ' ', 'PMDMDK\digicamproc',' ');

pmdOpenSourcePlugin

Parameter Type Description
handle PMDHandle * Empty PMDHandle structure. On success, this value will contain the handle for subsequent operations
rplugin const char * Camera (source) plugin. The extension can be omitted. It can be relative or absolute.
rparam const char * Parameter for the camera (source) plugin
returns int PMD_OK on success, errorcode otherwise

The pmdOpenSourcePlugin command connects the camera and provides a handle for subsequent operation. The difference to pmdOpen is that no processing commands can be run. I.e. with only a source plugin loaded only the following commands are supported:

PMDSDK example

PMDHandle hndl = 0;
int result = pmdOpenSourcePlugin(&hndl, "digicam", "");
if (result != PMD_OK) {
  // error, handle is not valid
}

PMDMDK example

hndl = pmdOpenSourcePlugin('PMDMDK\digicam', ' ');

pmdOpenProcessingPlugin

Parameter Type Description
handle PMDHandle * Empty PMDHandle structure. On success, this value will contain the handle for subsequent operations
pplugin const char * Processing plugin. The extension can be omitted. It can be relative or absolute. Can be Null, then no processing plugin is loaded
pparam const char * Parameter for the processing plugin
returns int PMD_OK on success, errorcode otherwise

The pmdOpenProcessingPlugin command connects the camera and provides a handle for subsequent operation. The difference to pmdOpen is that no source commands can be run. I.e. with only a processing plugin loaded only the following commands are supported:

Example

PMDHandle hndl = 0;
int result = pmdOpenProcessingPlugin(&hndl, "digicamproc", "");
if (result != PMD_OK) {
  // error, handle is not valid
}

pmdClose

Parameter Type Description
handle PMDHandle Handle of the connection
returns int PMD_OK on success, errorcode otherwise

Disconnect and close the handle.
PMDSDK Example

int result = pmdClose(hndl);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

pmdClose(hndl);

pmdUpdate

Parameter Type Description
handle PMDHandle Handle of the connection
returns int PMD_OK on success, errorcode otherwise

Retrieve a new frame from the camera. This function must be called before beeing able to obtain image data. To obtain the actual data, use pmdGetSourceData, pmdGetDistances, pmdGetAmplitudes etc. Those calls to the above get-functions will produce the same data from the same frame until pmdUpdate is called again.
PMDSDK Example

int result = pmdUpdate(hndl);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

pmdUpdate(hndl);

pmdGetSourceDataDescription

Parameter Type Description
handle PMDHandle Handle of the connection
dd PMDDataDescription * Will contain the PMDDataDescription after the call.
returns int PMD_OK on success, errorcode otherwise

Get the description of the current raw data frame (refer to PMDDataDescription).
PMDSDK Example

PMDDataDescription dd;
int result = pmdGetSourceDataDescription(hndl, &dd);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

dd = pmdGetSourceDataDescription(hndl);

pmdGetSourceData

Parameter Type Description
handle PMDHandle Handle of the connection
data void * Pointer to a block of memory to contain the data.
maxLen size_t Maximum amount of bytes that can be written to memory allocated in data
returns int PMD_OK on success, errorcode otherwise

If the result data should be longer than maxLen the function results in an error. This function provides the raw data of the current frame. It may contain up to four containers in the following format:

header (128 x 4 bytes) data (2 bytes per pixel) header (128 x 4 bytes) data (2 bytes per pixel) header (128 x 4 bytes) data (2 bytes per pixel) header (128 x 4 bytes) data (2 bytes per pixel)

The overall size of the data block can be obtained calling pmdGetSourceDataSize and depends on the amount of containers and their resolutions in pixels
Header:
The header contains 128 32-bit words in network order. For a listing of these fields refer to Source Data Container Header.
Data:
The data block contains a 16-bit value per pixel. What data lies in each container depends on PMD Calculation Mode. By default three containers are available: Distances, Amplitudes and Plausibilities. Distances are scaled on the uniqueness range. Amplitudes are scaled equally as in pmdGetAmplitudes. Plausibilities contain flags providing more information about each pixel (refer to Plausibility Flags).
PMDSDK Example (only one container is processed)

unsigned int sizeData = 0;
pmdGetSourceDataSize(hndl, &sizeData);
unsigned char *data = new unsigned char[sizeData];
int result = pmdGetSourceData(hndl, (void *) data, sizeData);
if (result != PMD_OK) {
  // error
}
insigned int *header = new unsigned int[128];
for (int i = 0; i < 128; i++) {
  header[i] = (data[4*i]) | (data[4*i + 1] << 8) | (data[4*i + 2] << 16) | (data[4*i + 3]  << 24);
}
unsigned short *distances = new unsigned short[Xres * Yres];
for (int i = 0; i < Xres * Yres; i++) {
  distances[i] = data[512 + 2*i] | (data[512 + 2*i + 1] << 8);
}

PMDMDK Example

raw = zeros(1, Xres*Yres);
data = pmdGetSourceData(hndl);
raw = reshape(typecast(data(513:(512+2*Xres*Yres)),'uint16'),Xres,Yres);
header = typecast(data(1:512),'uint32');

pmdGetSourceDataSize

Parameter Type Description
handle PMDHandle Handle of the connection
maxLen size_t * Will contain the size of present source data
returns int PMD_OK on success, errorcode otherwise

Gets the size of the current frame in bytes. It is needed when calling pmdGetSourceData
Example

pmdGetAmplitudes

Parameter Type Description
handle PMDHandle Handle of the connection
data float * Pointer to a block of memory to contain the data.
maxLen size_t Maximum amount of bytes that can be written to memory allocated in data
returns int PMD_OK on success, errorcode otherwise

Get the amplitude data from the current frame. If there is more data available than maxLen, an error is returned. The data in the buffer received looks like follows. The pixel orientation is illustrated in the coordinate system figure. Amplitudes are raw values between 0 and 65535.

32 bit float
Amplitude Pixel 0 Addr 0
Amplitude Pixel 1 Addr 1
Amplitude Pixel 2 Addr 2
... ...

PMDSDK Example

float[] amp = new float[Xres * Yres];  // Xres and Yres are obtained from PMDDataDescription struct
int result = pmdGetAmplitudes(hndl, amp, sizeof(float)*Xres*Yres);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

amp = pmdGetAmplitudes(hndl);

pmdGetDistances

Parameter Type Description
handle PMDHandle Handle of the connection
data float * Pointer to a block of memory to contain the data.
maxLen size_t Maximum amount of bytes that can be written to memory allocated in data
returns int PMD_OK on success, errorcode otherwise

Get the distance data from the current frame. If there is more data available than maxLen, an error is returned. The data in the buffer received looks like follows. The pixel orientation is illustrated in the coordinate system figure. Distances are in [m].

32 bit float
Distance Pixel 0 Addr 0
Distance Pixel 1 Addr 1
Distance Pixel 2 Addr 2
... ...

PMDSDK Example

float[] dist = new float[Xres * Yres];  // Xres and Yres are obtained from PMDDataDescription struct
int result = pmdGetDistances(hndl, dist, sizeof(float)*Xres*Yres);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

dist = pmdGetDistances(hndl);

pmdGetFlags

Parameter Type Description
handle PMDHandle Handle of the connection
data uint32 * Pointer to a block of memory to contain the data.
maxLen size_t Maximum amount of bytes that can be written to memory allocated in data
returns int PMD_OK on success, errorcode otherwise

Get the plausibility data from the current frame. If there is more data available than maxLen, an error is returned. A plausability value contains flags providing more information about each pixel (refer to Plausibility Flags). The data in the buffer received looks like follows. The pixel orientation is illustrated in the coordinate system figure.

32 bit float
Flags Pixel 0 Addr 0
Flags Pixel 1 Addr 1
Flags Pixel 2 Addr 2
... ...

PMDSDK Example

uint32[] flags = new uint32[Xres * Yres];  // Xres and Yres are obtained from PMDDataDescription struct
int result = pmdGetFlags(hndl, flags, sizeof(uint32)*Xres*Yres);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

flags = pmdGetFlags(hndl);

pmdGet3DCoordinates

Parameter Type Description
handle PMDHandle Handle of the connection
data float * Pointer to a block of memory to contain the data.
maxLen size_t Maximum amount of bytes that can be written to memory allocated in data
returns int PMD_OK on success, errorcode otherwise

Get 3D coordinates from the current frame. If there is more data available than maxLen, an error is returned. 3D Coordinates are organised as iterations of x, y, z float values. The data in the buffer received looks like follows. The pixel orientation is illustrated in the coordinate system figure. Coordinates are in [m].

32 bit float
X coordinate Pixel 0 Addr 0
Y coordinate Pixel 0 Addr 1
Z coordinate Pixel 0 Addr 2
X coordinate Pixel 1 Addr 0
Y coordinate Pixel 1 Addr 1
Z coordinate Pixel 1 Addr 2
... ...


PMDSDK Example

float[] pos = new float[Xres * Yres * 3];  // Xres and Yres are obtained from PMDDataDescription struct
int result = pmdGet3DCoordinates(hndl, pos, sizeof(float)*Xres*Yres*3);
if (result != PMD_OK) {
  // error
}
float[] posx = new float[Xres * Yres];
float[] posy = new float[Xres * Yres];
float[] posz = new float[Xres * Yres];
for (int i = 0; i < Xres * Yres; i++) {
  posx[i] = pos[i*3];
  posy[i] = pos[i*3+1];
  posz[i] = pos[i*3+2];
}
delete[] pos;

PMDMDK Example

pos = pmdGet3DCoordinates(hndl);

pmdGetIntegrationTime

Parameter Type Description
handle PMDHandle Handle of the connection
t unsigned The integration time
idx unsigned Sequence index of the integration time (usually 0)
returns int PMD_OK on success, errorcode otherwise

Get the current integration time of a specified sequence.
PMDSDK Example

unsigned intTime;
int result = pmdGetIntegrationTime(hndl, &intTime, 0);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

intTime = pmdGetIntegrationTime(hndl, 0);

pmdGetModulationFrequency

Parameter Type Description
handle PMDHandle Handle of the connection
t unsigned The modulation frequency
idx unsigned Sequence index of the modulation frequency (usually 0)
returns int PMD_OK on success, errorcode otherwise

Get the current modulation frequency of a specified sequence.
PMDSDK Example

unsigned modFreq;
int result = pmdGetModulationFrequency(hndl, &modFreq, 0);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

modFreq = pmdGetIntegrationTime(hndl, 0);

pmdGetValidIntegrationTime

Parameter Type Description
handle PMDHandle Handle of the connection
result unsigned * Pointer to a variable to contain the integration time in microseconds
idx unsigned Sequence index of the integration time (usually 0)
w Proximity Where to look for a valid integration time in respect to the desired integration time (CloseTo, AtLeast or AtMost)
t unsigned The desired integration time
returns int PMD_OK on success, errorcode otherwise

Get a supported integration time of the camera based on a given desired integration time.
PMDSDK Example

unsigned intTime;
int result = pmdGetValidIntegrationTime(hndl, &intTime, 0, CloseTo, 1000);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

intTime = pmdGetValidIntegrationTime(hndl, 0, CloseTo, 1000);

pmdGetValidModulationFrequency

Parameter Type Description
handle PMDHandle Handle of the connection
result unsigned * Pointer to a variable to contain the modulation frequency in Hertz
idx unsigned Sequence index of the modulation frequency (usually 0)
w Proximity Where to look for a valid integration time in respect to the desired modulation frequency (CloseTo, AtLeast or AtMost)
t unsigned The desired modulation frequency
returns int PMD_OK on success, errorcode otherwise

Get a supported modulation frequency of the camera based on a given desired modulation frequency.
PMDSDK Example

unsigned modFreq;
int result = pmdGetValidModulationFrequency(hndl, &modFreq, 0, CloseTo, 20000000);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

modFreq = pmdGetValidModulationFrequency(hndl, 0, CloseTo, 20000000);

pmdSetIntegrationTime

Parameter Type Description
handle PMDHandle Handle of the connection
idx unsigned Sequence index of the integration time (usually 0)
t unsigned Integration time in microseconds
returns int PMD_OK on success, errorcode otherwise

Set the integration time of the camera
PMDSDK Example

int result = pmdSetIntegrationTime(hndl, 0, 1000);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

pmdSetIntegrationTime(hndl, 0, 1000);

pmdSetModulationFrequency

Parameter Type Description
handle PMDHandle Handle of the connection
idx unsigned Sequence index of the modulation frequency (usually 0)
t unsigned Modulation frequency in Hertz
returns int PMD_OK on success, errorcode otherwise

Set the modulation frequency of the camera. The range of valid modulation frequencies goes from 5MHz up to 30MHz. Note that not every frequency in this area can possibly set. Please refer to pmdGetValidModulationFrequency
PMDSDK Example

int result = SetModulationFrequency(hndl, 0, 20000000);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

pmdSetModulationFrequency(hndl, 0, 20000000);

pmdSourceCommand

Parameter Type Description
handle PMDHandle Handle of the connection
result char * Pointer to a block of memory to contain the result string
maxLen size_t Maximum length of the result string, including terminating 0
cmd char * The command to be executed
returns int PMD_OK on success, errorcode otherwise

Execute an source plugin-specific command. Feedback is literally provided in the result char sequence additionally to the result code. This command is a wrapper for many other functionalities such as direct write to the register set of the camera (Camera Registers). Valid commands are listed in Source Commands. If the result string should be longer than maxLen it is truncated.
PMDSDK Example

char *answer = new char[128];
int result = pmdSourceCommand(hndl, answer, 128, "SetOffset 0 -133");
if (result != PMD_OK) {
  // error
}

PMDMDK Example

result = pmdSourceCommand(hndl, 'SetOffset 0 -133');

pmdProcessingCommand

Parameter Type Description
handle PMDHandle Handle of the connection
result char * Pointer to a block of memory to contain the result string
maxLen size_t Maximum length of the result string, including terminating 0
cmd char * The command to be executed
returns int PMD_OK on success, errorcode otherwise

Execute an processing plugin-specific command. Feedback is literally provided in the result char sequence additionally to the result code. Valid commands are listed in Processing Commands. If the result string should be longer than maxLen it is truncated.
Example

char *answer = new char[128];
int result = pmdProcessingCommand(hndl, answer, 128, "SetBilateralFilter off");
if (result != PMD_OK) {
  // error
}

PmdMdk Example

result = pmdProcessingCommand(hndl, 'SetBilateralFilter off');

pmdGetLastError

Parameter Type Description
handle PMDHandle Handle of the connection
error char * Pointer to a block of memory to contain the result string
maxLen size_t Maximum length of the result string, including terminating 0
returns int PMD_OK on success, errorcode otherwise

Get an error description for the last error. Error messages are stored per handle. A new error associated with PMDHandle A does not overwrite the last error message associated with PMDHandle B. If the result string should be longer than maxLen it is truncated.
PMDSDK Example

char *answer = new char[128];
int result = pmdGetLastError(hndl, answer, 128);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

answer = pmdGetLastError(hndl);

pmdCalcDistances

Parameter Type Description
handle PMDHandle Handle of the connection
data float * Pointer to a block of memory to contain the data.
maxLen size_t Maximum amount of bytes that can be written to memory allocated in data
sourceDD PMDDataDescription Struct of the source data description
sourceData void * Pointer to a block of memory containing the source data
returns int PMD_OK on success, errorcode otherwise

Calc the distance data from stored source data. If there is more data available than maxLen, an error is returned. For a description of the result data buffer refer to pmdGetDistances.
PMDSDK Example

PMDDataDescription dd;
int result = pmdGetSourceDataDescription(hndl, &dd);
if (result != PMD_OK) {
  // error
}
int sizeData = 0;
pmdGetSourceDataSize(hndl, &sizeData);
unsigned char[] data = new char[sizeData];
int result = pmdGetSourceData(hndl, (void *) data, sizeData);
if (result != PMD_OK) {
  // error
}
float[] dist = new float[dd.img.numColumns * dd.img.numRows];
int result = pmdCalcDistances(hndl, dist, sizeof(float)*dd.img.numColumns * dd.img.numRows, dd, data);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

dd = pmdGetSourceDataDescription(hndl);
data = pmdGetSourceData(hndl);
dist = pmdCalcDistances(hndl, dd, data);

pmdCalcAmplitudes

Parameter Type Description
handle PMDHandle Handle of the connection
data float * Pointer to a block of memory to contain the data.
maxLen size_t Maximum amount of bytes that can be written to memory allocated in data
sourceDD PMDDataDescription Struct of the source data description
sourceData void * Pointer to a block of memory containing the source data
returns int PMD_OK on success, errorcode otherwise

Calc the amplitude data from stored source data. If there is more data available than maxLen, an error is returned. For a description of the result data buffer refer to pmdGetAmplitudes.
PMDSDK Example

PMDDataDescription dd;
int result = pmdGetSourceDataDescription(hndl, &dd);
if (result != PMD_OK) {
  // error
}
int sizeData = 0;
pmdGetSourceDataSize(hndl, &sizeData);
unsigned char[] data = new char[sizeData];
int result = pmdGetSourceData(hndl, (void *) data, sizeData);
if (result != PMD_OK) {
  // error
}
float[] dist = new float[dd.img.numColumns * dd.img.numRows];
int result = pmdCalcAmplitudes(hndl, dist, sizeof(float) * dd.img.numColumns * dd.img.numRows, dd, data);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

dd = pmdGetSourceDataDescription(hndl);
data = pmdGetSourceData(hndl);
amp = pmdCalcAmplitudes(hndl, dd, data);

pmdCalc3DCoordinates

Parameter Type Description
handle PMDHandle Handle of the connection
data float * Pointer to a block of memory to contain the data.
maxLen size_t Maximum amount of bytes that can be written to memory allocated in data
sourceDD PMDDataDescription Struct of the source data description
sourceData void * Pointer to a block of memory containing the source data
returns int PMD_OK on success, errorcode otherwise

Calc the distance data from stored source data. If there is more data available than maxLen, an error is returned. 3D Coordinates are organised as iterations of x, y, z float values. For a description of the result data buffer refer to pmdGet3DCoordinates.
PMDSDK Example

PMDDataDescription dd;
int result = pmdGetSourceDataDescription(hndl, &dd);
if (result != PMD_OK) {
  // error
}
int sizeData = 0;
pmdGetSourceDataSize(hndl, &sizeData);
unsigned char[] data = new char[sizeData];
int result = pmdGetSourceData(hndl, (void *) data, sizeData);
if (result != PMD_OK) {
  // error
}
float[] pos = new float[dd.img.numColumns * dd.img.numRows * 3];
int result = pmdCalc3DCoordinates(hndl, pos, sizeof(float) * dd.img.numColumns * dd.img.numRows * 3, dd, data);
if (result != PMD_OK) {
  // error
}
float[] posx = new float[dd.img.numColumns * dd.img.numRows];
float[] posy = new float[dd.img.numColumns * dd.img.numRows];
float[] posz = new float[dd.img.numColumns * dd.img.numRows];
for (int i = 0; i < dd.img.numColumns * dd.img.numRows; i++) {
  posx[i] = pos[i*3];
  posy[i] = pos[i*3+1];
  posz[i] = pos[i*3+2];
}
delete[] pos;

PMDMDK Example

dd = pmdGetSourceDataDescription(hndl);
data = pmdGetSourceData(hndl);
pos = pmdCalc3DCoordinates(hndl, dd, data);

pmdCalcFlags

Parameter Type Description
handle PMDHandle Handle of the connection
data uint32 * Pointer to a block of memory to contain the data.
maxLen size_t Maximum amount of bytes that can be written to memory allocated in data
sourceDD PMDDataDescription Struct of the source data description
sourceData void * Pointer to a block of memory containing the source data
returns int PMD_OK on success, errorcode otherwise

Get the plausibility data from stored source data. If there is more data available than maxLen, an error is returned. For a description of the result data buffer refer to pmdGetFlags.
PMDSDK Example

PMDDataDescription dd;
int result = pmdGetSourceDataDescription(hndl, dd);
if (result != PMD_OK) {
  // error
}
int sizeData = 0;
pmdGetSourceDataSize(hndl, &sizeData);
unsigned char[] data = new char[sizeData];
int result = pmdGetSourceData(hndl, (void *) data, sizeData);
if (result != PMD_OK) {
  // error
}
uint32[] flags = new uint32[dd.img.numColumns * dd.img.numRows];
int result = pmdCalcFlags(hndl, flags, sizeof(uint32) * dd.img.numColumns * dd.img.numRows, dd, data);
if (result != PMD_OK) {
  // error
}

PMDMDK Example

dd = pmdGetSourceDataDescription(hndl);
data = pmdGetSourceData(hndl);
flags = pmdCalcFlags(hndl, dd, data);

Processing Commands

Processing commands interact directly with the processing plugin.

Usage:

  • Pass the command as a string calling pmdProcessingCommand
  • Numeric parameters can be provided in decimal or hexadecimal format with leading 0x
  • Parameters are separated by spaces
  • pmdProcessingCommand reports the result of the processing command as a literal string in its parameter 'result' (here denoted as "returns")

PMDSDK Example

char answer[128];
answer[0] = 0;
int result = pmdProcessingCommand(hndl, answer, sizeof(answer), "SetBilateralFilter off");

PMDMDK Example

answer = pmdProcessingCommand(hndl, 'SetBilateralFilter off');

SetBilateralFilter

Parameter Description
modifier "on" or "off"
returns "OK"

This command turns bilateral filtering on or off.

Source Commands

Source commands interact directly with the source plugin.

Usage:

  • Pass the command as a string calling pmdSourceCommand
  • Numeric parameters can be provided in decimal or hexadecimal format with leading 0x
  • Parameters are separated by spaces
  • pmdSourceCommand reports the result of the source command as a literal string in its parameter 'result' (denoted as "returns" in following tables)

PMDSDK Example

char result[128];
result[0] = 0;
int res= pmdSourceCommand(hndl, result, sizeof(result), "SetRegister 0x1A 137");

PMDMDK Example

result = pmdSourceCommand(hndl, 'SetRegister 0x1A 137');

GetRegister

Parameter Description
address Address of the register to write (see Camera Registers)
returns The register content

This command returns the content of the denoted register.


SetRegister

Parameter Description
address Address of the register to write (see Camera Registers)
value Value to write into register
returns "OK"

This command writes a designated value directly into the denoted register. Some registers are read only, while others should not be written directly (such as distance offset). Register address overflows are not checked!


LoadRegisterMap

Parameter Description
filename The text file that is parsed and loaded into the registers
returns "OK"

The complete set of registers is parsed out of the file and then written into the camera's volatile internal memory. Use with care and with files provided by Bluetechnix only.


GetOffset

Parameter Description
Sequence index Sequence to which the offset is to be applied to
returns The offset for the indexed sequence in millimeters

Returns the offset, that is applied globally to all computed distances for a certain sequence. The offset may vary for different modulation frequencies. The offset returned by this source command will allways be positive and may not necessarily be the same value that was set using SetOffset.


SetOffset

Parameter Description
Sequence index Sequence to which the offset is to be applied to
value A signed offset in millimeters
returns The new offset for the indexed sequence in millimeters

Sets the offset for the indexed modulation frequency. The offset is given in [mm] and may be positive or negative. Negative values are converted to positive equivalents. This means when setting negative offset values using SetOffset, GetOffset will not return the same value.


GetSerialNumber

Parameter Description
returns The serial number of the device (see No. Serial/Customer)

Retrieves the serial number from the sensor. The serial number is provided as hexadecimal value of eight characters length with a leading 0x.

GetTriggerMode

Parameter Description
returns "Freerun" or "Hard"

Returns the current trigger mode.

SetTriggerMode

Parameter Description
Trigger mode "Freerun" or "Hard"
returns "OK"

Set the current trigger mode of the camera.

LoadCalibrationData

Parameter Description
filename Filename of calibration file
returns "OK"

Loads the calibration data from the given file. If no file parameter is provided, the plugin tries to automatically load argos3d.cal from the executable folder.


IsCalibrationDataLoaded

Parameter Description
returns "YES" or "NO"

If calibration data was loaded previously "YES" is returned. Otherwise "NO".

WriteConfigToFlash

Parameter Description
returns "OK"

Writes the whole sensor configuration to persistent flash memory. This current configuration will then be used as startup parameterization everytime the device is powered on. Use with care!

DisableIntegrationTimeCheck

Parameter Description
returns "OK"

Disables any limit for the integration time. Use with care! The camera will heat up to destruction (of itself and surroundings) if unrecommended values get involved.

From plugin version 0.3.0 onward this command is no longer supported. The integration time check is always deactivated and can no longer be switched on.

PMDSDK Data Structures

PMDDataDescription

The Data Description struct is always 128 bytes long and contains information about the captured frame.

struct PMDDataDescription
{
    unsigned PID;
    unsigned DID;
    unsigned type;
    unsigned size;
    unsigned subHeaderType;
    union
    {
            struct PMDGenericData gen;
            struct PMDImageData img;
            char fillUpToSizeOfStructure[108];
    };
};

PMDGenericData

Generic data

struct PMDGenericData
{
    unsigned subType;
    unsigned numElem;
    unsigned sizeOfElem;
};

PMDImageData

Image data

struct PMDImageData
{
    unsigned subType;
    unsigned numColumns;             // image x-size in pixels
    unsigned numRows;                // image y-size in pixels
    unsigned numSubImages;
    int integrationTime[4];          // integration time for up to four different sequences
    int modulationFrequency[4];      // modulation frequency for up to four different sequences
    int offset[4];                   // offset for up to four different sequences
    int pixelAspectRatio;
    int pixelOrigin;
    unsigned timeStampHi;            not working
    unsigned timeStampLo;            not working
    char reserved[24];
    unsigned userData0;
};

Plausibility Flags

The plausibility data contains flags providing more information on each pixel.

PMD_FLAG_INVALID               0x1  // The pixel is not to be relied on. Do not use this depth value
PMD_FLAG_SATURATED             0x2  // The calculated distance is not within a defined range and can therefore not be used
PMD_FLAG_INCONSISTENT          0x4  // The pixel’s raw data values are inconsistent with each other. This can happen when there are very fast changes in the scene (motion artefacts)
PMD_FLAG_LOW_SIGNAL            0x8  // The pixel's exposure was too low
PMD_FLAG_SBI_ACTIVE           0x10

PMD Result Codes

Result code returned by all PMDSDK Commands

PMD_OK                0
PMD_RUNTIME_ERROR     1024
PMD_GENERIC_ERROR     1025
PMD_DISCONNECTED      1026
PMD_INVALID_VALUE     1027
PMD_TIMEOUT_ERROR     1028
PMD_LOGIC_ERROR       2048
PMD_UNKNOWN_HANDLE    2049
PMD_NOT_IMPLEMENTED   2050
PMD_OUT_OF_BOUNDS     2051
PMD_RESOURCE_ERROR    4096
PMD_FILE_NOT_FOUND    4097
PMD_COULD_NOT_OPEN    4098
PMD_DATA_NOT_FOUND    4099
PMD_END_OF_DATA       4100
PMD_DEVICE_IS_BUSY    4101


Source Data Container Header

No. 32bit doubleword - network byte order Header Data Description
0 PMD Status
1 No. Serial/Customer
2 No. Release/Date
3 No. Framebytes
4 No. Rows
5 No. Columns
6 Set ROI
7 ROI_Column_Begin
8 ROI_Column_End
9 ROI_Row_Begin
10 ROI_Row_end
11 Sequence Length
12 Sequence Combine
13 Output Mode
14 PMD Acquisition Mode
15 PMD Calculation Mode
16 Temperature PMD
17 Temperature Illumination
18 Temperature Customer
19 0
20 0
21 0
22 Chipsize Columns
23 Chipsize Rows
24 Time Stamp Increment timestamp increment as configured in register 24
25 Trigger Mode
32-95 Customer Specification Area
96 Sequence pll_select
97 Sequence int_time
98 Sequence mod_frequency
99 Sequence frame_time
100 Sequence grayscale phase shift
101 Sequence no phases
102 Sequence distance offset
103 Sequence Amplitude Min
104 Sequence Saturation
105 Sequence Symmetry
106 Frame Counter
107 Time Stamp
timestamp of image
granularity can be configured in register 24
default granularity 1ms

PmdMdk Types and Data Structures

Handle

The handle for a camera connection is stored as a number. This handle is used for all operations that interact with a data source. It is initialized with the functions pmdOpen() or pmdOpenSourcePlugin() and is diposed when calling pmdClose().

Data Description Structure

The data description structure is returned by pmdGetSourceDataDescription(). It contains information about a data block. This is used to describe the source data of a camera.

Field Description
PID Identifier of the plugin that generated of modified the data block.
DID Identifier of the data block. This is unique for a plugin.
type Type of the data. This is used to describe what kind of data is in the block.
size Size in bytes of the data block.
subHeaderType Identifier for the active subheader structure. This can be ignored in MATLAB because the right substructure is automatically available.

Substructures (only one of these fields is used at the same time)

Substructure Description
gen Generic data substructure
std Image data substructure

Generic data substructure

Contains information about a generic data block. This structure is used as a field inside a data description structure for special information.

Field Description
subType Sub-type of the data. This depends of type in the data description structure and allows further refinement of the type.
numElem Number of data elements.
sizeOfElem Size in bytes of one data element.

Image data substructure

Contains information about a PMD- or image-data block. This structure is used as a field inside a data description structure for special information.

Field Description
subType Sub-type of the data. This depends of type in the data description structure and allows further refinement of the type.
numColumns Number of pixel columns in the image.
numRows Number of pixel rows in the image.
numSubImages Number of sub-images (e.g. phase images) in the data block.
integrationTime0-3 Up to four integration times used to generate the image.
modulationFrequency0-3 Up to four modulation frequencies used to generate the image.

Camera Registers

Register Name Address Hex Address Bit Length Interpretation Read/Write Description
General
PMD Status 0 0x00 uint32 bitwise r
No. Serial/Customer 1 0x01 uint32 bit 31 - bit 20: Device Type; bit19 - bit 0: Serial Number r
No. Release/Date 2 0x02 uint32 nibblewise r Firmware release date
No. Framebytes 3 0x03 uint32 num r Size of raw data
No. Rows 4 0x04 uint16 num r Vertical count of imager pixels
No. Columns 5 0x05 uint16 num r Horizontal count of imager pixels
Sequence Length 11 0x0B uint8 num 0…12 r/w
Sequence Combine 12 0x0C uint8 num 0…12 r/w
Output Mode 13 0x0D uint8 num 1..2 r/w
PMD Acquisition Mode 14 0x0E uint8 bitwise r/w
PMD Calculation Mode 15 0x0F uint32 bitwise r/w
Temperature PMD 16 0x10 uint32 word r Temperature of Imager (if available)
Temperature Illumination 17 0x11 uint32 fixedpoint 9.4 °C r Temperature of LED board
Temperature Customer 18 0x12 uint32 word r
Update Camera Data 19 0x13 uint32 bitwise r/w
Update_Flash_Data 20 0x14 uint32 bitwise r/w
Flash_Magic 21 0x15 uint32 num r/w
Chipsize_Columns 22 0x16 uint16 num r/w
Chipsize_Rows 23 0x17 uint16 num r/w
TimeStamp Increment 24 0x18 uint32 num r/w
78125000 * (desired timestamp granularity)
default: 78125000 * 0.001s = 78125
Trigger Mode 25 0x19 uint8 logic r/w 00: freerun, 01: hardware trigger
Temperature Compensation 26 0x1A uint16 fixcomma 11.5 mm/°C r/w
Illumination
Mod Led Enable 48 0x30 uint8 bitwise r/w
Sequencing
Sequence 0 int_time 129 0x81 uint16 us r/w
Sequence 0 mod_frequency 130 0x82 uint32 Hz r/w
Sequence 0 frame_time 131 0x83 uint32 us r/w
Sequence 0 distance offset 134 0x86 uint16 mm r/w
Sequence 0 Amplitude Min 135 0x87 uint16 num 0..2^16-1 r/w
Sequence 0 Saturation 136 0x88 uint32 2x num 0..2^16-1 r/w
Sequence 0 Symmetry 137 0x89 uint32 2x num 0..2^16-1 r/w

Register Details

No. Serial/Customer

The Serial/Customer Number of the camera contains the serial number and the device type code:

Bit Description
bit 31 - bit 20 PON code
bit 19 - bit 0 Serial Number (found on the label on the camera's back)

PON code to PON table:

Code PON
0x001 150-2001-1
0x002 160-0001-1
0x003 160-0001-2
0x004 150-2201-1
0x005 170-2201-2
0x006 160-0001-3
0x007 150-2201-2
0x008 909-2222-1
0x700 Reserved

Trigger Mode

Value Description
0x0 Free run mode
0x1 Hardware trigger mode


Mod Led Enable

Bit Name Description
Bit0: enable pmd_mod
Bit1: enable led_mod Enables internal modulation signal
Bit2: enable ext_mod Enables external modulation signal (Modulation light interface)
Bit3: enable led1_en Currently not supported
Bit4: enable led2_en Enables built-in leds