Newer
Older
BrainWave-Task-Visualizer / nouha_recv.py
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Wed Jun 5 10:33:19 2024
  4.  
  5. @author: Naoya
  6.  
  7. FocusCalmから得たデータをcsv化するプログラム
  8. BandPower + Attention + Meditationの同時取得可能
  9. それぞれ受信したデータが無い場合にはファイル作成を飛ばす
  10.  
  11. 2024/12/12 更新
  12. ・外部からデータを記録したいとき用にクラス化
  13.  
  14. """
  15. from __future__ import unicode_literals, print_function
  16. from socket import socket, AF_INET, SOCK_DGRAM
  17.  
  18. import numpy as np
  19. import matplotlib.pyplot as plt
  20. import struct
  21. import csv
  22. import keyboard
  23. import datetime
  24. from pythonosc import osc_message
  25. import sys
  26. import collections
  27. import os
  28.  
  29. waves = []
  30. attentions = []
  31. meditations = []
  32. keys = []
  33. key_type = {"neutral":0, "left":1, "right":2, "break":5,"quit":9}
  34. SAVE_DIR = "csvfiles"
  35.  
  36. #
  37. #EEGから送られたデータを配列に変換する関数
  38. #引数:data(EEGデータ)
  39. #返り値:リスト[δ波、θ波、α波、β波、γ波]
  40. def Convert_BrainWave(data):
  41. try:
  42. msg = osc_message.OscMessage(data)
  43. # print(msg.params)
  44. types = msg.address
  45. arguments = []
  46. if types == "/Attention":
  47. arguments.append("Attention")
  48. arguments.append(float(msg.params[0]))
  49. elif types == "/Meditation":
  50. arguments.append("Meditation")
  51. arguments.append(float(msg.params[0]))
  52. elif types == "/BandPower":
  53. arguments.append("BandPower")
  54. arguments += list(map(float, msg.params[0].split(";")))
  55. else:
  56. raise ValueError(f"未知のデータ形式: {msg.address}")
  57. return arguments
  58. except osc_message.ParseError:
  59. print("OSCメッセージのパースに失敗")
  60. return None
  61. except ValueError as e:
  62. print(f"データ変換エラー: \n{e}")
  63. return None
  64. except Exception as e:
  65. print(f"予期せぬエラー: \n{e}")
  66. return None
  67. class BrainWave_Receive:
  68. def __init__(self):
  69. try:
  70. self.waves = []
  71. self.attentions = []
  72. self.meditations = []
  73. self.keys = []
  74. except Exception as e:
  75. print(f"初期化エラー: \n{e}")
  76. raise
  77. def Receive_BrainWave(self, nouha, key, address):
  78. key = key_type[key]
  79. if key == 9:
  80. self.SaveFile()
  81. return
  82. elif key == 5:
  83. converted_datas = ["Break", "", "", "", "", ""]
  84. else:
  85. converted_datas = Convert_BrainWave(nouha)
  86. converted_datas.append(key)
  87. # 受信するデータによっていれる配列を変える
  88.  
  89. if converted_datas[0] == "BandPower":
  90. self.waves.append(converted_datas[1:])
  91. print(f"\n type: {converted_datas[0]}\n alpha: {converted_datas[1]}\n beta: {converted_datas[2]}\n theta: {converted_datas[3]}\n delta: {converted_datas[4]}\n gamma: {converted_datas[5]} \n key: {converted_datas[6]}\n from: {address}\n")
  92. keys = [row[5] for row in self.waves]
  93. elif converted_datas[0] == "Attention":
  94. self.attentions.append(converted_datas[1:])
  95. print(f"\n type: {converted_datas[0]}\n Attention: {converted_datas[1]}\n key: {converted_datas[2]}\n from: {address}\n")
  96. elif converted_datas[0] == "Meditation":
  97. self.meditations.append(converted_datas[1:])
  98. print(f"\n type: {converted_datas[0]}\n Meditation: {converted_datas[1]}\n key: {converted_datas[2]}\n from: {address}\n")
  99. elif converted_datas[0] == "Break":
  100. self.waves.append(["", "", "", "", ""])
  101. self.attentions.append(["", ""])
  102. self.meditations.append(["", ""])
  103.  
  104. def SaveFile(self):
  105. #csvファイルの作成
  106. try:
  107. timestamp = str(datetime.datetime.now()).replace(" ", ",").replace(".", "-").replace(":", "-")
  108. for data_type, data_list, header in [
  109. ("BandPower", self.waves, ["alpha", "beta", "theta", "delta", "gamma", "key"]),
  110. ("Attention", self.attentions, ["attention", "key"]),
  111. ("Meditation", self.meditations, ["meditation", "key"])
  112. ]:
  113. if data_list:
  114. filename = os.path.join(SAVE_DIR, f'nouhadata_{data_type}{timestamp}.csv')
  115. try:
  116. with open(filename, 'w', newline="") as f:
  117. writer = csv.writer(f)
  118. writer.writerow(header)
  119. writer.writerows(data_list)
  120. print(f"csvファイルの生成に成功しました。ファイル名:{filename}")
  121. except PermissionError:
  122. print(f"ファイル{filename}への書き込み権限がありません。")
  123. except Exception as e:
  124. print(f"ファイルへの書き込みエラー。\n{e}")
  125. except Exception as e:
  126. print(f"保存処理のエラー: \n{e}")
  127.  
  128. # if not len(self.waves) == 0:
  129. # with open(r'.\nouhadata_BandPower' + timestamp + ".csv", 'w', newline="") as f:
  130. # writer = csv.writer(f)
  131. # writer.writerow(["alpha","beta","theta","delta","gamma","key"])
  132. # writer.writerows(self.waves)
  133. # print(f"csvファイルを生成しました。ファイル名:nouhadata_BandPower{timestamp}.csv")
  134.  
  135. # if not len(self.attentions) == 0:
  136. # with open(r'.\nouhadata_Attention' + timestamp + ".csv", 'w', newline="") as f:
  137. # writer = csv.writer(f)
  138. # writer.writerow(["attention","key"])
  139. # writer.writerows(self.attentions)
  140. # print(f"csvファイルを生成しました。ファイル名:nouhadata_Attention{timestamp}.csv")
  141. # if not len(self.meditations) == 0:
  142. # with open(r'.\nouhadata_Meditation' + timestamp + ".csv", 'w', newline="") as f:
  143. # writer = csv.writer(f)
  144. # writer.writerow(["meditation","key"])
  145. # writer.writerows(self.meditations)
  146. # print(f"csvファイルを生成しました。ファイル名:nouhadata_Meditation{timestamp}.csv")
  147.  
  148. #このプログラムを直接開いた時の処理
  149. def main(process):
  150. while True:
  151. data, address = s.recvfrom(1024)
  152. if keyboard.is_pressed('F8'):
  153. recvFlag = (recvFlag + 1) % 2
  154.  
  155. if recvFlag == 1:
  156. if keyboard.is_pressed('left') or keyboard.is_pressed('a'): #左キーを押したとき
  157. key = 1
  158. elif keyboard.is_pressed('right') or keyboard.is_pressed('d'): #右キーを押したとき
  159. key = 2
  160. elif keyboard.is_pressed('up') or keyboard.is_pressed('w'): #右キーを押したとき
  161. key = 0
  162. elif keyboard.is_pressed('q'):
  163. key = 9
  164. process.Receive_BrainWave(data, key, address)
  165. print("処理を中止します")
  166. s.close()
  167. break
  168. else:
  169. pass
  170. process.Receive_BrainWave(data, key)#終了しないときはここに到達
  171. else:
  172. if keyboard.is_pressed('q'):
  173. print("処理を中止します")
  174. s.close()
  175. break
  176. print("recvFlag = ", recvFlag, ", key = ", key)
  177. if len(waves) > 0 and (1 in keys or 2 in keys):
  178. print(collections.Counter(keys))
  179.  
  180. #処理が最後までに終了したあとにポートを閉じる
  181. s.close()
  182. saveFlag = int(input("保存しますか? 保存する:1、保存しない:2 >>"))
  183.  
  184. if saveFlag == 2:
  185. sys.exit()
  186. process.SaveFile()
  187.  
  188. #メインの処理(このファイルを直接開いたとき)
  189. #データを受け取って処理、キー入力を認識してデータに追加
  190. #何も押さなければkey=0、左キーでkey=1、右キーでkey=2、上キーでkey=3、下キーでkey=4、qキーで処理の中止
  191. #最新のデータのみ毎回表示、
  192. if __name__ == "__main__":
  193. HOST = ''
  194. PORT = 8001
  195. s = socket(AF_INET, SOCK_DGRAM)
  196. s.bind((HOST, PORT))
  197. recvFlag = 0
  198. key = 0
  199. process = BrainWave_Receive()
  200. main(process)
  201.