Skip to content

Commit

Permalink
Add local files
Browse files Browse the repository at this point in the history
  • Loading branch information
lauraporta committed Nov 7, 2024
1 parent fffe347 commit 9fa8559
Show file tree
Hide file tree
Showing 10 changed files with 478 additions and 4 deletions.
Binary file added Copy_of_calibration.mat
Binary file not shown.
9 changes: 6 additions & 3 deletions corridor_mp_300/run_virtual_corridor_mp_300.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ function run_virtual_corridor_mp_300()
ai_chan = 'ai0';
ai_offset = calibration.offset;
cm_per_s_per_volts = calibration.scale;
ai_deadband = 0.005;
%ai_deadband = 0.005;
ai_deadband = 0.01;
di_chan = 'port0/line0';
max_speed = 100; % cm/s
di_chan_gain_on = 'port0/line1';


%% load parameters for the corridor
Expand All @@ -65,6 +67,7 @@ function run_virtual_corridor_mp_300()

di = daq.createSession('ni');
di.addDigitalChannel(nidaq_dev, di_chan, 'InputOnly');
di.addDigitalChannel(nidaq_dev, di_chan_gain_on, 'InputOnly');


%% startup psychotoolbox
Expand Down Expand Up @@ -151,7 +154,7 @@ function run_virtual_corridor_mp_300()
% poll the digital input
di_state = inputSingleScan(di);

if di_state == 1
if di_state(1) == 1
Screen('FillRect', window, 0);
Screen('Flip', window);
if n_independent_screens == 2
Expand All @@ -170,7 +173,7 @@ function run_virtual_corridor_mp_300()
% compute the updated position
ai_volts = (ai_volts - ai_offset);
if abs(ai_volts) > ai_deadband
speed = cm_per_s_per_volts * ai_volts;
speed = cm_per_s_per_volts * ai_volts * di_state(2);
pos = pos + speed * (toc(last_tic));
else
speed = 0;
Expand Down
262 changes: 262 additions & 0 deletions corridor_mp_300/run_virtual_corridor_mp_300_gratings.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
function run_virtual_corridor_mp_300_gratings()
%%RUN_VIRTUAL_CORRIDOR_MP_300()
% Runs an inifinite loop in a corridor.
% Start at position 0, listens to an analog input and computes a "position"
% value (integration of the analog input which it expects to be a )
% If digital input is high, screen is black and position resets to 0.
% Relevant parameters are inside this script... will be a good idea to take them
% out.
% Must pre-create the corridor (using 'create_virtual_corridor_gratings.m') and
% load it here.

%% parameters
% whether to save some debugging variables
debug_on = 0;

Screen('Preference', 'SkipSyncTests', 1);

% file with corridor
corridor_location = 'saved\virtual_corridor_mp_300_gratings_960x540_20241022.mat';
% mini-DAQ calibration (offset and scale)
calibration_file = 'calibration.mat';
% gamma correction
gamma_correction_file = 'gamma_table_mp_300.mat';

% photodiode box size in pixels
pd_box_size = 100;

% screen information
n_independent_screens = 2;
if n_independent_screens == 2
screen_number = [1, 3];
x_flip_on = [0, 1];
y_flip_on = [1, 1];
else
screen_number = 1;
x_flip_on = 0;
y_flip_on = 1;
end

% load mini-DAQ calibration
load(calibration_file, 'calibration');

% NI-DAQ info
nidaq_dev = 'Dev1';
ai_chan = 'ai0';
ai_offset = calibration.offset;
cm_per_s_per_volts = calibration.scale;
%ai_deadband = 0.005;
ai_deadband = 0.01;
di_chan = 'port0/line0';
max_speed = 100; % cm/s
di_chan_gain_on = 'port0/line1';


%% load parameters for the corridor
load(corridor_location, 'dot_mask', 'corridor_mask', ...
'position', 'screenXpixels', 'screenYpixels');
forward_limit = max(position);
back_limit = min(position);

% photodiode box
photodiode_position = [screenXpixels-pd_box_size, 0, screenXpixels, pd_box_size];

%% setup DAQ
ai = daq.createSession('ni');
ai.addAnalogInputChannel(nidaq_dev, ai_chan, 'Voltage');

di = daq.createSession('ni');
di.addDigitalChannel(nidaq_dev, di_chan, 'InputOnly');
di.addDigitalChannel(nidaq_dev, di_chan_gain_on, 'InputOnly');


%% startup psychotoolbox
PsychDefaultSetup(2);

% make sure screen is available
screens = Screen('Screens');
if ~ismember(screen_number, screens)
error('screen %i is not available', screen_number);
end

% load gamma correction
load(gamma_correction_file, 'gamma_table');

% open a window on chosen screen
[window, ~] = PsychImaging('OpenWindow', screen_number(1), 0);
if n_independent_screens == 2
[window2, ~] = PsychImaging('OpenWindow', screen_number(2), 1);
end

% make sure that the corridor was generated for this screen
% [xpix, ypix] = Screen('WindowSize', window);
% if xpix ~= screenXpixels || ypix ~= screenYPixels
% error('loaded corridor is not for this screen: %s', corridor_location);
% end

% for alpha blending (the corridor is an alpha mask)
Screen('BlendFunction', window, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');
if n_independent_screens == 2
Screen('BlendFunction', window2, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');
end

original_gamma = Screen('LoadNormalizedGammaTable', window, gamma_table, 0);
if n_independent_screens == 2
original_gamma2 = Screen('LoadNormalizedGammaTable', window2, gamma_table, 0);
end


%% pre-define the textures
% corridor mask
corridor_mask_transformed = transform_mask(corridor_mask, x_flip_on(1), y_flip_on(1));
corridor_texture = Screen('MakeTexture', window, corridor_mask_transformed);

if n_independent_screens == 2

corridor_mask_transformed = transform_mask(corridor_mask, x_flip_on(2), y_flip_on(2));
corridor_texture2 = Screen('MakeTexture', window2, corridor_mask_transformed);
end

% dot textures
dot_texture = [];
dot_texture2 = [];

for i = 1 : size(dot_mask, 3)

dot_mask_transformed = transform_mask(dot_mask(:, :, i), x_flip_on(1), y_flip_on(1));
dot_texture(i) = Screen('MakeTexture', window, dot_mask_transformed);

if n_independent_screens == 2

dot_mask_transformed = transform_mask(dot_mask(:, :, i), x_flip_on(2), y_flip_on(2));
dot_texture2(i) = Screen('MakeTexture', window2, dot_mask_transformed);
end
end


%% initialization
pos = 0;
last_tic = tic;

% if debugging store some extra information
if debug_on
iters = 10000;
store_time = nan(iters, 1);
count = 0;
initial_tic = tic;
end


%% start the loop
try
while 1

% poll the digital input
di_state = inputSingleScan(di);

if di_state(1) == 1
Screen('FillRect', window, 0);
Screen('Flip', window);
if n_independent_screens == 2
Screen('FillRect', window2, 0);
Screen('Flip', window2);
end
pos = 0;
continue
end

% poll analog input == velocity
ai_volts = inputSingleScan(ai);

% fprintf('%.7f', ai_volts);

% compute the updated position
ai_volts = (ai_volts - ai_offset);
if abs(ai_volts) > ai_deadband
speed = cm_per_s_per_volts * ai_volts * di_state(2);
pos = pos + speed * (toc(last_tic));
else
speed = 0;
end
last_tic = tic;


% set limits here
if pos >= forward_limit
pos = forward_limit;
idx = length(position);
elseif pos <= back_limit
pos = back_limit;
idx = 1;
else
[~, idx] = min(abs(position - pos));
end

% print out position if in debug
if debug_on
fprintf('%.2f cm\n', pos);
end

% draw the textures to screen
Screen('DrawTexture', window, dot_texture(idx));
Screen('DrawTexture', window, corridor_texture);
if n_independent_screens == 2
Screen('DrawTexture', window2, dot_texture2(idx));
Screen('DrawTexture', window2, corridor_texture2);
end

% photodiode box indicating speed
Screen('FillRect', window, speed/max_speed, photodiode_position);

% display updated image
Screen('Flip', window, [], [], 2);
if n_independent_screens == 2
Screen('Flip', window2, [], [], 2);
end

% if debugging
if debug_on
if count < iters
count = count + 1;
store_time(count) = toc(initial_tic);
end
end

% check for key-press from the user
[~, ~, keyCode] = KbCheck;
if keyCode(KbName('escape'))
if debug_on
assignin('base', 'store_time', store_time)
end
Screen('CloseAll');
sca;
error('escape');
end
end

catch ME

Screen('LoadNormalizedGammaTable', window, original_gamma, 0);
if n_independent_screens == 2
Screen('LoadNormalizedGammaTable', window2, original_gamma2, 0);
end

sca;

rethrow(ME);
end



function mask_transformed = transform_mask(mask, x_flip_on, y_flip_on)

mask_transformed = mask;

if x_flip_on
mask_transformed = mask_transformed(:, end:-1:1, :);
end

if y_flip_on
mask_transformed = mask_transformed(end:-1:1, :, :);
end

2 changes: 1 addition & 1 deletion corridor_mp_300/saved/create_virtual_corridor_mp_300.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
screenXpixels = 960;
screenYpixels = 540;

mouse_height = 2.5; % cm, height of mouse relative to bottom of screen
mouse_height = 2; % cm, height of mouse relative to bottom of screen
corridor_above_mouse = 5; % cm, height of corridor relative to mouse
corridor_below_mouse = -0.5; % cm, bottom of corridor relative to mouse

Expand Down
Loading

0 comments on commit 9fa8559

Please sign in to comment.