0819
2013-08-19
*1376891440*necomimiを改造して脳波データを取り出した
脳波で猫耳が動く「a href=http://www.amazon.co.jp/gp/product/B007YNBOJM/ref=as_li_ss_tl?ie=UTF8camp=247creative=7399creativeASIN=B007YNBOJMlinkCode=as2tag=nishiohirokaz-22necomimi/a」が、なんと3000円台で投げ売りされて話題になっていました。僕も3150円で買いました。なんと中に入っている脳波チップを単体で買うより安い!(a href='http://www.switch-science.com/catalog/978/'スイッチサイエンス/aではいま4980円)
頭に着けるための電極とセットになっているのにチップより安いだなんて!よしこれを改造してPCで脳波の値を取得できるようにしよう!
necomimiの分解・改造に関しては既に先人がいくつかのエントリーを上げておられます。まずこちら: a href='http://hizwarp.net/archives/386'nekomimiを分解してみた/a。シールを剥がすとネジが出てくるのでそれを回せば簡単に開くとの話。これはそのとおりでした。簡単でした。シールを剥がす時にノリが残ってネチョネチョにならないように慎重に剥がす必要があるけど。
上記スイッチサイエンスのページから各ピンがどういう意味かの説明PDFが見れます。Pin1が額でPin2がその線のシールド線(ケーブルがノイズを受けるのをキャンセルするためか)、Pin5が耳でPin4がそのシールド、じゃあPin3はどこにつながるんだ?Pin3も耳電極につながってるんじゃないかと思ったけども、テスターではPin5だけが耳電極と導通。耳たぶ電極は2つの金属で挟む形になっているけども、その片方だけがPin5と導通。これでいいのかなぁ。ちょっと不安。最悪の場合僕のnecomimiがのPin3の配線が断線している可能性も考えられる。手元には1個しかないので誰か他の人にPin3がどこにつながっているのか確認して欲しいところです。
あ、耳たぶ電極のことを「心拍センサ」と書いているブログを何処かで見かけましたけど、心拍センサはLEDと受光素子が向かい合わせになっている構造で、こっちは両方金属なので心拍センサでないことは明らかです。
さて次は心拍データをnecomimiの外に引っ張りだす配線をしましょう。こちらを参照:a href='http://www.kako.com/neta/2013-019/2013-019.html'小ネタ/a。脳波チップTGAM1の出力はスイッチサイエンスのサイトに書いてあるとおり「UART(57600 baud、8ビット、パリティ無し、 1 ストップビット)」なので、このUARTのTXとGNDを引っ張り出します。僕は最初間違えてTXとRXを引っ張りだしてしまった…。ここのサイトのようにTXを回路から、GNDを電池ボックスから取る形に変更して、ちゃんと信号が取れるようになりました。
取り出したUARTの信号をUSB端子経由でPCで読むために、秋月のAE-UM232R(FT232RLを使ったUSB-シリアル変換基板)を使います。今回、チップは3.3Vと書いてあったので、以前自分が書いたエントリーa href='http://d.hatena.ne.jp/nishiohirokazu/20130406/1365258081'AE-UM232Rで3.3V出力を出す方法/aを参考にしてジャンパピンを設定します。J1を1-2間ショートにする必要があります。
回路のクローズアップ。黒いケーブルがnecomimiのGNDにつながっていて、それが青いワイヤーでAE-UM232RのGNDにつながっています。白いケーブルがnecomimiのTXにつながっていて、これが3本のワイヤーを経由してAE-UM232RのRXD、反対側の5本目のピンにつながっています。
f:id:nishiohirokazu:20130819203954j:image
これで /dev/tty.usbserial とかからチップの出力が読めるようになります。おっと書き忘れていましたが僕の環境はMac OS X 10.7.5です。この出力をどうこうする上では、チップを作っているNeuroSkyがSDKを公開しているのでそれを参照するのがよいでしょう。a href='http://developer.neurosky.com/docs/doku.php?id=thinkgear_connector_tgc'thinkgear_connector_tgc NeuroSky Developer - Wiki/a。Windows版とMac版のアプリが用意されています。アプリを起動したらそのアプリがシリアルを読みつつサーバになって、TCPで13854ポートをListenし始めるので、適当なプログラムからそこへ接続すればJSON形式でデータが送られてくる…はずなんだけどもJSON形式にする設定の仕方がわからずバイナリフォーマットで送られてきたので「a href=http://www.music.mcgill.ca/~ben/306/binary_socket_protocol.pdfBinary Socket Packet Format/a」を参考にして自分でパースしました。
ここでeSenseが返す「集中」と「瞑想」の値でグラフを書いてみるとなんと正弦波に。これはThinkGear Connectorを起動するときにシリアルデバイスの指定を間違っていてうまく接続できなくて、色々設定を変えて試している時にうっかり「Demo mode」をONにしてしまったからでした。デモモードをOFFにすると、今度はバイナリパケットのフォーマットは正しいのに、ペイロードが0の状態に…うむむ。よくわからないのでNeurosky提供のツールを使わないで自前でシリアル通信をしてみることにします。
あ、ちなみにnecomimiはモーター音がうるさいのでドラえもん化しました。モーターの部分も裏のシールを剥がせばネジ穴が出るので簡単です。白黒の信号線は耳電極のケーブルが出る穴を広げてそこから外へ出しています。
f:id:nishiohirokazu:20130819145001j:image
シリアル通信にはpyserialを使えばOK。こっちのフォーマットは上記ソケットを流れるバイナリフォーマットと似ているけども違うフォーマット(a href='http://developer.neurosky.com/docs/doku.php?id=thinkgear_communications_protocol'thinkgear_communications_protocol NeuroSky Developer - Wiki/aを参照)なのでパーサをまた書くのかー面倒だなーと思ったのですが、ちょっと調べてみたら既に書いている人がいました。
https://pypi.python.org/pypi/thinkgear/0.2
PyPIに上がっているので pip install thinkgear ってするだけでライブラリがインストールされます。というわけで数行のPythonスクリプトを書くだけでOK。ThinkGearRawWaveDataを表示しないで捨てているのは、これが生データのパケットなので画面があっという間に流れてしまうから。捨ててやると残りのパケットは1秒に1回の頻度で送られてくるので目視で観察するのに適当です。
|python|
import thinkgear
PORT = '/dev/tty.usbserial-A9004xwG'
for packets in thinkgear.ThinkGearProtocol(PORT).get_packets():
for p in packets:
if isinstance(p, thinkgear.ThinkGearRawWaveData):
continue
print p
||
このスクリプトの出力はこんな感じ https://gist.github.com/nishio/6260262
||
POOR SIGNAL: 26
ASIC EEG Power: EEGPowerData(delta=1087207, theta=316167, lowalpha=848603, highalpha=153512, lowbeta=225246, highbeta=115827, lowgamma=113654, midgamma=80802)
ATTENTION eSense: 0
MEDITATION eSense: 0
POOR SIGNAL: 51
ASIC EEG Power: EEGPowerData(delta=644431, theta=203717, lowalpha=354474, highalpha=333722, lowbeta=141786, highbeta=80020, lowgamma=73025, midgamma=72347)
ATTENTION eSense: 0
MEDITATION eSense: 0
||
脳波の強度が8つの分類ごとに表示されています。delta=644431, theta=203717, lowalpha=354474, highalpha=333722, lowbeta=141786, highbeta=80020, lowgamma=73025, midgamma=72347…と。
あれれ…やっぱりeSenseの集中と瞑想の値が0だな…。2通りのソフトウェアで両方うまく行かないってことはハードウェアの問題なのだろうか?? センサーからの信号の質を表すPOOR SIGNALは、ヘッドセットを外すと200になり、つけると26ぐらいまで下がるので良好な信号が得られているってことだと思うのだが…まさかこれが0にならないとeSenseの出力が出ないとか?
とりあえずここまでの情報でも誰かの役に立ちそうだと思うのでシェアしておきます。もしeSenseの値までとれた方がいましたら教えていただけるとありがたいです。
状況を整理するために追記
- 分解前に普通に装着した状態で、耳はなんだかそれなりに動いていたけども、目を閉じて瞑想しようがアクションゲームをしようがはっきりわかる変化はなかった。この時点ですでに断線していた可能性が考えられるが比較対象がないのでよくわからない。
- 脳波チップのPin3がセンサーに繋がっていないことを疑問に思っているが、比較できる別のデバイスがないので正しいのかおかしいのかわからない。誰かデバイスを持っている人に確認して欲しい。
- ThinkGear Connecterでセンサーの値が0になってしまう現象を観測したのはドラえもん化の前。また、センサーからの信号でモーターがドライブされる回路の構造を考えても、モーターの回線を切ったことがセンサーからの出力に影響するとは考えにくい。
- UARTから読み込んでパースするあたりが問題なく動いていることから、読み出しのための回路が壊れているとは考えにくい。回路が壊れてて「バイナリプロトコルに正しく従いつつeSenseの値だけ0」という出力が出てくる確率は低そう。
- 「自分はeSenseの値もとれている、POOR SIGNALは0」という情報を頂きました。ということはシグナルの質が悪いのでチップがeSenseの値を出していないと可能性が高いか…その理由はなんだろう。やっぱりPin3が気になるので、これを耳センサにつないだりGNDにつないだりを試してみようかな。
- 「PCにつないだせいでACアダプタからのノイズが脳波回路の方にまで流れてシグナルの質が下がっているのではないか、ACアダプタを抜いてバッテリー駆動にしたらどうか」というご指摘があったので試してみましたが、POOR SIGNALの値に変化はありませんでした。
- 信号線とUART-USB変換基板の間にフォトカプラを挟んで電気的に絶縁する案も。
- 「Pin3は耳電極の片側に導通していた」という情報を頂きました。信号の質が悪いのはPin3~耳電極間が断線しているせい、という可能性が高まりました。次はこの修理を試してみたいと思います。
2011-08-19
*1313756054*セプキャン2011感想文
みんながバイナリ((http://d.hatena.ne.jp/mayahu32/20110816/1313505335))とかバイナリ((http://twitter.com/#!/_ko1/status/103706889086443520))とかUCAS((http://d.hatena.ne.jp/k_operafan/20110815/1313421656))とかで書いて読むのに苦労したから、僕はちゃんとASCIIで書きましたよ!
https://gist.github.com/1156669
** 言語仕様
1文字1トークンで、単純に並べるだけで関数呼び出しになる。たとえば「XYZ」というコードがあった場合、これはPythonでいうところの「X(Y)(Z)」に相当する。つまり「関数Xに引数Yを渡して呼び出し、その返り値の関数に引数Zを渡して呼び出す」という意味だ。
括弧()は特別な意味を持っていて、まあみんなの期待通り処理をまとめるのに使われる。評価は内側の括弧から順番。たとえば「X(YZ)」というコードがあった場合、これはPythonでいうところの「X(Y(Z))」に相当する。つまり「関数Yに引数Zを渡して呼び出し、その返り値を引数として関数Xを呼び出す」という意味だ。あと一番内側が複数個ある場合は一番出現が早いものが評価される。「( (01)(02)(03) )」だと01,02,03の順に実行されるってことね。(追記:「一番内側」という言葉が「一番カッコの深いところ」と誤解されうるのでもう一言書いておくと「( (01) (0(02)) (03) )」は01, 02, 0(02), 03の順に実行される。)
組み込み関数がU, 0, 1の3つ。あと名前付けのための特殊形式+がある。
一番独特なのは数値が全て関数でもある点で、整数オブジェクトはその数だけ増やす関数としても扱える。1は整数の1であると同時に関数でもある。たとえば「11」は「1という関数に引数1を渡したもの」になるので2になる。ただし、0だけは0増やす関数になっても面白く無いので引数を出力する関数にした。返り値は引数に0を足したものになる。先ほどの例にあった「( (01)(02)(03) )」は1,2,3の順に出力し、その後(123)を評価して6を返す。
あと特殊形式+は値を名前に束縛する。「+X(11)」とやると、(11)が整数の2になってからそれをXという名前に束縛する。だからそれ以降「XX」とかやれば関数2に数値2を入れたことになって4が返る。評価の順番に注意。意外に思うかも知れないが「X(+X(11))」は最初のXが評価されるのより+Xで束縛される方が先なのでエラーにならずに実行される。なお(+XY)の返り値はYである。
もう一度例を挙げると、「(0(1(01)))」はまず(01)が評価されて1が出力され、(0(11))の(11)が評価されて2になり、最後に(02)が実行されて2が出力される
組み込み関数Uの仕様は http://en.wikipedia.org/wiki/Iota_and_Jot を参照。
言語の名前はspcampでバージョン番号が2011.0.0。
他になにか言うことあったかなぁ。不明な点があれば気兼ねなくコメントしてください。
ソースコードにSとかKとかIが出てきているのはかなり親切に書いたつもり。全部Uで書いてもよかったんだけど本質的じゃない部分で読みづらいし。特殊形式の+とかもSKIをUから定義してコードをコンパクトにするために作ったわけだし。S,K,Iについて良い日本語の記事がどこにあるかわからなかったので SKI combinator: http://en.wikipedia.org/wiki/SKI_combinator_calculus を参照。(追記:Uの仕様も含めてa href='http://blog.livedoor.jp/dankogai/archives/51524324.html'404 Blog Not Found:Math - 言語はどこまで小さくなれるか - (unlambda|iota|jot) のすすめ/aがよくまとまっている)
1文字1トークンだからレキサーいらないし、構文も括弧で木構造なだけだからパーサも簡単。処理系はPythonで書いてて、doctestでテストケースたくさん書いて300行程度だからテスト削ったら200行くらいかなぁ。dis.disでバイトコードにディスアセンブルして562行くらい。SimpleHTTPServerよりちょこっと小さい。
追記: 12:03時点でメールで1通の正解が送られて来ました。
*1313757478*NHKでセプキャンが紹介されました
http://cgi2.nhk.or.jp/nw9/pickup/?date=110818_2
テレビがないので見れないと思ってたけど、公式にオンラインで見れるようだ。NHKすばらしい。内容も前提知識のない人向けということを考えればよくまとまってるんじゃないかな。
そして0.2秒くらいしか僕が映ってないのに妻が1回見ただけで発見してて女性は恐ろしいと思った。
img src=http://gyazo.com/f7f8e9d63881b4454efd60ee55caa3fd.png
あ、あとLACかっこいい。
2010-08-19
*1282200581*Ruby 1.9.2リリースとWEBrick脆弱性問題の顛末
はい、a href='http://www.ruby-lang.org/ja/news/2010/08/18/ruby-1-9-2-is-released/'Ruby 1.9.2がリリース/aされましたね。このバージョンではa href='http://slashdot.jp/security/article.pl?sid=10/08/13/0133222'WEBrick にゼロデイ攻撃可能な脆弱性 - スラッシュドット・ジャパン/aで紹介されている脆弱性が僕が書いたパッチで修正されているわけなのですけど、そもそもなんで僕が修正しているのか、って顛末がわりと面白いので紹介します。
- Apple、upstreamに報告してくれないまま脆弱性をCVEに届け出る
- upstreamに連絡が来ないまま脆弱性が公開される
- ruby-devにAppleが書いたと思われるパッチが貼られる(Appleでない人間によって)
- パッチのライセンスが不明なので取り込めない
- ライセンスを問い合わせるAppleの窓口が不明なので問い合わせもできない
- ruby-devを読んだ人はライセンス上安全なパッチを書けない
- 脆弱性だから話は非公開に進めたい
- yuguiさんがruby-devを読んでない僕に書かせることにする
- yuguiさんから攻撃用コードをもらってパッチを書く
- パブリックドメインと宣言
- Rubyに取り込まれて1.9.2リリース
Rubyのコードはほとんど書いたことがなかったので頼まれたときはできるかどうか不安だったのですけど、攻撃コードを見てみたらa href='http://openmya.hacker.jp/hasegawa/public/20061209/momiji.html'それ Unicode で/aのHACK #1で紹介されている2005年にGoogleの404ページで発生した脆弱性と同じなのが自明だったので、Tracer.onして攻撃して出力を眺めて問題点を修正するだけで簡単に直りました。
結局のところ、何が問題かというと
- 問題点を発見したら上流に報告して欲しい。あなたが困る問題はみんなも困る可能性があるんだ。
- 著作権を主張しないつもりなんだったらそれを明示的に宣言して欲しい。ライセンスが明示されていないのは、どんなライセンスよりも厳しいライセンスだ。
ということなんですよねぇ。おねがいしますよ、Appleさん。
hr
追記
a href='http://d.ma-aya.to/?date=20100819#p02'ポケットを空にして。(2010-08-19)/a
うーむ。
この記事には明らかな間違いと、正しいか正しくないかグレーな内容が含まれている。間違っていることくらいみんなわかるだろうしあえて言及して追い詰めることもないかなぁと思ってスルーしていたのだけども、身近で間違いに気づかない例が観測されたのでやっぱり言及しておかないとな…
まずは明らかな間違いについて。
Ruby に不適合なライセンスであるとしたら、それを組み込んで Apple が配布した Ruby がライセンス違反になるので、Ruby に適合したライセンスであると見なすのが適当であろう。
お茶を吹くかと思った。一般に「XのコードをYが使ってもよい」ことと「YのコードをXが使ってもよい」ということはイコールではない。たとえばAさんが自分のプログラムをパブリックドメインやNYSLで公開していたとする。Bさんはそれを修正したコードを自分の好きなライセンスで公開できる。AさんがBさんの行った修正を自分のソフトに取り込んでパブリックドメインを維持したら、これはライセンス違反になりうる。またCさんがLGPLでライブラリを公開して、Dさんがそれを修正してGPLで公開したとする。Cさんがその修正コードを取り込んだら、やっぱこれもGPLにしないとライセンス違反になりうる。GPLやパブリックドメインが特殊なのではない。一般論として「YがXを使えるならXもYを使える」なんて無茶苦茶な論理は通用しないってことだ。
次にグレーな内容について。
件のパッチに著作権が発生するか否か、といわれるとしないと思われる。全体のコードの割合から検討するとかなり少なく(1liner)、しかも部分修正で他の人から見てもそれ以外の修正方法はあまりないという時点で著作物とは見なせないと考える。
「みなせないと考える」のは自由だ。しかしあなた個人が「みなせないと考える」ことには何の意味もない。「これは著作物である」と著作権者が主張した場合にどうなるかを考えるんだ。あなたが法廷で「これは著作物とみなせない」と主張するための弁護士代や法務手続きの労働時間を提供してくれるのか?
今回の件に関して著作物とみなせないんじゃないかという意見は多い。僕だって今回の1行修正のパッチに著作権が発生すると法廷が認める確率はものすごく低いと思う。とても白に近いグレーだ。しかし問題点はそんなところじゃないんだ。そんなレイヤーの議論をしているのではない。現状のRubyコミュニティに訴訟に対処できる体力がない以上、いくら白に近く見えてもグレーなものは避けなければいけないんだ。
2009-08-19
*1250657560*Firefoxの検索バーからGoogleを英語で検索するには
lang=jaを削ったりとか「全言語から検索」をクリックして再検索とかめんどくさいし、デフォルト英語でいいんだけどなぁ、と思いながらGoogleの側でSearch LanguageやIntarface Languageを英語にしてみたりしてたけど、正解はこれ:
http://mycroft.mozdev.org/google-search-plugins.html
から「Google (No country redirect)」をクリックすれば一発インストール。
http://blogs.atanaka.biz/tanaka/index.php?itemid=960
本当に一発だった。もっと早くやっておけばよかった。
*1250674547*脳波日記
ここしばらくの電子工作日記と脳波日記を読み返すと、徐々に成長しているのがわかって面白い。前回の: http://d.hatena.ne.jp/nishiohirokazu/20090810/1249875992
結局、計測用アンプ(インスツルメンテーションアンプ)とかもろもろのアンプは類似品で代用したりせずに素直にDigi-keyで買うことにした。今日は抵抗やコンデンサを色々買った。
- コンデンサ売り場に行くとpFって単位とμFって単位しか見かけないのでそれが隣接しているような気がしてしまうが、1000pF = 1nF = 0.001μF、そしてμはアスキーじゃないのでしばしばuFと書かれる。回路図でパスコン(VccとGNDの間に挟むコンデンサ)に100nFと指定されていて、日本ではあんまり見かけないサイズだけど向こうではそれがメジャーなのかなーとか思っていたがこれ0.1uFね。すでに10個セットで2つ買っていた。
- 秋月は混んでいるので苦手だが、三端子レギュレータを買いに行ったらあっさり見つかった。電源用トランジスタはあの辺だなーと。ちんぷんかんぷんなりに何度も眺めているとどこに何があるのか徐々にわかってきているようだ。
- 電解コンデンサの相場がわからなくて、目につくところにあった100円の47uFより少しわきにあった50円の47uFの方が安い!と得をしたつもりで買ったが10円で売っているのを後で知って凹んだ。
- 電解コンデンサ10円、セラミックコンデンサ20円、抵抗5円って感じですか
- 足りないもの: アンプ、フォトカプラ
- PCと通信する部分がPCから激しくノイズを拾ってしまうので、フォトカプラで隔離する必要がある。OpenEEGの回路図では激しくノイズを拾う部分(シリアル通信部)とアンプとで同じ電源で動くことになっているので、間にDC-DCコンバータを挟んで隔離した上でコイルとコンデンサを挟んでコンバータの作るノイズを捨てている。しかし電池で駆動することが推奨と書いてあるので、そもそもフォトカプラよりセンサー側の回路は全部電池で駆動することにすればいいんじゃないのか。
- そもそもシリアルがないのでUSBにしたいし。
- 電池駆動(センサ→アンプ→フォトカプラ)→USB駆動(ケーブル→AVR→USB-Serial→PC)
- 「AVR→USB-Serial」の部分はArduinoで置き換え可能です!のはずなのでそのほうがみんな幸せになれそうだと思うんだ。
-- 残念ながらアナログ信号をフォトカプラに通すと激しく歪むらしいので(歪んでも倍音成分が載るくらいだから脳波に関してはあんまり実害がない気がするけど)すなおにAVRとUSB-Serialの間にフォトカプラを挟むことにしました。
- 電池駆動部はヘッドセット側に搭載する
- 積層セラミックコンデンサ(例の青い小さいやつ)をたくさん買ったのでどれがどれか識別する方法を学ぶ必要がある。10: 10pF, 100: 100pF, abc: (ab * 10^c)pF 簡単
- 抵抗の読み方は覚えたが220Kが赤赤橙なのを見て少し不安になった。22 * 10^4だから合ってるんだが、2.2だったかな?と不安になった。2.2のを見ると赤赤金になっていて金が-1乗、銀が-2乗。
たりないものはアンプとフォトカプラ、のはず。抵抗とコンデンサが十分な量あるはずなのでとりあえずブレッドボードで組み立ててみる。ブレッドボードでそれなりに動作チェックをしてからハンダ付け。
- 抵抗
-- 2.2K 100個入り 100
-- 470 100個入り 100
-- 7.5K 100個入り 100
-- 1M 100個入り 100
-- その他 @5 x6 30
- コンデンサ
-- 積層セラミック @20 x30 600
-- 0.1uF(100nF)10個 @100 x2 200
-- 電解コンデンサ 47uF @50 x2 100 #失敗
-- 電解コンデンサ 47uF @10 x8 80
-- 積層セラミック @20 x4 80
- インダクタ 22uH @25 x2 50
- 三端子レギュレータ L7805C 4個入り 100
hr
「ブレッドボードもう一つ買えばよかったな。」そして増えて行く「作りかけ回路の刺さったブレッドボード」
*1250698020*「ヱヴァンゲリヲン新劇場版:破」見て来た
- 1: id:akio0911と秋葉原で出会う
- 2: akio「ヱヴァ見ましたか?」
- 3: アニメも1回見ただけだし、前の劇場版も見ていないのであんまり興味がなくて…
- 4: akio「見てない?!それはいけない!今から見に行きましょう!」
- 5: 新宿に移動して見て来た
読者の皆さん、ヱヴァ見ましたか?
見てない?それはいけない!
エヴァに興味がなくても、SFに興味があるか、抽象画に興味があるか、映像に興味があるかのどれかであればぜひ見るべき。見るべき。見るべき。
hr
秋葉原で待ち合わせ→晩ご飯を食べる→新宿に移動→一緒に映画を見る→終電で帰宅
img src=http://gyazo.com/21d657586911b296d9686d9ff5ecd2bb.png
な、ば、そんなんじゃないんだからねっ!!