Newer
Older
BrainWave-Task-Visualizer / run.py
  1. import sys, random
  2. import os
  3. import pygame
  4. import time
  5. from pygame.locals import *
  6. import nouha_recv as bwr
  7. from socket import socket, AF_INET, SOCK_DGRAM
  8.  
  9. import TaskManager
  10.  
  11. #”重要” offLineModeをFalseにすると脳波データの通信が行われるため、UDP通信が起動していない場合にFalseにするとバグ発生の可能性あり
  12. offLineMode = True
  13. WIDTH = 3200 #ウィンドウの横サイズ
  14. HEIGHT = 1800 #ウィンドウの縦サイズ
  15. TIME = 30000 #タスクの継続時間(ミリ秒)
  16. BREAK_TIME = 15000 #タスク間の休憩時間(ミリ秒)
  17. PREP_TIME = 10000 #各タスクの「慣れ」時間(ミリ秒)
  18. TASK_COUNT = 10 #右、左、ニュートラルそれぞれのタスク数(デフォルトの場合それぞれ5回ずつタスクを実施)
  19. #UDPの準備
  20. HOST = ''
  21. PORT = 8001
  22. #サウンドファイルの指定
  23. SOUND_DIR = "sounds"
  24. BLINK_INTERVAL = 1000
  25. white = (255, 255, 255)
  26. black = (0, 0, 0)
  27. screen_type = ["sound", "screen", "task"]
  28. text_type = {"sound":"音声再生・脳波測定中…", "screen":"画面指示・脳波測定中…", "task":"タスク指示・脳波測定中…"}
  29. mind_type = ["right", "left", "neutral"]
  30. musics = ["001", "002", "003", "420"]
  31. position_rect = (0, 0, 0, 0)
  32. position_circle = (0, 0)
  33. get_tick_time = [0, 0] #[before, now]
  34. # 指示内容を定義
  35. instructions = {
  36. "right": [
  37.  
  38. "右手を想像して箸で食べ物を掴んでください。",
  39. "右手のボタンを押してください。",
  40. "右手のレバーを操作してください。",
  41. ],
  42. "left": [
  43. "左手を想像して箸で食べ物を掴んでください。",
  44. "左手のボタンを押してください。",
  45. "左手のレバーを操作してください。",
  46. ],
  47. "neutral": [
  48. "目を閉じてリラックスしてください。",
  49. "深呼吸をしてください。",
  50. "座禅を組んで瞑想してください。"
  51. ]
  52. }
  53.  
  54. #アプリの初期化
  55. def initialize_pygame():
  56. try:
  57. pygame.init()
  58. screen = pygame.display.set_mode((WIDTH, HEIGHT))
  59. get_tick_time = [pygame.time.get_ticks(), pygame.time.get_ticks()]
  60. return screen
  61. except pygame.error as e:
  62. print(f"Pygameの初期化エラー: \n{e}")
  63. sys.exit(1)
  64.  
  65. #音声・音楽の再生
  66. def load_and_play_sound(filename):
  67. try:
  68. pygame.mixer.music.load(filename)
  69. pygame.mixer.music.play()
  70. except pygame.error as e:
  71. print(f"音楽ファイル{filename}の読み込みエラー: \n{e}")
  72. return False
  73. return True
  74.  
  75. #脳波データの受け取りと処理
  76. def send_nouhadata(s, choice, mind, process):
  77. print_text = text_type[choice]
  78. print("タスク経過時間:", str(get_tick_time[1] - get_tick_time[0]), print_text)
  79. if offLineMode == False and get_tick_time[1] - get_tick_time[0] >= PREP_TIME:
  80. data, address = s.recvfrom(1024)
  81. process.Receive_BrainWave(nouha=data, key=mind, address=address)
  82. get_tick_time[1] = pygame.time.get_ticks()
  83.  
  84. #アプリの終了時の処理
  85. def check_exit(s, choice, process):
  86. for event in pygame.event.get():
  87. if event.type == QUIT:
  88. try:
  89. if not offLineMode:
  90. send_nouhadata(s, choice, mind="quit", process=process)
  91. pygame.quit()
  92. s.close()
  93. sys.exit()
  94. except Exception as e:
  95. print(f"終了処理中にエラー発生: \n{e}")
  96. sys.exit(1)
  97. return False
  98.  
  99. #メイン
  100. def main():
  101. try:
  102. s = socket(AF_INET, SOCK_DGRAM)
  103. try:
  104. s.bind((HOST, PORT))
  105. except OSError as e:
  106. print(f"ポート{PORT}のバインドに失敗。ポートが既に開かれている可能性があります。: \n{e}")
  107. return
  108. screen = initialize_pygame()
  109. process = bwr.BrainWave_Receive()
  110. task_manager = TaskManager.TaskManager(TASK_COUNT)
  111. while True:
  112. try:
  113. get_tick_time[0] = pygame.time.get_ticks()
  114. mind = task_manager.get_next_type("mind")
  115. if mind is None:
  116. print("すべてのタスクが完了しました。ウィンドウを閉じて終了してください。")
  117. while True:
  118. if check_exit(s, choice, process):
  119. break
  120. choice = task_manager.get_next_type("task")
  121. if choice != "task" and mind == "neutral":
  122. task_manager.sub_counts(mind, choice, 1)
  123. continue
  124. if choice == "screen" and mind != "neutral":
  125. try:
  126. load_and_play_sound(os.path.join(SOUND_DIR, "画面を注視してください.wav"))
  127. last_blink = pygame.time.get_ticks()
  128. is_visible = True
  129. screen.fill(black)
  130. #円の描画
  131. if mind == "right":
  132. position_rect = (WIDTH / 2, 0, WIDTH, HEIGHT)
  133. position_circle = (WIDTH * 3 / 4, HEIGHT / 2)
  134. elif mind == "left":
  135. position_rect = (0, 0, WIDTH / 2, HEIGHT)
  136. position_circle = (WIDTH / 4, HEIGHT / 2)
  137. while get_tick_time[1] - get_tick_time[0] <= TIME:
  138. current_time = pygame.time.get_ticks()
  139. if current_time - last_blink >= BLINK_INTERVAL:
  140. is_visible = not is_visible
  141. last_blink = current_time
  142. if is_visible:
  143. screen.fill(black)
  144. screen.fill((255, 255, 0), position_rect)
  145. pygame.draw.circle(screen, (255, 0, 255), position_circle, 150)
  146. else:
  147. screen.fill(black)
  148. pygame.display.update()
  149. send_nouhadata(s, choice, mind, process)
  150. if check_exit(s, choice, process):
  151. break
  152. screen.fill(black)
  153. except pygame.error as e:
  154. print(f"画面描画エラー: \n{e}")
  155. elif choice == "sound" and mind != "neutral":
  156. screen.fill(black)
  157. music_choice = random.choice(musics)
  158. filename = os.path.join(SOUND_DIR, music_choice+"_"+mind+".mp3")
  159. if not load_and_play_sound(filename):
  160. continue
  161. while pygame.mixer.music.get_busy():
  162. send_nouhadata(s, choice, mind, process)
  163. if check_exit(s, choice, process):
  164. break
  165. screen.fill(black)
  166. elif choice == "task":
  167. screen.fill(black)
  168. instruction = random.choice(instructions[mind])
  169. filename = os.path.join(SOUND_DIR, mind+"_"+instruction+".wav")
  170. load_and_play_sound(filename)
  171. print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {instruction}")
  172. while get_tick_time[1] - get_tick_time[0] <= TIME:
  173. send_nouhadata(s, choice, mind, process)
  174. if check_exit(s, choice, process):
  175. break
  176. load_and_play_sound(filename = os.path.join(SOUND_DIR, "タスクを終了してください.wav"))
  177. screen.fill(black)
  178. #画面の更新
  179. pygame.display.update()
  180. #タスク間の休憩
  181. get_tick_time[0] = pygame.time.get_ticks()
  182. print(f"現在の実行回数: {task_manager.get_counts()}\nタスク実行回数: {task_manager.get_taskCounts()}")
  183. while get_tick_time[1] - get_tick_time[0] <= BREAK_TIME:
  184. if check_exit(s, choice, process):
  185. break
  186. get_tick_time[1] = pygame.time.get_ticks()
  187. except SystemExit:
  188. pygame.quit()
  189. s.close()
  190. sys.exit()
  191. except Exception as e:
  192. print(f"予期せぬエラー: \n{e}")
  193. continue
  194. except Exception as e:
  195. print(f"重大なエラー: \n{e}")
  196. finally:
  197. try:
  198. pygame.quit()
  199. s.close()
  200. except Exception as e:
  201. print(f"終了処理中にエラーが発生しました:\n{e}")
  202. sys.exit(1)
  203.  
  204. #直接起動時の処理
  205. if __name__ == "__main__":
  206. main()
  207. # process = bwr.BrainWave_Receive #インスタンス作成
  208. # while True:
  209. # timeClock.tick(250)
  210. # mind = random.choice(mind_type)
  211. # choice = random.choice(screen_type)
  212. # if choice == "screen" and mind != "neutral":
  213. # screen.fill(black)
  214. # #円の描画
  215. # if mind == "right":
  216. # position_rect = (width / 2, 0, width, height)
  217. # position_circle = (width * 3 / 4, height / 2)
  218. # elif mind == "left":
  219. # position_rect = (0, 0, width / 2, height)
  220. # position_circle = (width / 4, height / 2)
  221. # screen.fill((255, 255, 0), position_rect)
  222. # pygame.draw.circle(screen, (255, 0, 255), position_circle, 150)
  223. # pygame.display.update()
  224. # while timeClock.get_time() <= 60000:
  225. # print(str(timeClock.get_time()))
  226. # if offLineMode == False:
  227. # data, address = s.recvfrom(1024)
  228. # process.Receive_BrainWave(nouha=data, key=mind, address=address)
  229. # elif choice == "sound" and mind != "neutral":
  230. # screen.fill(black)
  231. # if mind == "right":
  232. # pygame.mixer.music.load(filename_right)
  233. # pygame.mixer.music.rewind()
  234. # elif mind == "left":
  235. # pygame.mixer.music.load(filename_left)
  236. # pygame.mixer.music.rewind()
  237. # while pygame.mixer.music.get_busy():
  238. # print("Playing...")
  239. # if offLineMode == False:
  240. # data, address = s.recvfrom(1024)
  241. # process.Receive_BrainWave(nouha=data, key=mind, address=address)
  242. # elif choice == "task":
  243. # screen.fill(black)
  244. # instruction = random.choice(instructions[mind])
  245. # filename = ".\\" + mind + "_" + instruction + ".wav"
  246. # pygame.mixer.music.load(filename)
  247. # pygame.mixer.music.play()
  248. # text = instruction
  249. # print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {instruction}")
  250. # while pygame.mixer.music.get_busy():
  251. # print("Playing...")
  252. # while timeClock.get_time() <= 60000:
  253. # print(str(timeClock.get_time()))
  254. # if offLineMode == False:
  255. # data, address = s.recvfrom(1024)
  256. # process.Receive_BrainWave(nouha=data, key=mind, address=address)
  257. # #画面の更新
  258. # pygame.display.update()
  259. # pygame.time.wait(10000) #10秒間クールダウン
  260. # #終了イベント
  261. # for event in pygame.event.get():
  262. # if event.type == QUIT:
  263. # process.Receive_BrainWave(nouha=data, key=9, address=address)
  264. # pygame.quit()
  265. # sys.exit()