Difference between revisions of "Optitrak + Projector touch table/surface"
Jump to navigation
Jump to search
Line 1: | Line 1: | ||
==Calibration with Tracking Tools== | |||
''note: if you are using the laptop setup in room 3108, make sure that the dongle for Tracking Tools is not plugged in when starting up the computer.'' | |||
Revision as of 17:38, 30 April 2012
Calibration with Tracking Tools
note: if you are using the laptop setup in room 3108, make sure that the dongle for Tracking Tools is not plugged in when starting up the computer.
Matlab scripts
Function: Setting the optitrak plane in matlab
In place of the matlab code for reading in optitrak data, the following matlab function can be used to:
- read in data sent from the optitrak system, and furthermore
- set the table top plane, as understood by the Optitrak, into variables for reference in matlab, and
- transform the native coordinate system of the optitrak (x z y) into another, possibly more familiar coordinate system (x y z).
This function will return:
This function should be called before opening a main window with psychtoolbox.
function [touch_plane_info, client] = opti_setup_touch_plane_srt %This gives an error (freezes) if the NET assembly is already loaded. In %that case you need to quit Matlab and start over if ~IsAssemblyAdded('NatNetML') Opti = NET.addAssembly('C:\Users\Jim Enns\Documents\MATLAB\NatNetSDK2.2\NatNetSDK\lib\NatNetML.dll'); end client = NatNetML.NatNetClientML(1); %client.Initialize('142.103.0.167','142.103.0.167'); client.Initialize('142.103.251.175','142.103.251.175'); data = client.GetLastFrameOfData; reply = 'N'; while ~strcmpi(reply,'Y') answer = {}; while isempty(answer) prompt={'Pixel Coords: '}; name='Lower Left Corner'; numlines=[1,35]; %this width allows for title to be seen defaultanswer={'[0 768]'}; answer=inputdlg(prompt,name,numlines,defaultanswer); %convert from string to number data for output variables if ~isempty(answer) OriginPixelCoords = str2num(answer{1}); end end pDataDest = [data.OtherMarkers(1).x data.OtherMarkers(1).z data.OtherMarkers(1).y]; Question = {'LOWER LEFT pre coordinate transform:'... ... 'Marker 1: ' num2str(pDataDest(1:3))... ... 'Accept?'... }; ButtonName = questdlg(Question, 'Data Check', 'Yes', 'No', 'Quit', 'Yes'); switch ButtonName case 'Yes' orig_pos = pDataDest; reply = 'Y'; case 'No' reply = 'N'; case 'Quit' %quit opto too? %need to pass quit flag so this actually works? transform_info = []; clear all; close all; Screen('CloseAll'); disp('*** Exiting Program ***'); return end end %take a point on +ve x axis reply='N'; while ~strcmpi(reply,'Y') answer = {}; while isempty(answer) prompt={'Pixel Coords: '}; name='Lower Right Corner'; numlines=[1,35]; %this width allows for title to be seen defaultanswer={'[1024 768]'}; answer=inputdlg(prompt,name,numlines,defaultanswer); %convert from string to number data for output variables if ~isempty(answer) XAxisPixelCoords = str2num(answer{1}); end end pDataDest = [data.OtherMarkers(1).x data.OtherMarkers(1).z data.OtherMarkers(1).y]; Question = {'LOWER RIGHT pre coordinate transform:'... ... 'Marker 1: ' num2str(pDataDest(1:3))... ... 'Accept?'... }; ButtonName = questdlg(Question, 'Data Check', 'Yes', 'No', 'Quit', 'Yes'); switch ButtonName case 'Yes' x_axis = pDataDest; reply = 'Y'; case 'No' reply = 'N'; case 'Quit' %quit opto too? %need to pass quit flag so this actually works? clear all; close all; Screen('CloseAll'); disp('*** Exiting Program ***'); return end end % point on the xy plane reply='N'; while ~strcmpi(reply,'Y') answer = {}; while isempty(answer) prompt={'Pixel Coords: '}; name='Upper Left Corner'; numlines=[1,35]; %this width allows for title to be seen defaultanswer={'[0 0]'}; answer=inputdlg(prompt,name,numlines,defaultanswer); %convert from string to number data for output variables if ~isempty(answer) YAxisPixelCoords = str2num(answer{1}); end end pDataDest = [data.OtherMarkers(1).x data.OtherMarkers(1).z data.OtherMarkers(1).y]; Question = {'UPPER LEFT pre coordinate transform:'... ... 'Marker 1: ' num2str(pDataDest(1:3))... ... 'Accept?'... }; ButtonName = questdlg(Question, 'Data Check', 'Yes', 'No', 'Quit', 'Yes'); switch ButtonName case 'Yes' y_axis = pDataDest; reply = 'Y'; case 'No' reply = 'N'; case 'Quit' %quit opto too? %need to pass quit flag so this actually works? clear all; close all; Screen('CloseAll'); disp('*** Exiting Program ***'); return end end % finish the screen rect (event though this is redundant for establishing % the plane) reply='N'; while ~strcmpi(reply,'Y') answer = {}; while isempty(answer) prompt={'Pixel Coords: '}; name='Upper Right Corner'; numlines=[1,35]; %this width allows for title to be seen defaultanswer={'[1024 0]'}; answer=inputdlg(prompt,name,numlines,defaultanswer); %convert from string to number data for output variables if ~isempty(answer) OppCornerPixelCoords = str2num(answer{1}); end end pDataDest = [data.OtherMarkers(1).x data.OtherMarkers(1).z data.OtherMarkers(1).y]; Question = {'UPPER RIGHT pre coordinate transform:'... ... 'Marker 1: ' num2str(pDataDest(1:3))... ... 'Accept?'... }; ButtonName = questdlg(Question, 'Data Check', 'Yes', 'No', 'Quit', 'Yes'); switch ButtonName case 'Yes' opp_corner = pDataDest; reply = 'Y'; case 'No' reply = 'N'; case 'Quit' %quit opto too? %need to pass quit flag so this actually works? clear all; close all; Screen('CloseAll'); disp('*** Exiting Program ***'); return end end %Create the Coordinate Systesm [T_opto_plane,T_plane_opto]=MakeCoordSystem(orig_pos,x_axis,y_axis); %Display the new transformed coordinate system disp('Points in Local Coordinate System are:') [new_orig]=transform4(T_opto_plane, orig_pos) [new_x_axis]=transform4(T_opto_plane, x_axis) [new_y_axis]=transform4(T_opto_plane, y_axis) [new_opp_corner]=transform4(T_opto_plane, opp_corner) touch_plane_info.T_opto_plane = double(T_opto_plane); touch_plane_info.T_plane_opto = double(T_plane_opto); touch_plane_info.opto_rect = double([new_orig; new_x_axis; new_y_axis; new_opp_corner]); touch_plane_info.pixel_rect = double([OriginPixelCoords; XAxisPixelCoords; YAxisPixelCoords; OppCornerPixelCoords]); touch_plane_info.old_opto_rect = double([orig_pos; x_axis; y_axis; opp_corner]); %calculate the pixel to opto conversion mm1 = double((new_x_axis(1) - new_orig(1))/(XAxisPixelCoords(1) - OriginPixelCoords(1)) * 1000); mm2 = double((new_opp_corner(1) - new_y_axis(1))/(OppCornerPixelCoords(1) - YAxisPixelCoords(1)) * 1000); mm3 = double(-(new_orig(2) - new_y_axis(2))/(OriginPixelCoords(2) - YAxisPixelCoords(2)) * 1000); mm4 = double(-(new_x_axis(2) - new_opp_corner(2))/(XAxisPixelCoords(2) - OppCornerPixelCoords(2)) * 1000); touch_plane_info.mmPerPixel = mean ([mm1 mm2 mm3 mm4]);