Sign up Calendar Latest Topics
 
 
 


Reply
  Author   Comment  
dbuitra2

Junior Member
Registered:
Posts: 6
Reply with quote  #1 
Hi all
We are trying to run a behavioral task using 3D spatial information coming from a tracking system (optitrack), essentially the animal would be navigating in a cage and as he enters previously defined places we would trigger rewards and some sort of visual or auditory stimulation, right now the tracking software can output all the spatial information of the tracked object (x y z coordinates, timestamps, frame number) to matlab with event handlers, but we want to know if there is a way to use the tracking data coming to matlab as a custom input in mokeylogic so that we can do behavioral control as the animal navigates.

Thank you 
0
Jaewon

Administrator
Registered:
Posts: 730
Reply with quote  #2 
Do you know how the tracking software calls the matlab event handler (i.e., function)? Does the software have to run on the same computer with MATLAB?

What is the prototype of the event handler? How are the input arguments defined?
0
dbuitra2

Junior Member
Registered:
Posts: 6
Reply with quote  #3 
Hi Jaewon 

The tracking software comes with a matlab wrapper that connects to the computer that is getting all the tracking data using its IP address, so they can be in separate computers, the source code they provide is private but the description of the event handler goes like this:
% add some callback functions that execute autmatically in an asynchronous manner to the event of a new frame of mocap data, similar to how software interrupts operate. callback functions block further execution of running code and a event handler buffer is created with pending function callbacks to execute. Matlab by default is single threaded callbacks are added to the event handler buffer in no particular order. 
0
Jaewon

Administrator
Registered:
Posts: 730
Reply with quote  #4 
Okay. What is this MATLAB wrapper like? Does it have a GUI? Or is it a MATLAB script?

What do you need to do to register the callback? For example, a typical event handler registration goes like this:

[output1,output2] = addEventHandler(arg1,arg2,'plotData');  % plotData is the callback

Then the plotData() can be like this:

function plotData(src,event)  % this is the prototype of the callback
end

Please show me the code you need to type, to register the callback and to get the callback data.
0
dbuitra2

Junior Member
Registered:
Posts: 6
Reply with quote  #5 

 

The Event handler:


        natnetclient.addlistener( 1 , 'position' );
  fprintf( 'Enabling the listeners for asynchronous callback execution\n' )
  natnetclient.enable(1)
  pause(30)
  fprintf( 'Disabling the listeners\n')
  natnetclient.disable(0)
  disp('NatNet Event Handler Sample End' )
 
The Callback function:

 function position( ~ , evnt )
  rbnum = 1;%Rigid body number
  
  
  % Get the frame number
  frame = double( evnt.data.iFrame );
    
  % Get the rigid body position
  x = double( evnt.data.RigidBodies( rbnum ).x );
  y = double( evnt.data.RigidBodies( rbnum ).y );
  z = double( evnt.data.RigidBodies( rbnum ).z );
  
    end  

0
Jaewon

Administrator
Registered:
Posts: 730
Reply with quote  #6 
Good. I would add those event handler codes at the beginning and end of the timing file, for starters.

----- beginning of your timing file -----
natnetclient.addlistener( 1 , 'position' );
natnetclient.enable(1);


(other task control codes)

natnetclient.disable(0);
----- end of your timing file -----

You can start and stop the client when the task starts and ends using the alert function, rather than every trial, but it is up to you.

Then the position function will be called asynchronously during the ML task is running. Since the position function is not convenient to get the result of behavior monitoring, I would make a helper function, let's say, postrack(). Then let position() pass the information to postrack().

----- beginning of position() -----
function position( ~ , evnt )
rbnum = 1;%Rigid body number
 
% Get the frame number
frame = double( evnt.data.iFrame );
    
% Get the rigid body position
x = double( evnt.data.RigidBodies( rbnum ).x );
y = double( evnt.data.RigidBodies( rbnum ).y );
z = double( evnt.data.RigidBodies( rbnum ).z );

postrack(1,frame,x,y,z);

end
----- end of position() -----

postrack() checks the animal's position and stores the result as below.

----- beginning of postrack() -----
function varargout = postrack(command,varargin)
persistent IsTheAnimalThere
if isempty(IsTheAnimalThere), IsTheAnimalThere = false; end

switch command
    case 1
        frame = varargin{1};
        x = varargin{2};
        y = varargin{3};
        z = varargin{4};

       % check if the animal is in the defined place
       if  x==2 && y==3 & z==4  % this condition is just an example.
           IsTheAnimalThere = true;
       else
           IsTheAnimalThere = false;
       end

    case 2
        varargout{1} = IsTheAnimalThere;
end

end
----- end of postrack() -----

Then you can read the result of the position evaluation from the timing file like this:

IsTheAnimalThere = postrack(2);

I didn't test if the above codes actually work, but I think you can get the idea.
0
dbuitra2

Junior Member
Registered:
Posts: 6
Reply with quote  #7 
Thanks for your reply Jaewon! It was very helpful
0
Previous Topic | Next Topic
Print
Reply

Quick Navigation:

Easily create a Forum Website with Website Toolbox.