NaturalPoint Tracking Toolkits (Point Cloud and Rigid Body)
Users Manual
5. Using the Point Cloud API
In order to use Point Cloud tracking in your own applications, you will need to implement support for it using the Point Cloud API. The following section provides an overview of the system architecture as well as specific detail about the API.
-
5.1 Architecture
- The Point Cloud API is written as a series of COM automation interfaces and is built on top of the OptiTrack SDK. This type of interface was chosen due to the flexibility it provides. COM automation interfaces are supported by nearly every language, including VBScript, JavaScript, Visual Basic and C/C++. Support also exists for Python, Delphi and many others. Check your favorite language for more details.
-
5.2 Interface Layout
- The figure below shows the interfaces of the Point Cloud API and their relationships.
The main interface is INPPointCloud. This interface provides the ability to enumerate the cameras, load calibration profiles, and process tracking data. When a frame of 3D data is ready, the client will obtain an INPPointCloudFrame object, markers detected in the frame are available via INPPointCloudPoint. Notifications about when a new frame of 3D data is available are received through the _INPPointCloudEvents interface.
-
5.3 Design Considerations
-
5.3.1 Getting Started
Only a small amount of code needs to be written in order to begin. The following outlines the procedure for initializing the camera:
- Make sure the cameras have been calibrated with the result saved to a file as described in Section 4.2 ("Camera Calibration tool").
- Create the INPPointCloud object.
- Load an existing calibration profile using the INPPointCloud->LoadProfile() method.
- Call the INPPointCloud->Start() method to enumerate and start the cameras.
At this point, the cameras should be initialized and collecting frame information. The main loop of the application should either handle frame callbacks using the _INPPointCloudEvents interface or poll for frames using INPPointCloud->GetFrame().
When data processing is complete, call the INPPointCloud->Stop() method.
5.3.2 Tracking Markers
The Point Cloud API provides a simple interface to the powerful functionality which collects 2D tracking data from multiple OptiTrack cameras and merges it into 3D position data. To create a single frame of 3D data the Point Cloud software will collect one frame from each camera present. When all of the frames are collected and the 3D position data has been calculated, a OnFrameAvailable() callback will be triggered to notify the client application. The client can also choose to poll for new frames using INPPointCloud->GetFrame(). The client will then obtain an INPPointCloudFrame object for the frame. This allows it to enumerate the individual markers as INPPointCloudPoints using the Item() call. The X, Y and Z axis position of the markers can be extracted at this time for use in the client application.
Frame Object Lifetime
Frame objects in the Point Cloud system are a limited resource. Be sure to call the Free() method to release the INPPointCloudFrame interface as quickly as possible.
Coordinate System
All position data will be returned in meters. The absolute accuracy of the coordinate system relies on a good calibration and the accurate use of a ground plane as described in Section 4.2 ("Camera Calibration tool").
5.3.3 Reading Camera Positions
Once a calibration is loaded, the position and orientation will be known for every camera that is connected as long as it was present during the calibration process. The position data can be extracted by enumerating the cameras through the GetCamera() call of the INPPointCloud interface. This returns an INPPointCloudCamera object which can be used to read X, Y, Z and the rotational data.
5.3.4 Connection Points
Standard COM connection points are used for callback notifications. Connection points were chosen because they are compatible with most languages that communicate with COM automation interfaces. See the COM documentation in the MSDN help for more information. Specifically, search for IConnectionPoint and IConnectionPointContainer. There is slightly more overhead involved with setting up connection points in C/C++, but sample code is provided to assist in coding.
5.3.5 Threading Issues
The OptiTrack APIs are apartment threaded. Apartment threaded means that only one thread can be used to call into the DLL at any given time. Any other threads that are used to call into the DLL while another thread is executing in the DLL will be blocked until the first thread completes.
This also affects how callbacks are implemented. Connection point callbacks must be done on the same thread that created the object. This is accomplished by creating a hidden window whenever an object that has connection points is created. The hidden window uses the message queue of the calling thread. Callbacks are done by posting a message to the hidden window and then calling the connection point callback interface.
The drawback to this mechanism is that the message queue for the thread that created the object needs to be free to run if OptiTrack notifications are to be handled in the timely fashion. For instance, if the main thread of a GUI application is used to create the OptiTrack camera object, make sure that no blocking operations are run on that thread. If a blocking operation is required, use a message loop to handle messages.
This issue only affects connection point callbacks. If camera frame information is gathered by polling this INPPointCloud interface, this is not a concern.
-
5.4 Interfaces
-
5.4.1 INPPointCloud
This is the main entry point for communicating with the Point Cloud toolkit. This interface provides the ability to enumerate cameras, load calibration profiles, and process tracking data.
-
5.4.1.1 INPPointCloud::LoadProfile( )
-
The LoadProfile( ) method attempts to load a calibration profile stored in a file. It is passed the path to the profile and returns information about whether or not it succeeded.
HRESULT LoadProfile(BSTR Filename);
Parameters
- Filename
[in] the path to the location of the calibration profile
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
| NP_POINTCLOUD_LOAD_FAILED |
Method failed, profile not loaded |
-
5.4.1.2 INPPointCloud::Start( )
-
The Start( ) method enumerates and starts the cameras so that tracking will begin. This method should be called after the LoadProfile( ) method.
HRESULT Start( );
Parameters
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
| NP_POINTCLOUD_FAILED |
Method failed, cameras could not be started |
-
5.4.1.3 INPPointCloud::Stop( )
-
The Stop( ) method stops the cameras so that tracking will cease.
HRESULT Stop( );
Parameters
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
| NP_POINTCLOUD_FAILED |
Method failed, cameras could not be stopped |
-
5.4.1.4 INPPointCloud::GetFrame( )
-
The GetFrame( ) method retrieves a INPPointCloudFrame object containing a processed frame of 3D tracking data.
HRESULT GetFrame(INPPointCloudFrame ** NPPointCloudFrame);
Parameters
- NPPointCloudFrame
[out] pointer that receives an INPPointCloudFrame interface. Return value will be NULL if no frame is available.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
-
5.4.1.5 INPPointCloud::GetCamera( )
-
The GetCamera( ) method retrieves a INPPointCloudCamera object for one of the connected OptiTrack cameras.
HRESULT GetCamera([in] LONG Index, [out] INPPointCloudCamera ** NPPointCloudCamera);
Parameters
- Index
[in] Index of the item to retrieve.
- NPPointCloudCamera
[out] pointer that receives a INPPointCloudCamera interface. Return value will be NULL if the camera does not exist.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
-
5.4.1.6 INPPointCloud::get_CameraCount( )
-
The get_CameraCount( ) method retrieves the number of connected OptiTrack cameras.
HRESULT get_CameraCount([out, retval] LONG* pVal);
Parameters
- pVal
[out] pointer that receives a LONG with the number of cameras connected.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
-
5.4.1.7 INPPointCloud2::GetCamera( )
-
The INPPointCloud2 GetCamera( ) method retrieves a INPPointCloudCamera2 object for one of the connected OptiTrack cameras. The INPPointCloud2 version of this method uses a retval unlike the INPPointCloud one.
HRESULT GetCamera([in] LONG Index, [out, retval] INPPointCloudCamera2 ** NPPointCloudCamera);
Parameters
- Index
[in] Index of the item to retrieve.
- NPPointCloudCamera2
[out, retval] pointer that receives a INPPointCloudCamera2 interface. Return value will be NULL if the camera does not exist.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
5.4.2 INPPointCloudFrame
This object contains information about the current frame of processed 3D tracking data. This interface is a standard COM enumeration interface containing a list of all objects in the frame.
-
5.4.2.1 INPPointCloudFrame::get_Count( )
-
The get_Count( ) method retrieves the number of 3D markers detected in the frame.
HRESULT get_Count([out, retval] LONG* pVal);
Parameters
- pVal
[out] pointer that receives a LONG with the number of 3D markers in the frame.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
-
5.4.2.1 INPPointCloudFrame::Item( )
-
The Item( ) allows the enumeration of the 3D markers detected in a frame.
HRESULT Item([in] LONG a_vlIndex, [out, retval] INPPointCloudPoint ** NPPointCloudPoint);
Parameters
- Index
[in] Index of the item to retrieve.
- NPPointCloudPoint
[out, retval] pointer that receives a INPPointCloudPoint interface. Return value will be NULL if the marker does not exist.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
5.4.3 INPPointCloudPoint
This object contains 3D (X,Y,Z) position information about a single detected marker in a frame.
-
5.4.3.1 INPPointCloudPoint::get_X( )
-
The get_X( ) method retrieves the X axis position of a 3D marker detected in the frame.
HRESULT get_X([out, retval] DOUBLE* pVal);
Parameters
- pVal
[out] pointer that receives a Double with the X axis position in meters of a 3D marker.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
| E_POINTER |
Pointer is invalid |
-
5.4.3.2 INPPointCloudPoint::get_Y( )
-
The get_Y( ) method retrieves the Y axis position of a 3D marker detected in the frame.
HRESULT get_Y([out, retval] DOUBLE* pVal);
Parameters
- pVal
[out] pointer that receives a Double with the Y axis position in meters of a 3D marker.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
| E_POINTER |
Pointer is invalid |
-
5.4.3.3 INPPointCloudPoint::get_Z( )
-
The get_Z( ) method retrieves the Z axis position of a 3D marker detected in the frame.
HRESULT get_Z([out, retval] DOUBLE* pVal);
Parameters
- pVal
[out] pointer that receives a Double with the Z axis position in meters of a 3D marker.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
| E_POINTER |
Pointer is invalid |
5.4.4 INPPointCloudCamera
This object contains 3D (X,Y,Z) position and orientatation (rotation) information about a connected OptiTrack camera.
-
5.4.4.1 INPPointCloudCamera::get_X( )
-
The get_X( ) method retrieves the X axis position of a camera.
HRESULT get_X([out, retval] DOUBLE* pVal);
Parameters
- pVal
[out] pointer that receives a Double with the X axis position in meters of a camera.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
| E_POINTER |
Pointer is invalid |
-
5.4.4.2 INPPointCloudCamera::get_Y( )
-
The get_Y( ) method retrieves the Y axis position of a camera
HRESULT get_Y([out, retval] DOUBLE* pVal);
Parameters
- pVal
[out] pointer that receives a Double with the Y axis position in meters of a camera.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
| E_POINTER |
Pointer is invalid |
-
5.4.4.3 INPPointCloudCamera::get_Z( )
-
The get_Z( ) method retrieves the Z axis position of a camera
HRESULT get_Z([out, retval] DOUBLE* pVal);
Parameters
- pVal
[out] pointer that receives a Double with the Z axis position in meters of a camera.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
| E_POINTER |
Pointer is invalid |
-
5.4.4.4 INPPointCloudCamera::GetRotationMatrix( )
-
The GetRotationMatrix( ) method retrieves one element from the Camera Rotation Matrix array.
HRESULT GetRotationMatrix([in] LONG Index, [out, retval] DOUBLE* pVal);
Parameters
- Index
[in] Index of the item in the array to retrieve. There are 9 elements in the array, valid inputs range from 0 to 9.
- pVal
[out] pointer that receives a Double with the selected item of the Camera Rotation Matrix array.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
| E_POINTER |
Pointer is invalid |
-
5.4.4.5 INPPointCloudCamera2::GetOptiTrackCamera( )
-
The GetOptiTrackCamera( ) method retrieves a OptiTrack INPCamera object. It is only available when using INPPointCloudCamera2.
HRESULT GetOptiTrackCamera([out, retval] INPCamera ** NPCamera);
Parameters
- Index
- pVal
[out, retval] pointer that receives a OptiTrack INPCamera interface. Return value will be NULL if the camera does not exist.
Parameters
| Value | Meaning |
| S_OK |
Method succeeded |
-
5.5 Return Codes
- The following is a listing of non-successful return codes for the Point Cloud API.
enum __MIDL___MIDL_itf_PointCloudCOM_0000_0001
{
NP_POINTCLOUD_FILE_NOT_FOUND = 1,
NP_POINTCLOUD_LOAD_FAILED = NP_POINTCLOUD_FILE_NOT_FOUND + 1,
NP_POINTCLOUD_FAILED = NP_POINTCLOUD_LOAD_FAILED + 1,
NP_POINTCLOUD_CAMERAS_ALREADY_STARTED = NP_POINTCLOUD_FAILED + 1,
NP_POINTCLOUD_CAMERAS_NOT_RUNNING = NP_POINTCLOUD_CAMERAS_ALREADY_STARTED + 1,
NP_POINTCLOUD_PROFILE_ALREADY_LOADED = NP_POINTCLOUD_CAMERAS_NOT_RUNNING + 1,
NP_POINTCLOUD_CAMERAS_RUNNING = NP_POINTCLOUD_PROFILE_ALREADY_LOADED + 1,
NP_POINTCLOUD_INVALID_FILE = NP_POINTCLOUD_CAMERAS_RUNNING + 1,
NP_POINTCLOUD_INVALID_PROFILE_CAMERA_COUNT = NP_POINTCLOUD_INVALID_FILE + 1,
NP_POINTCLOUD_UNABLE_TO_INITIALIZE_OPTITRACK_CAMERAS =
NP_POINTCLOUD_INVALID_PROFILE_CAMERA_COUNT + 1,
NP_POINTCLOUD_FAILED_LICENSE_CHECK =
NP_POINTCLOUD_UNABLE_TO_INITIALIZE_OPTITRACK_CAMERAS + 1,
NP_POINTCLOUD_NO_PROFILE_LOADED = NP_POINTCLOUD_FAILED_LICENSE_CHECK + 1
NP_POINTCLOUD;
}
|