2010-12-10 4 views
7

Ich verwende Psychtoolbox in MATLAB, um ein verhaltenspsychologisches Paradigma zu betreiben. Als Teil des Paradigmas müssen Benutzer einen visuellen Reiz sehen und darauf mit einem Eingabemechanismus reagieren. Für eine Tastatur funktioniert dies wie folgt:Wie kann ich Eingabe und Anzeige in MATLAB parallelisieren?

  1. zeigen Stimulus
  2. Umfrage Tastatur für die Antwort
    1. wenn keine Antwort erkannt, Schleife zurück auf 1
    2. wenn Antwort erkannt wird, brechen und mit Skript weitergehen

Dies funktioniert für eine Tastatur in Ordnung, wie in Schritt 2 zwischen 1-2 ms dauert. Das Problem tritt auf, wenn ich einen alternativen Eingabemechanismus verwende; In diesem Fall dauert Schritt 2 ~ 20 ms. (Ich brauche diese alternative Eingabe, um die Studie auszuführen, und das sollte als unveränderliche Tatsache betrachtet werden.) Da sich der Stimulus mit einer sehr kurzen Zeitspanne ändert, unterbricht diese zusätzliche Verzögerung die Aufgabe.

Mein aktueller Gedanke ist zu versuchen, die parallele Verarbeitung zu verwenden, so dass ein Thread den Stimulus anzeigt und ein anderer Thread die Tastatur abfragt. Ich verwende derzeit die Parallel Computing Toolbox, um dies zu tun. Das Problem, das ich habe, ist, dass ich nicht weiß, wie man Tastatureingabe zu einem "parallelisierten" Thread leitet. Weiß jemand (1), ob es möglich ist, Tastatureingaben zu einem Thread zu leiten/ein Thread zu haben, senden Sie ein visuelles Signal an einen Monitor, und wenn ja, (2) wie geht das?

Auch wenn jemand bessere Ideen hat, wie man dieses Problem angehen kann, bin ich ganz Ohr.

+0

Ich bin ein wenig verwirrt. Möchten Sie einen Stimulus anzeigen, eine voreingestellte Zeitspanne für eine Antwort des Benutzers warten und dann einen anderen Stimulus anzeigen, in dem sie nicht geantwortet haben (oder die Schleife unterbrechen, wenn sie vorhanden sind)? Wie genau "bricht" die Verzögerung die Aufgabe? – gnovice

+0

@gnovice - Nein, ich möchte einen Stimulus zeigen (und ständig aktualisieren) und nur aufhören, ihn zu zeigen (zu aktualisieren), wenn eine Antwort gegeben wird. Wie die Verzögerung bricht, ist ziemlich detailliert, aber es genügt zu sagen, dass der Bildschirm in der Größenordnung von 5-8 ms aktualisiert werden muss und die zusätzliche Verzögerung von 20 ms zu lang ist. – eykanal

+0

Also, ich denke, Sie haben einen animierten Stimulus, wenn Sie es kontinuierlich aktualisieren müssen, aber alle 5-8 ms wäre eine Bildrate von 125-200 Hz. Muss es wirklich so schnell sein? Eine typische Bildrate von 60 Hz ist normalerweise gut genug, um ein Flackern zu vermeiden. – gnovice

Antwort

4

Nach this MATLAB newsgroup thread scheint es, dass Threads Grafikobjekte nicht ändern können. Nur der Desktop-MATLAB-Client kann das tun. Dies bedeutet, dass Sie nicht mit der Aktualisierung von Grafiken aus einem Thread umgehen können, und ich kann dies bestätigen, als ich es versuchte und war nicht in der Lage, Zahlen oder sogar die root object von einem Thread zu ändern.

Ich denke jedoch, dass Sie möglicherweise die wichtigsten Grafiken in MATLAB aktualisieren können, während ein Thread Abfragen für Ihre Eingabe behandelt. Hier ist eine Beispielfunktion zur kontinuierlichen Herstellung einer Anzeige aktualisiert, bis ein Thread für die Eingabe warten, von KbCheck läuft beendet:

function varargout = plot_until_input 

    obj = createJob();         %# Create a job 
    task = createTask(obj,@get_input,4,{deviceNumber}); %# Create a task 
    submit(obj);           %# Submit the job 
    waitForState(task,'running'); %# Wait for the task to start running 

    %# Initialize your stimulus display here 
    while ~strcmp(get(task,'State'),'finished') %# Loop while the task is running 
    %# Update your stimulus display here 
    end 

    varargout = get(task,'OutputArguments'); %# Get the outputs from the task 
    destroy(obj);        %# Remove the job from memory 

%#---Nested functions below--- 

    function [keyIsDown,secs,keyCode,deltaSecs] = get_input(deviceNumber) 
    keyIsDown = false; 
    while ~keyIsDown %# Keep looping until a key is pressed 
     [keyIsDown,secs,keyCode,deltaSecs] = KbCheck(deviceNumber); 
    end 
    end 

end 

konnte ich erfolgreich die obige Funktion mit einigen einfachen Plot-Routinen ausführen und den Code in get_input mit einem Ersatz einfache pause Anweisung und ein Rückgabewert. Ich bin mir nicht sicher, ob KbCheck in einem Thread funktioniert, aber hoffentlich werden Sie in der Lage sein, dies für Ihre Bedürfnisse anzupassen.

Hier ist die Dokumentation für die Parallel Computing Toolbox-Funktionen in dem obigen Code verwendet: createJob, createTask, submit, waitForState, destroy.

+1

Ich benutze eine Toolbox namens [PsychToolbox] (http://psychotoolbox.org/), sie haben eine ziemlich anspruchsvolle Funktion 'KbCheck', die Mex-Funktionen für diese Art von Sache verwendet. Außerdem haben sie ihre eigenen Screen-Draw-Funktionen und verwenden nicht die eingebauten Plot-Funktionen (zumindest nicht direkt). Trotzdem danke. – eykanal

+0

+1: Ich lerne hier immer etwas Neues. – Jonas

+0

Ich weiß nicht warum der Downvote, aber ein +1 von mir für die nette Idee. Ich war mir der verschiedenen "wateforstate" Optionen nicht bewusst. Ich werde es versuchen, wenn ich am Montag wieder zur Arbeit komme und mehr Feedback gebe. Vielen Dank! – eykanal

2

Ich weiß nicht, wie Sie dies mit der parallelen Verarbeitung tun können.

Eine Funktion, die Sie möglicherweise verwenden können, ist jedoch die timer object. Sie würden das Timer-Objekt einrichten, um den Eingabemechanismus abzufragen, und wenn etwas entdeckt wird, ändern Sie den Wert einer globalen Variablen. Dann starten Sie Ihre Reizroutine. In der While-Schleife, in der Sie die Anzeige aktualisieren, überprüfen Sie die globale Variable für eine Änderung anhand des Timer-Objekts.

+0

In meinem Fall muss ich jedoch ständig den Stimulus WHILE polling den Eingabemechanismus aktualisieren. Wenn ich etwas nicht vermisse, erlaubt dieser Ansatz keine kontinuierliche Stimulusaktualisierung aufgrund des uiwait-Anrufs. – eykanal

+0

@eykanal: Jetzt verstehe ich. Ja, das würde mit figures/uiwait nicht funktionieren, aber wenn das Timer-Objekt den Wert einer globalen Variable ändert, könnte es funktionieren. Man müsste testen, ob es schnell genug war. – Jonas

-2

Sie müssen die 20ms Latenz in Ihrem Eingabegerät angehen. Wenn es zu langsam ist, holen Sie sich ein anderes Eingabegerät. Mit geeigneten Antwortfeldern können Sie ein gutes Timing im Unter-Millisekunden-Bereich erreichen.

All diese Diskussion über Threading ist fehlgeleitet und nicht auf das PTB-Framework anwendbar.

+2

"Holen Sie ein anderes Eingabegerät" ist fast immer eine schlechte Antwort, so oft (einschließlich in meinem Fall) sind Sie auf eine bestimmte Art von Eingabegerät beschränkt. Es passiert, dass die Threading-Lösung funktioniert hat, so dass sie definitiv auf das PTB-Framework anwendbar ist. – eykanal

+0

okay, was auch immer funktioniert. – towolf

Verwandte Themen