Commit 1223a27b authored by Jesse Heckman's avatar Jesse Heckman
Browse files

organized vPrime structure

parent 0c2bd26b
......@@ -22,7 +22,6 @@ function [stim, cfg] = pb_vSetupTrial(stim,cfg)
n = nled*2; % LEDs need to be turned on and off
s = ledpattern(n);
%%
cnt = 0;
for iLED = 1:nled
% TDT RZ6
......@@ -50,7 +49,7 @@ function [stim, cfg] = pb_vSetupTrial(stim,cfg)
cnt = cnt+1;
if ii==1
s(cnt).set(led(iLED).Z,cfg.ledcolours{col},1);
s(cnt).intensity(cfg.ledcolours{col},led(iLED).intensity); % hoop: range 0-255, sphere range 1-50
s(cnt).intensity(cfg.ledcolours{col},led(iLED).intensity); % Vestibular range 0-100;
else
s(cnt).set(led(iLED).Z,cfg.ledcolours{col},0);
end
......@@ -89,10 +88,10 @@ function [stim, cfg] = pb_vSetupTrial(stim,cfg)
cfg.maxSamples = maxSamples;
%% Wait for?
% This needs some tweaking
% search for latest event with longest offset
% which should also include sampling period and sound although this does not have an
% offevent
e = [stim.offevent];
d = [stim.offdelay];
mxevent = max(e);
......
......@@ -9,8 +9,6 @@ function signal = pb_vSafety(signal)
% PBToolbox (2018): JJH: j.heckman@donders.ru.nl
%% TODO: CONTROL SPEED OF EXPERIMENT (DIFF(SIGNAL))
vAx = {'Vertical','Horizontal'};
for iAx = 1:2
......@@ -19,9 +17,9 @@ function signal = pb_vSafety(signal)
warning(['Detected unsafe signal. ' vAx{iAx} ' duration too long!']);
signal(iAx).duration = 300;
end
if signal(iAx).amplitude > 40/iAx
if signal(iAx).amplitude > 100/iAx
warning(['Detected unsafe signal. ' vAx{iAx} ' amplitude too large!']);
signal(iAx).amplitude = 40/iAx;
signal(iAx).amplitude = 100/iAx;
end
if signal(iAx).frequency > .3
warning(['Detected unsafe signal. ' vAx{iAx} ' frequency too high!']);
......
......@@ -8,17 +8,23 @@ function [profile,dur] = pb_vSignalVC(handles)
% PBToolbox (2018): JJH: j.heckman@donders.ru.nl
%% INITIALIZE
% Selects relevant handles
block = handles.block;
bnumber = handles.cfg.blocknumber;
% Read & create signals
%% SIGNALS
% Creates safe vestibular signals.
% Read & create signals
signal = pb_vBuildSignal(block(bnumber).signal);
signal = pb_vSafety(signal);
vSignal = pb_vCreateSignal(1, signal(1).duration, 10, signal(1).frequency, signal(1).type);
hSignal = pb_vCreateSignal(1, signal(2).duration, 10, signal(2).frequency, signal(2).type);
% Finalize signals
% Finalize signals
sigData.v.x = vSignal.x .* signal(1).amplitude;
sigData.v.t = (0:1:length(sigData.v.x)-1)/10;
profile.v = sigData.v.x;
......@@ -27,7 +33,7 @@ function [profile,dur] = pb_vSignalVC(handles)
sigData.h.t = (0:1:length(sigData.h.x)-1)/10;
profile.h = sigData.h.x;
% Check signal safety
% Check signal safety
[hSafe,~] = pb_vCheckVelSignal(profile.h);
[vSafe,mvel] = pb_vCheckVelSignal(profile.v);
......@@ -35,19 +41,21 @@ function [profile,dur] = pb_vSignalVC(handles)
error(['Vestibular signals were not safe! (velocity exceeds ' num2str(mvel) ')']);
end
% Feedback GUI
%% FEEDBACK GUI
% interacts with GUI for feedback
updateBlock(handles, signal);
handles = pb_gethandles(handles);
dur = max([handles.block(bnumber).signal.ver.duration handles.block(bnumber).signal.hor.duration]);
% set axis
% Set axis
axes(handles.signals);
cla; hold on;
handles.signals.YLim = [-50 50];
handles.signals.XLim = [0 dur];
% plot signals
% Plot signals
dv = 10 * [0 diff(profile.v)];
dh = 10 * [0 diff(profile.h)];
t = sigData.v.t;
......
classdef pb_dataobj < handle
% PB_VCREATEDAT()
%
% PB_VCREATEDAT() ...
%
% See also ...
% PBToolbox (2018): JJH: j.heckman@donders.ru.nl
% LEDPATTERN
% Create a collection of stimulus patterns for the PA_LEDS
% class.
% s = ledpattern creates a single pattern
% s = ledpattern(n) creates a vector of n patterns
% s = ledpattern(m,n) creates a mxn matrix of patterns
%
% See also INTENSITY, SET, CLEAR, CLEAR_ALL, GET_LEDS, DELETE,
% DUMP.
properties (Access=protected)
intensity_red = uint16(50);
intensity_grn = uint16(50);
leds_red = zeros(128, 1);
leds_grn = zeros(128, 1);
end
methods
function obj = ledpattern(m,n)
% PA_LEDPATTERN constructor
if nargin ~= 0 % Allow nargin == 0 syntax
if nargin < 2
n = 1;
end
obj(m, n) = ledpattern; % Preallocate object array
end
end
function intensity(this, color, value)
% INTENSITY(color, value)
% Set the intensity of the red or green leds
% if color starts with 'r' the intensity of the red leds is set
% by manpulating the PWM output duty cycle. Otherwise the green
% intensity is set.
% The value should be in the range 1..50
if color(1) == 'r'
this.intensity_red = uint16(value);
else
this.intensity_grn = uint16(value);
end
end
function delete(obj) %#ok<INUSD>
% DELETE - destructor
end
function set(this, lednr, color, value)
% SET(lednr, color, value)
% Turn the led with color on output lednr on or off, depending
% on the value paramater. 0 is off, otherwise on. If not specified,
% value is assumed to be 1
%
% Note that LEDNRs start at 0!
if nargin < 4
value = 1;
end
if color(1) == 'r'
this.leds_red(lednr+1) = (value ~= 0);
else
this.leds_grn(lednr+1) = (value ~= 0);
end
end
function clear(this, lednr, color)
% CLEAR(lednr, color)
% Shorthand for SET(lednr, color, 0);
this.set(lednr, color, 0);
end
function clear_all(this)
% CLEAR_ALL
% Turn all leds off.
this.leds_red = zeros(128,1);
this.leds_grn = zeros(128,1);
end
function [r, g, ir, ig] = get_leds(this)
% [leds_red, leds_grn,intens_red, intens_grn] = GET_LEDS;
% Returns the value of the internal variables holding led
% values and intensities.
if nargout > 0
r=this.leds_red;
end
if nargout > 1
g=this.leds_grn;
end
if nargout > 2
ir=this.intensity_red;
end
if nargout > 3
ig=this.intensity_grn;
end
end
function dump(this)
% DUMP - show the content of the internal variables
this.intensity_red
this.intensity_grn
this.leds_red' %#ok<NOPRT>
this.leds_grn' %#ok<NOPRT>
end
end
end
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% %
% Part of Programmeer Beer Toolbox (PBToolbox) %
% Written by: Jesse J. Heckman (2018) %
% %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
function pb_vStoreBlockDat(cfg, Dat)
function pb_vStoreData(cfg, Dat)
% PB_VSTOREBLOCKDAT
%
% PB_VSTOREBLOCKDAT(cfg, Dat) stores 'Dat' Data in files.
......@@ -10,7 +10,6 @@ function pb_vStoreBlockDat(cfg, Dat)
[~,fn] = pb_fext(cfg.fname);
file = [cfg.dname filesep 'block_info_' fn '.mat'];
save(file, 'Dat');
end
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
......
......@@ -7,79 +7,36 @@ function pb_vEndExp
% PBToolbox (2018): JJH: j.heckman@donders.ru.nl
stim.X = 0;
stim.Y = 0;
stim.X = 0;
stim.Y = 0;
stim.channel = [];
stim.detect = [];
stim.event = [];
stim.intensity = 60;
stim.modality = 'sound';
stim.offdelay = 0;
stim.offevent = 0;
stim.ondelay = 0;
stim.onevent = 0;
stim.matfile = 'rehandel.mat';
stim.azimuth = 3.5084e-15;
stim.elevation = -3.5084e-15;
stim.Z = 10;
stim.ledhandle = [];
stim.detect = [];
stim.event = [];
stim.intensity = 60;
stim.modality = 'sound';
stim.offdelay = 0;
stim.offevent = 0;
stim.ondelay = 0;
stim.onevent = 0;
stim.matfile = 'rehandel.mat';
stim.azimuth = 3.5084e-15;
stim.elevation = -3.5084e-15;
stim.Z = 10;
stim.ledhandle = [];
stim.parameters = 99;
% fname = fullfile('C:\DATA\SND',stim.matfile);
% if ~exist(fname)
% disp('You do not have Handel installed.');
% disp('1000 monkeys are doing your work for you, and are now writing Handel.');
% load handel;
% snd = resample(y,round(cfg.RZ6Fs),Fs); %#ok<NASGU>
% nsamples = numel(snd);
% dur = round( nsamples/cfg.RZ6Fs*1000);
% stim.duration = dur;
% save(fname,'snd');
% end
% disp('Hallelujah');
% warning('cannot load into RZ6 circuit as it cannot handle .mat files');
% stim = trialSetupMinor(cfg,stim);
% trialRunMinor(cfg,stim);
%% Let's run some LEDs instead
import org.zeromq.ZMQ
n = 8;
s = ledpattern(n);
seq1 = [0:2:9 fliplr(16:2:24)];
seq2 = [1:2:9 fliplr(17:2:24)];
ir=50;
ig=ir;
for i=1:n
if mod(i,2) == 0
s(i).set(seq1,'r');
else
s(i).set(seq2,'g');
end
s(i).intensity('r', ir);
s(i).intensity('g', ig);
end
leds = ledcontroller_pi('dcn-led06','dcn-led07');
leds.write(s);
for i=1:n
leds.trigger;
pause(0.35);
end
pb_lightshow;
%% Mop up
% Turn off the lights
t=ledpattern;
t = ledpattern;
leds.write(t);
leds.trigger;
delete(leds);
delete(s);
delete(t);
delete([leds,t]);
end
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
......
......@@ -82,10 +82,7 @@ function [block,cfg] = pb_vReadExp(cfg)
block(bn).trial(tn).stim(sn).modality = 'LED';
block(bn).trial(tn).stim(sn).X = par(1);
block(bn).trial(tn).stim(sn).Y = par(2);
block(bn).trial(tn).stim(sn).intensity = par(3);
block(bn).trial(tn).stim(sn).intensity = par(3); % hoop: range 0-255, sphere range 1-50
block(bn).trial(tn).stim(sn).intensity = par(3); % vestibular 0-100
block(bn).trial(tn).stim(sn).onevent = par(4);
block(bn).trial(tn).stim(sn).ondelay = par(5);
......
......@@ -74,8 +74,8 @@ function pb_vRunExp(handles)
pb_vTraces(handles);
% save trial
handles = pb_vStoreData(handles, profile);
handles.cfg = pb_updatecount(handles.cfg,'trial','count');
handles = pb_vStoreData(handles, profile);
handles.cfg = pb_updatecount(handles.cfg,'trial','count');
toc(trialTime);
end
......@@ -112,6 +112,8 @@ function pb_vRunExp(handles)
pb_vEndExp;
pb_vStoreBlockDat(handles.cfg, Dat);
pb_vInitialize(handles, false);
delete([ses, rc, str]);
toc(expTime);
end
......
function Dat = pb_vRunVC(signal)
% PB_VRUNVC()
%
% PB_VRUNVC() ...
%
% See also ...
% PBToolbox (2018): JJH: j.heckman@donders.ru.nl
%% CREATE SIGNALS
vSignal = pb_vCreateSignal(1, signal(1).duration, 10, .1, signal(1).type);
hSignal = pb_vCreateSignal(1, signal(2).duration, 10, .1, signal(2).type);
Dat.v.x = vSignal.x .* signal(1).amplitude;
Dat.v.t = (0:1:length(Dat.v.x)-1)/10;
Dat.h.x = hSignal.x .* signal(2).amplitude;
Dat.h.t = (0:1:length(Dat.h.x)-1)/10;
%% RUN CHAIR
profile.v = Dat.v.x;
profile.h = Dat.h.x;
%% excecute profile
dur = max([signal(1).duration signal(2).duration]);
send_profile(profile);
run_profile(dur);
%[sv,pv] = read_profile;
%% save data
Dat.signal = [1 1];
Dat.amplitude = [signal(1).amplitude signal(2).amplitude];
%Dat.sv = sv;
%Dat.pv = pv;
end
function send_profile(profile)
disp('writing profile to servo');
%vs = vs_servo;
%vs.write_profile(profile.v,profile.h);
%delete(vs);
end
function [sv,pv]=read_profile
%vs=vs_servo;
%[sv.vertical,sv.horizontal] = vs.read_profile_sv;
%[pv.vertical,pv.horizontal] = vs.read_profile_pv;
%delete(vs);
end
function run_profile(dur)
%vs=vs_servo;
%vs.enable;
%pause(1);
%vs.start;
%disp('started');
%pause(dur+5);
%vs.stop;
%disp('stopped');
%vs.disable;
%disp('done');
%delete(vs);
end
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% %
% Part of Programmeer Beer Toolbox (PBToolbox) %
% Written by: Jesse J. Heckman (2018) %
% %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment