4 自作のプログラムを動かそう。

以下のプログラムは、最も基本となるプログラムです。内容をよく理解して、実験プログラムを作る際の参考にしてください。

このプログラムでは、画面の中央に円を1つ呈示します。いずれかのキーを押すと、その情報をコマンドウィンドウに表示します。ESCキーを押すとプログラムを終了します。

Matlabで動かすには

  1. Mファイルを新規作成して下のプログラムをコピーして貼り付けます。
  2. ファイルを保存します。
  3. 実行ボタン(もしくはデバッグ → 実行)を押すとプログラムが動き始めます。
  4. ディレクトリ(フォルダ)の変更を促されたときは、その指示に従います。

Octave(Win)で動かすには

注意)PTB 3.0.10よりWindows版のOctaveはサポートしなくなったようです。

  1. テキストエディター(私のお勧めはTeraPadです)でMファイル(拡張子を .m にしてください)を作成し、下のプログラムをコピーして貼り付けます。
  2. Octaveを立ち上げて、cd コマンドを使ってファイルを保存しているディレクトリ(フォルダ)に移動します。(例 cd 'c:\Users\test\myprogram')シングルクオーテーションで囲むとパスに日本語が含まれていても大丈夫なようです。
  3. プログラム名(ファイル名)を入力してエンターキーを押します。

Octave (Mac) で動かすには

  1. Macに標準でインストールされているテキストエディットを使ってMファイルを作成します。(ほかのエディターでもかまいません。例えばCotEditor)テキストエディットのデフォルトの設定ではリッチテキスト形式になりますので、環境設定から標準テキスト形式に変更してファイルを新規作成します。下のプログラムをコピーして貼り付けし、拡張子を .m として保存します。
  2. Octaveを立ち上げて、cd コマンドを使ってファイルを保存しているディレクトリ(フォルダ)に移動します。(例 cd ~/Documents/myprogram)パスに日本語が含まれていても大丈夫なようです。
  3. プログラム名(ファイル名)を入力してエンターキーを押します。

function ovalkey
ListenChar(2); % キー入力がmatlabをジャマしないように。
AssertOpenGL; % OpenGLが使えるかどうかのチェック。
KbName('UnifyKeyNames'); % OSで共通のキー配置にする。
% プログラムが動かない場合はmyKeyCheckを使ってみてください。
%myKeyCheck;
% あらかじめ読み込んでおく必要がある関数たち
GetSecs;
WaitSecs(0.1);
rand('state', sum(100*clock));
% 背景色
bgColor = [128 128 128];
% 円の色
ovalColor = [255 0 0];
% 円の半径
radius = 20;
try
  % 必要に応じてカーソルを消してください
  %HideCursor;
  
  screenNumber = max(Screen('Screens'));
  % ウィンドウでの呈示(デバッグ用)
  %[windowPtr, windowRect] = Screen('OpenWindow', screenNumber, bgColor, [100, 200, 700, 600]);
  % フルスクリーンでの呈示
  [windowPtr, windowRect] = Screen('OpenWindow', screenNumber, bgColor);
    
  % 画面の中央の座標
  [centerX centerY] = RectCenter(windowRect);
     
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % 円の描画
  Screen('FillOval', windowPtr, ovalColor, [centerX - radius, centerY - radius, centerX + radius, centerY + radius]);
  Screen('Flip', windowPtr); % 画面に呈示
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % ESCキーを押すまでは円を呈示したまま
  % ESCキー以外を押すと、押されたキーの情報をコマンドウィンドウに表示します。
  escapeKey = KbName('ESCAPE');
  while KbCheck; end % いずれのキーも押されていないことをチェック。
   
  while 1
      [ keyIsDown, seconds, keyCode ] = KbCheck;
      if keyIsDown
    
          % キー情報はコマンドウィンドウに表示されます。
          fprintf('キー情報: %i %s \n', find(keyCode), KbName(keyCode));
     
          if keyCode(escapeKey)
              break; % while 文を抜けます。
          end;
  
          % いずれのキーも押されていないことをチェック。
          while KbCheck; end;
      end;
  end
  
  %終了処理
  Screen('CloseAll');
  ShowCursor;
  ListenChar(0);
  
catch % 正常に終了した場合は、catch以下は実行されません。
  Screen('CloseAll');
  ShowCursor;
  ListenChar(0);
  psychrethrow(psychlasterror);
end

上記プログラムを上の行から順に説明

  • functionの名前はovalkey。ファイル名と一致していればどんな名前でもかまわない(ただし、ハイフンを含むのはダメ。日本語もダメ)。
  • help ListenCharを参照。ListenCharを設定しない状態でキーボードを押すと、Matlabのエディタやコマンドウィンドウにその文字が入力されてしまう。それを防ぐためにプログラムの頭でListenChar(2)を呼ぶ。プログラムを終了するときに、ListenChar(0)を呼び出して元の状態に戻す。注意点として、ListenChar(2)を呼び出していると、ブレークポイントを使ったデバッグ中にキーボードの入力が効かなくなる。そのときはCtrl+Cを押せばよい。
  • help AssertOpenGLを参照。PTBがOpenGLをベースとしていなかったり、Screen関数が適切に動かなかったときに、プログラムを中止してエラーを出力する。
  • キーボード入力で紹介した自作の関数 "myKeyCheck" を呼び出している。プログラムが正しく動作しないときに試してみてください。
  • help GetSecs を見てもらうと分かりますが、プログラム外のMEX関数(またはMファイル)は前もって呼び出しておくことによって、読み込みにかかる時間を抑えることができます。
  • rand('state', sum(100*clock)); をしてランダム関数を初期化しています。一般的な実験プログラムでは条件をランダムに配置したりするので、基本的には必ず呼び出しておく必要がある。
  • 背景色などはコマンドの引数(引数とは括弧の中の値)で指定してもよいが、プログラム内で何度も使う情報は変数(定数)として設定しておくと便利。

  • try・・・catch・・・endを一組として覚えましょう。tryからcatchの間で何かしらのエラーが生じると、その後の処理を止めてcatchからendの間に書かれていることを実行する。つまり、どんなエラーが生じても必ずやってほしいことをcatchからendの間に書いておくこと。注意点として、tryからcatchの間でエラーが生じなければ、catchからendの間に書かれていることはしない。
  • HideCursorは文字通り。カーソルが邪魔であれば呼び出すこと。ShowCursorで元に戻すのを忘れずに。
  • screenNumber=max(Screen('Screens'));は複数台のディスプレイを使っているときに重要になる。ディスプレイが1台であればあまり気にする必要はない。screenNumberという変数に、PTBがどのディスプレイを使用するのかという情報が代入される。
  • Screen関数は第1引数によってその働きが変わってくる。ここでは第1引数がOpenWindowで、刺激を呈示するウィンドウを開くということ。第2引数は前述のscreenNumber。第3引数は背景色。第4引数はウィンドウのサイズで、省略するとフルスクリーン表示になる。フルスクリーンのときはブレークポイントを使ったデバッグができないので、デバッグをしたいときは必ず第4引数を指定すること。
  • Screen('Preference', 'SkipSyncTests', 1); はデバッグ用です。フルスクリーンではなく、ウィンドウで表示させたいときに有効にしてください。ただし、これを有効にした状態は望ましくないので実験に用いるプログラムでは使用しないようにしてください。

  • centerX は画面の中心のX座標、centerY は画面の中心のy座標。
  • FillOvalは円を描くということ。windowPtr で描画するウィンドウを指定している。ovalColor は [255, 0, 0] で、赤色という意味。画面の中心座標を中心に、半径radiusの円を描画している。
  • Screen('Flip', windowPtr); で円を画面に表示。前の行のScreen('FillOval')の段階ではまだ画面に表示はされていない。Screen('Flip')を参照のこと。

  • while KbCheck; end いずれかのキーが押されているとkbCheckが「真(1)」の値を返すため、下の行に進まない。
  • while 1 ・・・endというのは、無限ループでwhileとendのあいだのことをずっと繰り返し行う。それだけだとプログラムが終わらないので、エスケープキーが押されたときにbreakコマンドを呼び出して、強制的に無限ループを止める。
  • [ keyIsDown, seconds, keyCode ] = KbCheck; でキーボードの情報を取得している。いずれかのキーが押されていると keyIsDownが1になる。seconds はキーを押したときの時間、keyCodeはどのキーを押したかの情報。[ ]の中の変数の名前は自由に決めることができます。KbCheck, KbWaitを参照のこと。
  • fprintfでキーボードの入力情報(キーに割り当てられた番号と、キーの名前)をコマンドウィンドウに表示させています。円の描画という観点からは意味のないコマンドです。キー入力についての理解を深めるために、キー情報を出力させているだけです。
  • psychrethrow(psychlasterror); を catch・・・end の中の一番最後に記載してください。これを書いておくと、プログラムに文法上のミスがあった場合などに、どこに誤りがあるのかをコマンドウィンドウに表示してくれます。非常に便利です。
  %Screen('Preference', 'SkipSyncTests', 1);