技術資料

目次 

目的 

生体・環境センサを用い、数値からストレス値を計測.行動識別から現時点での場所,状態を取得しストレス値を検知したらコーピングを実施する.コーピングは状況に応じた内容を被験者に指示を出し,実行させることで実現させる.コーピング指示はスマートグラスにARオブジェクトを表示させて知らせる.この流れを通じ人間の精神的身体的負担削減を目指す


開発ツールの決定 (ARを作る場合) 

主に使用するデバイスによってツールをインストールする。

使用端末androidiOS
ARCoreArToolkit

使用端末がEPSON開発・MOVERIO-BT300の場合 

ARグラスとして扱いやすいものを選んだ。
この端末はARCoreをサポートしていないのでVuforiapositionも使用できない。
なのでARの使用範囲がかなり狭いです

スマートグラスを用いた行動アシスト 

以降は生態環境情報の取得する方法を習得している前提で記録する

センサとマイコン(Arduino, Raspberry Pi)による行動分類 


ここでprocessing_data.py,newsensa_all.pyが正常に動いて
デンドログラムが表示され、センサ数値が取れているようなったら次行けます

1.データ取得 

以降はproscessing_data.pyのデンドログラム表示関数に書き加えていきます

1.1 音声入力による現在地と状況 

csvファイルに保存,デンドログラム作成に関しては先行研究あんので省略
ラベリングは一回しか行わないので最新がどのラベルの行動分析と一致するかを探る.

#ref(): File not found: "213.JPG" at page "行動分類とスマートグラスによるアンビエント環境構築"

このデンドログラムからわかるように、同じ行動=色でラベルは一つしかないしラベルされてない色もある.
縦軸の関連度を表すユーグリッド距離を指定し,色付けされている.約2000で場所ごとに分けられることが分かっている.(吟味する必要あり)
そこで最新地を識別するには色別に分ける必要がある

#leaf_rotation=0がラベルの向き、orientation="top"がクラスタリングの図の方向
   #color_threshold=xでユークリッド平方距離がx以上を同色で表示
   #above_threshold_color="color"でユークリッド平方距離がx以上を"color"色に染める
   ##最新ラベルとラベルされているデータの距離が2000以内の場合同じ場所として判別#####
   dendrogram(Z, labels=df_label,leaf_rotation='vertical',leaf_font_size=16,color_threshold=2000,above_threshold_color='gray')
   #各データのクラスター番号出力
   group = fcluster(Z, 2000, criterion='distance')

groupリストには時系列でクラスター番号が格納される.つまり色ごとに番号が与えられた。
つづいてcsvファイルから必要なデータをコード内にリストで出力する

   df['時間'] = pd.to_datetime(df['時間'],format='%Y%m%d %H:%M:%S')
       frame_time = pd.to_datetime(df['時間'],format='%Y%m%d %H:%M:%S')
   gsr=df['GSR'].to_list()
   snp=df['心拍数'].to_list()
   loc_label=df['mic'].to_list()
   list_time=frame_time.to_list()

このリストからラベルとクラスター番号を関連付けるためにリストをつくる

   
   loc_c = []    //入力した分だけのラベルの配列
   loc_d = []  //入力した分だけのラベルのクラスター番号の配列
   loc_b = []    //クラスター番号とラベルの合体配列.サイズはデータ数
   loc_label     //リスト型のラベル配列
   loc_num = []  //リスト型のクラスター番号配列 
   for num in group:
       loc_num.append(num)
   loc_b = list(zip(loc_num, loc_label))

このloc_bリストにクラスター番号とそのラベルがセットになって格納されているが、ラベルはほとんどがnanというflort形の空データなので除外する。

   for i in loc_label: 
       if  isinstance(i, str):
           loc_c.append(i)
   print(loc_c)        
   for j,k in zip(loc_num, loc_label) :
       if isinstance(k,str):
           loc_d.append(j)
   print(loc_d)
   print("合体")
   print(list(zip(loc_c,loc_d)))
12021.JPG

上からloc_c,loc_d,ラベルとその番号がセットになったリスト

ラベルにはマイクで「机 勉強中」などつづけて入力するのでこの入力を(場所)と(状況)に分ける必要がある

nowpoint =  group[length-1]   //最新のクラスター番号
#最新地のクラスター番号を調べ、それに対応している場所を特定
   if not nowpoint in loc_d:
       location = '不明 不明'
   else:
       for s,t in zip(loc_d, loc_c):  //最新のクラスター番号がラベリングリストにあったら場所が特定
           if nowpoint == s:
               location = t
#マイクで場所と状況を一度に入れているので分割
   loc_sp = location.split()
   #print(loc_sp)
   location=loc_sp[0]
   situation=loc_sp[1]

この(location)が場所、(situation)を状況、としてhtmlに書き込む


1.2 現在地による行動経過時間 

1.1でクラスター番号とラベリングした場所を関連付けられたので,最新と同じ状況をどれだけ続いているかを調べる.

1201.JPG

これはクラスター番号のリストを表示しているが,時系列で表示されている.
最新は最後なので最新=現在のクラスター番号は3とわかる.そして3が4つ続いているので12~16秒この行動が続いていると思われる.(カメラ取得は5秒で設定しているが3秒や4秒など薔薇薔薇で記録されることが多い)
この時間を取得し,どう行動経過時間を求める.

#場所が変わったかの判断と経過時間の算出
   #前回と今回の値が一緒だったら時間を加算、違ったら計測しなおす
   #start_timeを用意しnow_timeと引き算して分を出す.行動変化したらそれをstaretimeに変更する
   
   if lastpoint != nowpoint:
       print("行動変化")
       start_time = now=time
   else :
       print("継続中")
       #start_timeの算出、一個ずつ戻っていって行動変化したときの時刻をstart_timeとする
       for g in range(len(group)):
           if nowpoint != group[length -2-g]:
               start_time = list_time[length -1-g]
               break
   #行動経過時間の算出
   total_time=now_time-start_time 
   #total_time = total_time.strftime("%H:%M:%S")...0dayを消したい
   print('START ' , start_time)
   print('NOW   ' , now_time)
   print("TOTAL " , total_time)

まずnowpoint=最新のクラスター番号とlastpoint=そのひとつ前のクラスター番号を比較.
同じなら同じ行動が続いている、違ったら行動が変わったということになる.
その2つに応じてstart_time=計測開始時刻を設定する.行動が継続されていると判断された場合は一つ戻って比較,を繰り返す.
時間の演算はdatatimeを使えば簡単な引き算で求められる.

12011.JPG

1.3 生体センサによるストレス予測 

残念ながらストレス値代表LF?HFは出せなかったのでGSR,心拍の数値をストレス状態で予測させることにした
初期の学習データはマイク入力により決める
ラベリング同様に数字だけを入力しそれを主観ストレス値とする(1~10か1,5,8の3つか、のどちらかにしたい)
マイク入力は一桁の数字は入らないので「ゼロ いち」と言えばスプレッドシートには「1」と記録される
そしてprocessing_data.pyのマイクラベルの「nan」を排除する処理でストレスラベルだけの配列を作成しておく
(ラベル要素の長さとかで)
そのラベルが入力された時(直前)の心拍とGSRセンサ数値、ストレスラベルをまとめて配列を作り上げる.
そのストレスラベル配列を新たなcsvファイル(koo.csv)に書き込んだら
決定木分析アルゴリズムにかける(平松初期研究をまるぱくりした)

tree.PNG

GSR、心拍、ストレス値のデータがいっぱいたまったらコードを関数型にして
processing_data.pyで予測値を出力させる

#ストレス計測
   #マイクが数字だったら=ストレスアンケートだったらその時のGSRと心拍を表示
   #最新のGSR、心拍、ストレス入力の多次元配列制作
   for a,b,c in zip(gsr,snp,loc_label): 
       if isinstance(c, str) :
           print(a,b)
           if len(c.split()) == 1:
               H=[[a,b,int(c)]]
               
   #koo.csvに書き込む。最後のデータがひたすら書き込まれるんだけどどうしよう…
   with open('koo.csv', 'a') as f:
       writer = csv.writer(f)
       writer.writerow(H[-1])
   text =list(gssn[length-1])
   print(text[0],text[1])
   stress_data = decision_tree.tre_s(text[0],text[1])


「stress_data」をストレス値として表示

1.4 3つの要素からコーピング内容決定 

ストレスが検知されたらコーピングを発動させる
まず行動経過時間から長時間か短時間化を判別。
今回は60分(1,2時間)同じ行動だと判断されたら場所に応じた内容、短かったら行動自体に問題があるので行動切り替えを促す
(本人が気づかぬうちに長時間行動で身体的負担が増すことを防止する)
また想定される場所に応じて、(ストレス感じる内容を把握)適度なコーピングを示したい。
いろいろ調べてもコーピング内容はほぼ一緒だったので、その行動が可能かを踏まえた。
(会議中だったら休憩には入れないなど)

1215.JPG

行動時間はtotal_secondsで経過時間を秒に直し、規定値と比べる。

   #コーピング内容  
   
   #スプレッドシートの単語から
   if ('computer' and 'sitting' and 'monitor') in camera11:
       #とりあえずPC操作にしておいた
       cope2 = 'コンピューター操作により'
       cope3 = '休憩に入り、目を休め'
       
   else:
       cope2 = 'その他の行動により'
       cope3 = '気分展開、血流よくしなさい'
      
   #行動識別から
   if '兵' in situation:
       cope2 = 'コンピューター操作により'
       cope3 = '休憩に入り、目を休め'
   elif '会議'in situation:
       cope2 = '会議中なので'
       cope3 = 'ちょっと休め、耐えろ'
   elif '休'in situation:
       cope2 = '休憩でも'
       cope3 = '止めなさい'
   else:
       cope2 = 'その他の行動により'
       cope3 = '気分展開、血流よくしなさい'
       
   #とりあえす経過時間が長かった(90分以上,30分以上,それ以下)ら
   if int(total_time.total_seconds()) > 5400:
       print("長すぎ")
       cope1 = '長時間すぎる上'
   
   elif int(total_time.total_seconds()) > 1800:
       print("長時間行動")
       cope1 = '長時間行動と'
   else:
       print("短時間労働")
       cope1 = '行動は短いが'
      #cope3 = '行動を止めたほうがいい'
   
   #コーピング指示ストレス予測によりを決定
   if stress_data=='1':
       cope = 'no'
   else:
       cope = cope1 + cope2 + cope3
       print(cope)

2.ウェブ表示法アシスト:html探索 

今回は取得したデータを用いて行動アシスト表示の制作に入る
データをドライブに保存し,自身のPCでcsvファイルにログを備蓄したあと,データをもとにhtmlを作成する.
流れはcsvファイルを編集するコード(py),表示する文字ファイル(txt),表示されるウェブページ(html),MOVERRIO(グラス)の順で表示する

87.JPG

1.収集したデータをもとに表示する文字を作成(選択)
2.pyでtxtに書き込む。mode指定により毎度書き直すことが可能.まず白紙に数値以外の文字(項目)を書き,データ数値の変数を置き換える形でかきこむ(以下のようにhtmlを編集するならtxtとhtmlは同じファイルに入れる)
3.htmlの中でtxtを埋め込み,変更しない部分はここで編集する.
4.PC(Windowsの場合)htmlがある📁のパスを通す.
  Internet Information service (IIS)のDefault WebSiteの「機能ビュー」の「詳細設定」で📁物理パスを設定.
  さらに「既定のドキュメント」に追加.
5.こうするとPCと同一Wi-Fi内でのみ「http://(PCの物理アドレス)」でグラスにhtmlが表示される.(図の最後はUnityとなっているがこれは自身が掲げた最終目標)

・py内のtxtファイル編集

   file_name = r"C:\\Users\wasaza\Desktop\nana\opendata.txt"
   #コーピング発動時と普段で画像の違うhtml
   opendata = r"C:/Users/wasaza/Desktop/nana/nan.html"
   
   with open(file_name, mode='w+', encoding="utf_8") as f:
       data_lines=('場所 :' + location + '\n状況 :' + situation + '\n\n経過時間 :' + str(total_time) + '\n')
       data_lines2 = ('ストレス予測値 :' + str(stress_data) + ' ・ 状態 :'+ state+'\n指令 :'+cope)
       data_lines3=('Today :' + str(now_time) + '\n')
       
       f.write(data_lines3)
       f.write(data_lines)
       f.write(data_lines2)


・IISの設定

11102.JPG

・html内容(googleクロムで開くのがおすすめです)

11101.JPG

・実際表示されたhtml

12022.JPG



3.ウェブ表示法アシスト:スマホデザリング 

MOVERIOがAndroidなのをいいことにデザリングして同一wifi外でもやれるようにする。
スマホ(研究室)の設定>接続>デザリングからwifiデザリングOnにしてPC、スマートグラスをそのwifiにつなげる。
多分どこにいても2の要領でhtmlが見れるはず 以上!


使ったコード全部 

江崎のドライブに全部ある、はず 江崎のドライブに全部ある、はず
・raspberry pi (python)

graph_maker.py
new_sensaall_esk.py
gasmic_esk.py
他importしたモジュールなど

・PC(python)

processing_data.py
client_secret.json
decision_tree.py
koo.csv
fordend.csv
graf.py(?)
graph_maker.py
make.@y(?)
map.html
model.bin
-html-
winscp
nan.html
opendata.txt
textwinscp.txt
web.config
5.png

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS