Motive API: Quick Start Guide
Last updated
Last updated
SDK/API Support Disclaimer
We provide developer tools to enable OptiTrack customers across a broad set of applications to utilize their systems in the ways that best suit them. Our Motive API through the NatNet SDK and Camera SDK is designed to enable experienced software developers to integrate data transfer and/or system operation with their preferred systems and pipelines. Sample projects are provided alongside each tool, and we strongly recommend the users to reference or use the samples as reliable starting points. The following list specifies the range of support that will be provided for the SDK tools:
Using the SDK tools requires background knowledge on software development; therefore, we do not provide support for basic project setup, compiling, and linking when using the SDK/API to create your own applications.
Although we ensure the SDK tools and their libraries work as intended, we do not provide support for custom developed applications that have been programmed or modified by users using the SDK tools.
Ticketed support will be provided for licensed Motive users using the Motive API and/or the NatNet SDK tools from the included libraries and sample source codes only.
The Camera SDK is a free product, and therefore we do not provide free ticketed support for it.
For other questions, please check out the . Very often, similar development issues get reported and solved there.
This guide provides detailed instructions on commonly used functions of the Motive API for developing custom applications. For a full list of the functions, refer to the page. Also, for a sample use case of the API functions, please check out the provided project. In this guide, the following topics will be covered:
Library files and header files
Initialization and shutdown
Capture setup (Calibration)
Configuring camera settings
Updating captured frames
3D marker tracking
Rigid body tracking
Data streaming
When developing a Motive API project, make sure its linker knows where to find the required library files. This can be done either by specifying its location within the project or by copying these files onto the project folder.
MotiveAPI.h
Motive API libraries (.lib and .dll) are located in the lib folder within the Motive install directory; which is located at C:\Program Files\OptiTrack\Motive\lib
by default. In this folder, library files for both 64-bit (MotiveAPI.dll and MotiveAPI.lib) platforms can be found. When using the API library, all of the required DLL files must be located in the executable directory. Copy and paste the MotiveAPI.dll file onto the folder alongside the executable file.
Third-party Libraries
Additional third-party libraries are required for Motive API, and most of the DLL files for these libraries can be found in the Motive install directory C:\Program Files\OptiTrack\Motive\
. You can simply copy and paste all of the DLL files from the Motive installation directory into the directory of the Motive API project to use them. Highlighted items in the below image are the required DLL files.
Lastly, copy the C:\Program Files\OptiTrack\Motive\plugins\platforms
folder and its contents into the EXE as well since the libraries contained in this folder will also be used.
For function declarations, there are two required header files: MotiveAPI.h and RigidBodySettings.h, and these files are located in the C:\Program Files\OptiTrack\Motive\inc\
folder. Always include the directive syntax for adding the MotiveAPI.h header file for all programs that are developed against the Motive API. The syntax for including RigidBodySetting.h file is already included in the MotiveAPI.h file, so there is no need to include this separately.
The MotiveAPI.h file contains the declaration for most of the functions and classes in the API.
The RigidBodySettings.h file contains declaration for the cRigidBodySettings class, which is used for configuring Rigid Body asset properties.
Motive API, by default, loads the default calibration (CAL) and Application profile (MOTIVE) files from the program data directory unless separately specified. These are the files that Motive also loads at the application startup, and they are located in the following folder:
Default System Calibration: C:\ProgramData\OptiTrack\Motive\System Calibration.cal
Default Application Profile: C:\ProgramData\OptiTrack\MotiveProfile.motive
When using the API, connected devices and the Motive API library need to be properly initialized at the beginning of a program and closed down at the end. The following section covers Motive API functions for initializing and closing down devices.
Motive Profile Load
Please note that TT_Initialization loads the default Motive profiles (MOTIVE) from the ProgramData directory during the initialization process. To load Motive profile, or settings, from a specified directory, use TT_LoadProfile.
Loading Calibration
Open Motive.
Close out of Motive.
When successfully loaded, you will be able to obtain 3D tracking data using the API functions.
Note:
Calibration Files: When using the exported calibration files, make sure to use only valid calibration. Exported calibration file can be used again as long as the system setup remains unchanged. Note that the file will no longer be valid if any of the system setups have been altered after the calibration. Also, calibration quality may degrade over time due to environmental factors. For these reasons, we recommend re-calibrating the system routinely to guarantee the best tracking quality.
Tracking Bars: If you are using a tracking bar, camera calibration is not required for tracking 3D points.
If you wish to keep part of the current camera settings, you can use the above functions to obtain the configured settings (e.g. TT_CameraVideoType, TT_CameraFrameRate, TT_CameraExposure, etc.) and use them as input arguments for the TT_SetCameraSettings function. The following example demonstrates modifying frame rate and IR illumination intensity for all of the cameras, while keeping the other settings constant.
Camera Settings
Valid frame rate values: Varies depending on camera models, refer to the respective hardware specifications.
Valid exposure values: Depends on camera model and frame rate settings.
Valid threshold values: 0 - 255
Valid intensity values: 0 - 15
Video Types
Segment Mode: 0
Grayscale Mode: 1
Object Mode: 2
Precision Mode: 4
MJPEG Mode: 6
In order to process multiple consecutive frames, you must update the camera frames using the following API functions: TT_Update or TT_UpdateSingleFrame. Call one of the two functions repeatedly within a loop to process all of the incoming frames. In the 'marker sample', TT_Update function is called within a while loop as the frameCounter variable is incremented, as shown in the example below.
There are two functions for updating the camera frames: TT_Update and TT_UpdateSingleFrame. At the most fundamental level, these two functions both update the incoming camera frames. However, they may act differently in certain situations. When a client application stalls momentarily, it could get behind on updating the frames and the unprocessed frames may be accumulated. In this situation, each of these two functions will behave differently.
The TT_Update() function will disregard accumulated frames and service only the most recent frame data, but it also means that the client application will not be processing the previously missed frames.
The TT_UpdateSingleFrame() function ensures that only one frame is processed each time the function is called. However, when there are significant stalls in the program, using this function may result in accumulated processing latency.
In general, a user should always use TT_Update(). Only in the case where a user wants to ensure their client application has access to every frame of tracking data and they are having problems calling TT_Update() in a timely fashion, should they consider using TT_UpdateSingleFrame(). If it is important for your program to obtain and process every single frame, use the TT_UpdateSingleFrame() function for updating the data.
Marker Index
Marker Position
Let's go through importing RB assets into a client application using the API. In Motive, Rigid Body assets can be created from three or more reconstructed markers, and all of the created assets can be exported out into either application profile (MOTIVE) or a Motive Rigid Body file (TRA). Each Rigid Body asset saves marker arrangements when it was first created. As long as the marker locations remain the same, you can use saved asset definitions for tracking respective objects.
Exporting all RB assets from Motive:
Exporting application profile: File → Save Profile
Exporting Rigid Body file (TRA): File → Export Rigid Bodies (TRA)
Exporting individual RB asset:
Example: Creating RB Assets
Example: RB Tracking Data
The Motive API does not currently support configuring data streaming settings directly from the API. To configure the streaming server IP address and the data streaming settings, you will need to use Motive and save an application profile MOTIVE file that contains the desired configuration. Then, the exported profile can be loaded when using the API. Through this way, you will be able to set the interface IP address and decide which data to be streamed over the network.
Note: You could define these directories by using the MOTIVEAPI_INC
, MOTIVEAPI_LIB
environment variables. Check the project properties (Visual Studio) of the provided project for a sample project configuration.
If there are specific files that need to be loaded into the project, you can export and import two files from Motive: motive application profile (MOTIVE) and camera calibration (CAL). The is imported in order to obtain software settings and trackable asset definitions. Only after the camera calibration is imported, reliable 3D tracking data can be obtained. Application profiles can be loaded using the function, and the calibration files can be loaded using the TT_LoadCalibration function.
To initialize all of the connected cameras, call the function. This function initializes the API library and gets the cameras ready for capturing data, so always call this function at the beginning of a program. If you attempt to use the API functions without the initialization, you will get an error.
The function is primarily used for updating captured frames, which will be covered later, but there is another use. The TT_Update can also be called to update a list of connected devices, and you can call this function after the initialization to make sure all of the newly connected devices are properly initialized in the beginning.
When exiting out of a program, make sure to call the function to completely release and close down all of the connected devices. Cameras may fail to shut down completely when this function is not called.
The Motive application profile (MOTIVE) stores all the trackable assets involved in a capture and software configurations including and . When using the API, it is strongly recommended to first configure all of the settings and define trackable assets in Motive, export a profile MOTIVE file, and then load the file by calling the function. This way, you can adjust the settings for your need in advance and apply them to your program without worrying about configuring individual settings.
Cameras must be calibrated in order to track in 3D space. However, since camera calibration is a complex process, and because of this, it's easier to have the camera system calibrated from Motive, export the camera calibration file (CAL), and the exported file can be loaded into custom applications that are developed against the API. Once the calibration data is loaded, the 3D tracking functions can be used. For detailed instructions on camera calibration in Motive, please read through the page.
[Motive] Calibrate: Calibrate camera system using the Calibration panel. Read through the page for details.
[Motive] Export: After the system has been calibrated, export from Motive.
[API] Load: Import calibration onto your custom application by calling the function to import CAL files.
Connected cameras are accessible by index numbers. The camera indexes are assigned in the order the cameras are initialized. Most of the API functions for controlling cameras require an index value. When processing all of the cameras, use the function to obtain the total camera count and process each camera within a loop. For pointing to a specific camera, you can use the or functions to check and use the camera with given its index value. This section covers Motive API functions for checking and configuring camera frame rate, camera video type, camera exposure, pixel brightness threshold, and IR illumination intensity.
The following functions return integer values for the configured settings of a camera specified by its index number. Camera video type is returned as an integer value that represents a image processing mode, as listed in the .
These camera settings are equivalent to the settings that are listed in the Devices pane of Motive. For more information on each of the camera settings, refer to the page.
Now that we have covered functions for obtaining configured settings, now let's modify some of them. There are two main functions for adjusting the camera settings: and . The TT_SetCameraSettings function configures video type, exposure, threshold, and intensity settings of a camera which is specified by its index number. The TT_SetCameraFrameRate is used for configuring frame rate of a camera. Supported frame rate range may vary for different camera models. Check the device specifications and apply the frame rates only within the supported range.
Video Type: see the page for more information on image processing modes.
There are other camera settings, such as imager gain, that can be configured using the Motive API. Please refer to the page for descriptions on other functions.
After loading valid , you can use the API functions to track retroreflective markers and get their 3D coordinates. The following section demonstrates using the API functions for obtaining the 3D coordinates. Since marker data is obtained for each frame, always call the , or the , function each time newly captured frames are received.
In a given frame, each reconstructed marker is assigned a marker index number. These marker indexes are used for pointing to a particular reconstruction within a frame. You can also use the function to obtain the total marker count and use this value within a loop to process all of the reconstructed markers. Marker index values may vary between different frames, but unique identifiers will always remain the same. Use the function to obtain the individual marker labels if you wish to access same reconstructions for multiple frames.
For obtaining 3D position of a reconstructed marker, you can use , , and functions. These functions return 3D coordinates (X/Y/Z) of a marker in respect to the global coordinate system, which was defined during the calibration process. You can further analyze 3D movements directly from the reconstructed 3D marker positions, or you can create a Rigid Body asset from a set of tracked reconstructions for 6 Degrees of Freedom tracking data. Rigid body tracking via the API will be explained in the later section.
For tracking 6 degrees of freedom (DoF) movement of a Rigid Body, a corresponding Rigid Body (RB) asset must be defined. A RB asset is created from a set of reflective markers attached to a rigid object which is assumed to be undeformable. There are two main approaches for obtaining RB assets when using Motive API; you can either import existing Rigid Body data or you can define new Rigid Bodies using the function. Once RB assets are defined in the project, Rigid Body tracking functions can be used to obtain the 6 DoF tracking data. This section covers sample instructions for tracking Rigid Bodies using the Motive API.
We strongly recommend reading through the page for more information on how Rigid Body assets are defined in Motive.
Exporting Rigid Body file (TRA): Under the , right-click on a RB asset and click Export Rigid Body
When using the API, you can load exported assets by calling the function for application profiles and the or function for TRA files. When importing TRA files, the TT_LoadRigidBodies function will entirely replace the existing Rigid Bodies with the list of assets from the loaded TRA file. On the other hand, TT_AddRigidBodes will add the loaded assets onto the existing list while keeping the existing assets. Once Rigid Body assets are imported into the application, the API functions can be used to configure and access the Rigid Body assets.
Rigid body assets can also be defined directly using the API. The function defines a new Rigid Body from given 3D coordinates. This function takes in an array float values which represent x/y/z coordinates or multiple markers in respect to Rigid Body pivot point. The float array for multiple markers should be listed as following: {x1, y1, z1, x2, y2, z2, …, xN, yN, zN}. You can manually enter the coordinate values or use the TT_FrameMarkerX, TT_FrameMarkerY, and TT_FrameMarkerZ functions to input 3D coordinates of tracked markers.
When using the functions, you need to keep in mind that these locations are taken in respect to the RB pivot point. To set the pivot point at the center of created Rigid Body, you will need to first compute pivot point location, and subtract its coordinates from the 3D coordinates of the markers obtained by the TT_FrameMarkerX/Y/Z functions. This process is shown in the following example.
6 DoF Rigid Body tracking data can be obtained using the function. Using this function, you can save 3D position and orientation of a Rigid Body into declared variables. The saved position values indicate location of the Rigid Body pivot point, and they are represented in respect to the global coordinate axis. The Orientation is saved in both Euler and Quaternion orientation representations.
In Motive, Rigid Body assets have assigned to each of them. Depending on how these properties are configured, display and tracking behavior of corresponding Rigid Bodies may vary. When using the API, Rigid Body properties are configured and applied using the cRigidBodySettings class which is declared within the RigidBodySetting.h header file.
Within your program, create an instance of cRigidBodySettings class and call the API functions to obtain and adjust Rigid Body properties. Once desired changes are made, use the function to assign the properties back onto a Rigid Body asset.
For detailed information on individual Rigid Body settings, read through the page.
Once the API has been successfully initialized, data streaming can be enabled, or disabled, by calling either the , , or function. The TT_StreamNP function enables/disables data streaming via the NatNet. The is a client/server networking SDK designed for sending and receiving NaturalPoint data across networks, and tracking data from the API can be streamed to client applications from various platforms via the NatNet protocol. Once the data streaming is enabled, connect the NatNet client application to the server IP address to start receiving the data.
The TT_StreamNP function is equivalent to Broadcast Frame Data from the pane in Motive.
For more information on data streaming settings, read through the page.