2 キーボード入力

PTBのサンプルプログラム(デモ)を動かしたとき、何も画面に表示されなかったり、フリーズしてMatlabを強制終了しなくてはならないことがあります。(主にwindowsで)

この原因の多くは、キーボード入力の誤作動です。

キーボード入力の誤作動が生じているかを簡単に確認する方法があります。

もし、DriftDemo が正しく動くのに他のデモが動作しない場合は、キーボード入力の誤作動が生じていると判断してよいです。(なぜならDrittDemo はキーボードからの入力を待って動作を終了するデモではなく、一定時間が経過したら自動的に終了するデモなので)

PTBに付属しているデモには、実行をすると何かを呈示して、あるキーを押すと終了するタイプがあります。キーボードからの入力を正しく検知できないと、これらのデモは適切に動作しません。

以上の不具合を防ぐために次のような関数を作ってみました。

function myKeyCheck
% OSで共通のキー配置にする
KbName('UnifyKeyNames');
% いずれのキーも押されていない状態にするため1秒ほど待つ
tic;
while toc < 1; end;
% 無効にするキーの初期化
DisableKeysForKbCheck([]);
% 常に押されるキー情報を取得する
[ keyIsDown, secs, keyCode ] = KbCheck;
% 常に押されている(と誤検知されている)キーがあったら、それを無効にする
if keyIsDown
    fprintf('無効にしたキーがあります\n');
    keys=find(keyCode) % keyCodeの表示
    KbName(keys) % キーの名前を表示
    DisableKeysForKbCheck(keys);
end

上記のプログラムをmyKeyCheck.mという名前で保存したら、その保存先フォルダをMatlabのパス設定に加えるか、実行したい自作のプログラムと同じフォルダに保存してください。そうすることで上記のプログラムをmyKeyCheckという名前の関数として呼び出すことができるようになります。基本的にはどのプログラムにおいても冒頭でmyKeyCheckを呼び出すとよいでしょう(ただし、clear all などをする場合にはその後で呼び出す必要があります)。

補足

KbCheckで現在のキーボードの状況(押されているか押されていないか)を調べることができます。

KbCheck の戻り値のひとつである keyCodeには、256のキー配列において押されているキーについては1が、押されていないキーについては0が保存されています。私の環境では、どのキーも押していないのに配列番号243とか244が1になりました。

find関数で keyCode の非零要素(つまりPTBで押されていると誤認識されているキー)を抽出し、DisableKeysForKbCheck に渡すことで不具合を解消できます。詳しくは

help DisableKeysForKbCheck

をご覧ください。

RestrictKeysForKbCheck

を使う方法もあります。

KbName('UnifyKeyNames');

これをしないと本サイトで公開しているサンプルプログラムが動かなかったり、あるパソコンでは正しく動作するプログラムが、他のパソコンでは動作しなかったりします。

Matlabのコマンドウィンドウで

KbName('KeyNames')

を実行してみてください。256種類のキーの名前が表示されると思います。ここで表示されるキーの名前はパソコンによって若干異なることがあるようです。

例えば私の環境ですとKbName('UnifyKeyNames');をする前は、エスケープキーが"esc"となっていましたが、KbName('UnifyKeyNames');をした後は"ESCAPE"となりました。

KbName('UnifyKeyNames');の設定は clearall を呼び出すとリセットされるので注意してください。