Matlab Psychtoolbox fprintf ошибка с несколькими нажатиями клавиш в течение испытания - PullRequest
0 голосов
/ 13 марта 2019

У меня есть эксперимент, который собирает нажатия клавиш ('x' или 'n') и время реакции в ответ на отображение стимула. Если участник нажимает любую кнопку один раз за испытание, эксперимент проходит нормально. Однако, если они нажимают на клавиатуру несколько раз или удерживают нажатой клавишу, это часто приводит к сбою. (Я работаю с детьми, и даже если мы попросим их не делать этого, это часто случается).

Ошибка, которая возникает при сбое:

Функция не определена для входов 'cell'.

Ошибка в эксперименте (строка 682)

fprintf (dataFile, formatString, SJNB, Дата, Возраст, блок, пробная версия, trialFaceLabel, trialLoadLabel, Target, keyStroke, tStart, keyTime, Correct, RT, FaceGen);

Хотя и написано «Функция не определена для входов« ячейки »(что связано с этой публикацией), эта функция, кажется, работает должным образом в любое другое время, поэтому я не вижу что это просто не определено правильно. Только тогда, когда слишком много нажатий клавиш были нажаты подряд (например, если клавиша была нажата), возникает эта ошибка.

Какие изменения я могу внести, чтобы эксперимент был надежным и не зависал, даже если на пробу приходится несколько нажатий клавиш? Любая помощь будет оценена.

Я включил код ниже.

Вот некоторая дополнительная информация, если это полезно:

  • До экспериментального испытания есть тренировочный цикл, который настроен почти так же, но с двумя основными отличиями: 1) стимулы, отображаемые на экране, отличаются и 2) нажатия клавиш не записываются , Этот цикл, кажется, никогда не падает.

  • После сбоя ответы нажатия клавиш выводятся в командную строку.

  • Я просматривал другие подобные посты, например, этот пост, но, насколько я понимаю, цикл нажатия клавиш, который я написал, должен также завершиться, как только будет нажата клавиша - поэтому я не уверен, почему мой не работает в том же самом путь.

Приведенный ниже код включен в экспериментальный цикл. Что он делает: 1) в поисках нажатия клавиш 2) вычисление времени отклика на основе нажатия клавиши 3) звуковой сигнал, если ответ был неверным 4) печать в файл (это незадолго до окончания пробного периода) (это строка, на которую ссылается ошибка)

            %searching for keypress
            timedout = false;
            pressed = 0;
            %while pressed < 1;

            while ~timedout && ~pressed

                [keyIsDown, keyTime, keyCode] = KbCheck;

                if keyIsDown && ((keyTime-tStart) < max_stimulus_shown)
                    keyStroke = KbName(keyCode);
                    if any(strcmpi(keyStroke,leftKey)) || any(strcmpi(keyStroke,rightKey)) %|| any(strcmpi(keyStroke,exitKey))
                        pressed = 1;
                        WaitSecs(remainer-(keyTime-stimulus_shown));
                        break;
                    elseif any(strcmpi(keyStroke,exitKey))
                    disp('*** Experiment terminated ***');
                        break;
                        sca;
                    end
                elseif ((keyTime-tStart) > max_stimulus_shown)
                keyStroke = 'None';
                timedout = true;
                RT = 0;
                Correct = 0;
                pressed = 2; % 2 = not pressed
                KbQueueStop(); 
                end
            end 

            %calculate response times
            if pressed == 1 && (~timedout)
            RT = round((keyTime-tStart)*1000); % RT in ms
            if any(strcmpi(keyStroke,leftKey)) % pressed left (X)
                if any(strcmpi(Target, 'X')) % target was an X
                    Correct = 1;
                else % target was X, but pressed right (N)
                    Correct = 0;
                end
            elseif any(strcmpi(keyStroke,rightKey)) % they pressed right 
                if any(strcmpi(Target, 'N')) % target was an N
                    Correct = 1;
                else % target was N, but pressed right
                    Correct = 0;
                end
            elseif any(strcmpi(keyStroke,exitKey))
                disp('ESC');
                break;
            end
            end

            Screen('TextSize',Screen_wid, star_size);
            DrawFormattedText(Screen_wid, '.', 'center', 'center');
            WaitSecs(feedback);
            Screen('Flip', Screen_wid);

            %say when to beep                
            if Correct == 0 && ~timedout
            PsychPortAudio('Start', pahandle, repetitions, startCue, waitForDeviceStart);
            WaitSecs(remainer-beepLengthSecs);
            elseif Correct == 0 && timedout
            PsychPortAudio('Start', pahandle, repetitions, startCue, waitForDeviceStart);
            Screen('TextSize',Screen_wid, text_size);
            DrawFormattedText(Screen_wid, 'missed trial', 'center', 'center');
            Screen('Flip', Screen_wid);
            WaitSecs(beepLengthSecs+feedback);
            elseif Correct == 1
            WaitSecs(remainer+beepLengthSecs);
            end

            %WaitSecs(stimulus_shown); %stimulus shown for 0.2 seconds
            Screen('Flip', Screen_wid);

            dataFile = fopen(dataFileName, 'a');                               
            fprintf(dataFile, formatString, SJNB, Date, Age, block, trial, trialFaceLabel, trialLoadLabel, Target, keyStroke, tStart, keyTime, Correct, RT, FaceGen);
            fclose(dataFile);   

1 Ответ

0 голосов
/ 14 марта 2019

Функция KbName возвращает строку имени введенного ключа (ключей) через вектор кодов клавиш (key_name = KbName([21 22])) или логический вектор, возвращаемый KbCheck.

Если указан только ключ / True, он возвращается в виде строки. Но если одновременно нажимается более одной клавиши, она возвращается в виде массива ячеек строк.

Например, посмотрите на вывод:

% for key name consistency across operating systems
KbName('UnifyKeyNames')

% one key
KbName(21)

ans =

r

% more than one key
KbName([21 22])

ans =

  1×2 cell array

    'r'    's'

Ваша проблема в том, что когда одновременно нажимается более одной клавиши (относительно цикла проверки клавиш), keyStroke - это массив ячеек, содержащий клавиши, которые были нажаты. Похоже, вы обрабатываете массив ячеек надлежащим образом в большей части своего кода, за исключением вызова fprintf, который ожидает одну строку, а не массив ячеек строк.

Если вы хотите сохранить запись всех нажатых клавиш, вы можете преобразовать массив ячеек строк в одну строку с разделителем между элементами, например, добавив следующую строку перед вызовом fprintf:

if iscell(keyStroke)
    keyStroke = strjoin(keyStroke, '_');
end

Но также имейте в виду, что вы можете изменить логику своего эксперимента, чтобы отклонить испытания, в которых были нажаты две клавиши, или иначе обработать их по-другому, чем отклики с одной клавишей. В настоящее время у вас есть клавиша «влево», имеющая приоритет, другими словами, если у участника нажата левая клавиша, а целью является «X», пробная версия будет помечена как правильная, даже если также будет нажата правая клавиша. И наоборот, если у участника нажата левая клавиша, а целью является «N», пробная версия будет помечена как неправильная, даже если также нажата правая клавиша.

...