Discussion and Support for the OptiTrack, SmartNav and TrackIR brands by NaturalPoint

Tracking tools - Matlab and Labview

by heath789 » Mon Aug 15, 2011 8:51 am

I am using tracking tools v 2.3.1 and I am trying to compile the files included with it. I am using MATLAB with its included compiler. I am running 64 bit windows 7 but 32-bit TT and MATLAB to make sure the files are read in correctly. I am trying to use the API without Tracking Tools running to no avail.
Posts: 41
Joined: Wed Aug 10, 2011 7:42 am

by NaturalPoint - Mike » Tue Aug 16, 2011 12:38 am

What in particular are you trying to use, and what failure are you getting?
NaturalPoint - Mike
Posts: 1896
Joined: Tue Feb 01, 2011 8:41 am
Location: Corvallis, OR

by heath789 » Tue Aug 16, 2011 7:08 am

Thanks for the quick responses, Mike.

I am trying to use the TT_TrackableLocation function. In the header file, this is listed as a void function so I don't understand how its outputs should be handled. In the sample code for MATLAB posted in this thread, it is called like so:

[X,Y,Z,qx,qy,qz,qw,yaw,pitch,roll] =

The error I get in MATLAB when trying to run this is:

Caught unexpected char* Exception message is: index out of range

From the header file, I can't fully understand this function; can you provide more info as to how it works with inputs and outputs?

Posts: 41
Joined: Wed Aug 10, 2011 7:42 am

by davianmcllm » Sat Aug 27, 2011 5:31 am

how can i plug the matlab code into the labview?

As i need to deal with the Bspline nonlinear water tanks now..No idea how to set up the labview for that

i wonder anycode in labview can make my life go easier
Posts: 1
Joined: Sat Aug 27, 2011 5:24 am

by beckdo » Mon Aug 29, 2011 1:48 pm

heath789, I don't have much experience will plugging external DLLs into matlab, but I can give you more information about the function. Basically, the first parameter passed in is the index to the rigid body of interest. The following 10 parameters are pointers to floats. When calling, the function will populated the floats stored at the pointer locations with the position, quaternion orientation, and Euler angles.
NaturalPoint Employee
NaturalPoint Employee
Posts: 516
Joined: Tue Jan 02, 2007 2:02 pm

by litch09 » Wed Nov 30, 2011 8:59 pm

Sorry that I have not visited this forum for a while.

davianmcllm - please go to to see the labview implementation and instructions. This has NOT been tested on the latest versions of Tracking Tools.

heath789 - I will check out the why this does not work... i have not tested this code on the latest versions of TT. you certainly cannot run the Tracking Tools software at the same time as trying to run through the API.
Posts: 32
Joined: Tue Mar 10, 2009 6:28 pm

by vrtroopers » Fri Jun 29, 2012 8:57 am

litch09, I have been attempting to create live plots of the position of trackables in Matlab. Would you be willing to share the code you wrote to accomplish this?
Posts: 3
Joined: Wed Jun 20, 2012 9:10 am

by litch09 » Thu Oct 25, 2012 5:31 pm

For anyone who is interested, I have recently tried running previously posted Matlab code on the latest 64-bit version of TT (2.5.0) with a 64-bit version of Matlab and haven't succeeded. It seems that 'loadlibrary' throws an error that I can't pinpoint the source of. I will look into this further for a solution....
Posts: 32
Joined: Tue Mar 10, 2009 6:28 pm

by Stefano » Tue Feb 11, 2014 5:47 am

smith32 wrote:Quick update, I searched around and realized that I could just rename and compile my C coded S-Function as C++. As soon as I did this, all the errors went away. Hopefully this will help out others if they're looking to do something similar.

I plan on developing a TrackingTools Simulink block and some NatNet streaming blocks, when it's finished I'll post a link to the files for others to use.



I'm looking for a S-Function for Simulink to get the Real-Time-Info from Tracking Tools.
Did you finish your project?
Can you show me the code of the S-Function?


Posts: 5
Joined: Mon Nov 11, 2013 5:54 am

by Stefano » Thu Feb 20, 2014 1:24 pm


I was able to create a s-function for simulink.
The function imports the angel and position data from tracking tools.

Code: Select all
function NatNetsFunction(block)
% Level-2 MATLAB file S-Function for unit delay demo.
%   Copyright 1990-2009 The MathWorks, Inc.
%   $Revision: $
function setup(block)
  block.NumDialogPrms  = 1;
  %% Register number of input and output ports
  block.NumInputPorts  = 1;
  block.NumOutputPorts = 1;
  %% Setup functional port properties to dynamically
  %% inherited.
  block.InputPort(1).Dimensions        = 1;
  block.InputPort(1).DirectFeedthrough = false;
  block.OutputPort(1).Dimensions       = 6;  % one Object: (x,y,z, yaw, pitch, roll)
  %% Set block sample time to [0.01 0]
  block.SampleTimes = [0.01 0];
  %% Set the block simStateCompliance to default (i.e., same as a built-in block)
  block.SimStateCompliance = 'DefaultSimState';
  %% Register methods
  block.RegBlockMethod('PostPropagationSetup',    @DoPostPropSetup);
  block.RegBlockMethod('InitializeConditions',    @InitConditions); 
  block.RegBlockMethod('Outputs',                 @Output); 
  block.RegBlockMethod('Update',                  @Update);
  block.RegBlockMethod('Terminate',               @Terminate);
function DoPostPropSetup(block)
  %% Setup Dwork
  block.NumDworks = 1;
  block.Dwork(1).Name = 'x0';
  block.Dwork(1).Dimensions      = 1;
  block.Dwork(1).DatatypeID      = 0;
  block.Dwork(1).Complexity      = 'Real';
  block.Dwork(1).UsedAsDiscState = true;
function InitConditions(block)
  %% Initialize Dwork
  block.Dwork(1).Data = block.DialogPrm(1).Data;
 display('NatNet Sample Begin')
    global theClient;
    global frameRate;
    lastFrameTime = -1.0;
    lastFrameID = -1.0;
    usePollingLoop = false;         % approach 1 : poll for mocap data in a tight loop using GetLastFrameOfData
    usePollingTimer = false;        % approach 2 : poll using a Matlab timer callback ( better for UI based apps )
    useFrameReadyEvent = true;      % approach 3 : use event callback from NatNet (no polling)
  %  useUI = true;
  %  persistent arr;
    % Open figure
  %  if(useUI)
  %      hFigure = figure('Name','OptiTrack NatNet Matlab Sample','NumberTitle','off');
  %  end
   % try
        % Add NatNet .NET assembly so that Matlab can access its methods, delegates, etc.
        % Note : The NatNetML.DLL assembly depends on NatNet.dll, so make sure they
        % are both in the same folder and/or path if you move them.
        display('[NatNet] Creating Client.')
        % TODO : update the path to your NatNetML.DLL file here
        %dllPath = fullfile('c:','NatNetSDK2.5','Samples','bin','NatNetML.dll');
        dllPath = fullfile('c:','NatNetSDK2.5','lib','x64','NatNetML.dll');
        %dllPath = fullfile('c:','NaturalPoint Trackd Module','naturalpointtracker.dll');
        assemblyInfo = NET.addAssembly(dllPath);
        % Create an instance of a NatNet client
        theClient = NatNetML.NatNetClientML(0); % Input = iConnectionType: 0 = Multicast, 1 = Unicast
        version = theClient.NatNetVersion();
        fprintf( '[NatNet] Client Version : %d.%d.%d.%d\n', version(1), version(2), version(3), version(4) );
        % Connect to an OptiTrack server (e.g. Motive)
        display('[NatNet] Connecting to OptiTrack Server.')
        hst =;
        %HostIP = char(hst.getHostAddress);
        HostIP = char('');%Get IP
        flg = theClient.Initialize(HostIP, HostIP); % Flg = returnCode: 0 = Success
        if (flg == 0)
            display('[NatNet] Initialization Succeeded')
            display('[NatNet] Initialization Failed')
        % print out a list of the active tracking Models in Motive
        % Test - send command/request to Motive
        [byteArray, retCode] = theClient.SendMessageAndWait('FrameRate');
        if(retCode ==0)
            byteArray = uint8(byteArray);
            frameRate = typecast(byteArray,'single');
    function Output(block)
        %block.OutputPort(1).Data = block.Dwork(1).Data;
        global theClient;
        data = theClient.GetLastFrameOfData();
        %frameTime = data.fLatency;
        %frameID = data.iFrame;
        %                     if(frameTime ~= lastFrameTime)
        %                         fprintf('FrameTime: %0.3f\tFrameID: %5d\n',frameTime, frameID);
        %                         lastFrameTime = frameTime;
        %                         lastFrameID = frameID;
        %                     else
        %                         display('Duplicate frame');
        %                     end
        function Update(block)
            block.Dwork(1).Data = block.InputPort(1).Data;
 function Terminate(block)
      global theClient;
     display('NatNet Sample End')
      function [D] = ProcessFrame( frameOfData )
          rigidBodyData = frameOfData.RigidBodies(1);
          % Position
          % Test : Marker Y Position Data
          % angleY = data.LabeledMarkers(1).y;
          % Test : Rigid Body Y Position Data
          D.x= rigidBodyData.x*1000;
          D.y= rigidBodyData.y*1000;
          D.z= rigidBodyData.z*1000;
          % Test : Rigid Body 'Yaw'
          % Note : Motive display euler's is X (Pitch), Y (Yaw), Z (Roll), Right-Handed (RHS), Relative Axes
          % so we decode eulers heres to match that.
          % Orientation
          q = quaternion( rigidBodyData.qx, rigidBodyData.qy, rigidBodyData.qz, rigidBodyData.qw );
          qRot = quaternion( 0, 0, 0, 1);     % rotate pitch 180 to avoid 180/-180 flip for nicer graphing
          q = mtimes(q, qRot);
          angles = EulerAngles(q,'zyx');
          D.angleX = -angles(1) * 180.0 / pi;   % must invert due to 180 flip above
          D.angleY = angles(2) * 180.0 / pi;
          D.angleZ = -angles(3) * 180.0 / pi;   % must invert due to 180 flip above

Hope this is helpfull for some of you.
Posts: 5
Joined: Mon Nov 11, 2013 5:54 am


Return to Tracking Tools