PsychoPyと外部プログラムの連携
ここでは,下記のようなシンプルな実験プロジェクトに外部プログラムで測定した測定結果をUDPで送り込み保存してみる。プロジェクトは,Fixation(+)の後にTarget(□)が出るので,スペースキーを押すと,反応時間が記録されるというもの。
BuilderのPythonマーク(青と黄のヘビ)をクリックすると,Coderが起動する。ここでコードを改造すると,UnityやProcessingからのデータを受け取ることができる。ただし,Builderでコードを生成すると,改造部分はすべて消し飛ぶので注意が必要だ。
まず冒頭で,ライブラリを呼んで,グローバル変数とUDPでデータを受け取るサブルーチンを用意する。
############# NAGANO #################
import socket
import threading
# UDPソケット設定
UDP_IP = "127.0.0.1" # 受信するIPアドレス
UDP_PORT = 5005 # ポート番号
# グローバル変数に最新のUDPデータを格納
latest_udp_data = "No Data"
def udp_listener():
"""非同期でUDPデータを受信する関数"""
global latest_udp_data
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # 1024バイトまで受信
latest_udp_data = data.decode("utf-8") # デコードして文字列に
############# NAGANO #################
次にプログラム開始部分でスレッドをスタートする。
win = setupWindow(expInfo=expInfo)
setupDevices(expInfo=expInfo, thisExp=thisExp, win=win)
############# NAGANO #################
# UDPリスナーをスレッドで起動
udp_thread = threading.Thread(target=udp_listener, daemon=True)
udp_thread.start()
############# NAGANO #################
でさらに,UDPでうけとったデータを保存する。データの受取は,別スレッドが非同期で行ってくれる。
key_resp_target.duration = _key_resp_target_allKeys[-1].duration
############# NAGANO #################
# UDPデータをログに記録
thisExp.addData('UDP_Data', latest_udp_data)
thisExp.addData('KeyPress_Time', globalClock.getTime()) # キー押下時刻も記録
############# NAGANO #################
# a response ends the routine
continueRoutine = False
実行すると,以下のような感じでUDP経由で送られたデータが保存される。ちなみに,データ送信側は,ローカルホストの5005ポートにProcessingでCerry,Diamond,Sevenのどれかひとつの文字列を送るもの。もう一度いうが,Builderで更新するとこれらの改造部分は消し飛ぶので注意!