2012年5月7日月曜日

アシッドたんぱ大放送復活スペシャルにいってきた

"日本の平均的かつ最先端のクラブ"でおなじみの渋谷アシッドパンダカフェ。アシパンのポッドキャスト公開録音イベントに行ってきたよ。Dommuneを参考にした2部構成で、1部にトーク。2部にDJミックス。

第1部は店主の高野政所さんトークショー。トップ5の裏話を。おかしな名前のゲストが呼ばれた背景などを、当人を交えてのお話。録音してポッドキャストの予定だったのですが、録音に失敗していたとのこと。現場とUstreamのみのお楽しみになってしまったので、ここには書きません。

2部のDJミックスがすごかった。高野政所 a.k.a. DJ JET BARONとプリキュアおじさん2人のDJで、先発はDJ JET BARON。Funkotが楽しくて盛り上がるのは当たり前で、それ以上に政所さんがかっこいい。曲にノリつつもびしびし選曲をすすめる。代官山の申し訳ないと年末スペシャルでも政所さんのDJは聞いていたんだけど、あのときは照明でよく見えなかったんだよね。DJブースとの距離が近いのがアシパンのいいところ。

そしてプリキュアおじさん(=プリキュアにはまりすぎるあまり、政所さんに命名された)のDJ。プリキュアを見たことないし曲も知らないけど、確実に楽しいDJミックス。政所さん曰く、曲を聞きすぎているから完璧につないでいくとのこと。みんな聞ける機会をつくって聞きにいくべき。加えてVJもプリキュアおじさん自身が。というか他の人では無理だろうと。一人二役をバキーッとこなしてフロアを盛り上げるプリキュアおじさん、こういう大人になりたいと思いました。

"アシパンこわい"という声はありますけども、アシパンがこわいというよりも、初めて飛び込む場所がこわいってことかなと。初めて参加する勉強会はなんとなくこわかったりするしね。アシパンの中の人はみなあったかいというか、自分たちが楽しいと思ってることを一緒に楽しんでくれる人なら心のハードルは下がるじゃないですか。アシパンこわくなかったよ。

2012年4月30日月曜日

iOSの音声変換の精度が高すぎてビビってたじろぐ

iPhone 4Sでは音声から日本語を入力する機能が搭載されています。その変換精度がヤバいという話。

日本語はめんどうなもので、同じ読み仮名でも違う意味の言葉や、読み仮名も発音も全く同じなのに意味の違う言葉なんてものが存在します。上がその例。"うたまるさん"は当てられている漢字が違うだけで、発音は両者ともに同じ。これをSiriのシステムは完璧に使い分けるんですな。

もちろん"うたまるさん"だけでは、どっちかの判別は無理。ぼくの場合、1回目は"宇多丸さん"と変換されたので、おそらく変換履歴でも見ているのだろうと。だいたいの人は歌丸さんだと思います。

これに前後の尾ひれがつくと、変換の分岐が完璧になります。"らいむすたーのうたまるさん"のときに、後半が歌丸さんになることが(いまのところ)起きません。逆もまた然りで、"らくごかのうたまるさん"では想像通りの変換結果になります。単語じゃなく、文章(単語のつながり?)で判定していることがわかります。

もうひとつ。"うたまるもうしわけじゅにあ"なんて面倒な日本語も一発。後ろに"申し訳"がついているってことは、ここは歌丸ではなく宇多丸だなと判定していますね。

辞書サーバのチューニング加減ではあるのですが、サーバにはどんだけ収録してるのかとか、単語どうしの関連の重みづけ具合なんかとかが気になってしまうのです。"申し訳ないとフロム赤坂"のフロムがきちんとカタカナに変換される理由とかね。最後に定番のめんどうな日本語を。

2012年3月31日土曜日

オシロスコープをインターネットの向こう側へ

オシロスコープの3つめ。諸事情でRubyをつかっていた部分をすべてNode.jsにしました。決してRubyがキライになったからじゃないですよ。

全力で稼働中

ひとつ前と変わらずNode Ninjaさんで動かしています。→こちら←。仕組みの解説をします。

サーバ側

いままではNode WebSocket Serverをつかい、生のWebSocketをつかってブラウザに送っていましたが、今回からSocket.IOをつかうことにしました。なぜか。生WSのときは、Arduinoで読み取った信号の受け口とブラウザ送信の送り口を同じエンドポイントで運用していました。これだと特にKUFUをしない限り、誰でもサーバにメッセージを投げられて、全てのブラウザに送信されてしまいます。いままではサーバ起動後すぐにArduino側のスクリプトを起動しサーバに接続、IDを保存しておいてそのIDから来たメッセージのみブラウザに送信するとしていたのですが、なんとなくスマートじゃない。これを、Socket.IOの名前空間を利用して解決しています。

名前空間(Namespace)とは

ブラウザからSocket.IOを利用してサーバへつなぐ際に、log.niccol.li/hogehogeのようにサーバ名+文字列を指定することができます。スラッシュ以降が名前空間と呼ばれる機能で、指定した文字列ごとにサーバ内で処理を分岐させることができます(詳しくはこちら)。受信用・送信用に名前空間を分け、ブラウザからは送信専用のエンドポイントを指定することで分離を実現させています。

Arduino中継側

「ArduinoがanalogReadの値をシリアル通信で送信、受けたPCがWebSocketでサーバへ送信」の流れは変わっていません。いままではここをRuby/EventMachineで記述していましたが、サーバでSocket.IOを使い始めたのにあわせてNode.js+Socket.io-clientに置き換えました。前述の名前空間をつかい、Arduinoからの信号受信用のエンドポイントを指定しています。

ここでNode.jsに置き換えたことでちょっと変化が。シリアル通信を読むときに、EventMachineではたまに改行を見落とすため、異常な値が送信される問題がありました。これがNode.jsでは起こらないんですね。モジュール内部も含めて、シリアルポートから読み出したあとの処理に差異はみられないため、読む処理そのものの問題なのかなと。違う点といえば、NodeはTTYも含むI/Oをlibuvでまかなっているため、ノンブロッキング処理になっていますが、Rubyのほうはブロッキング処理のよう。改行で文字列を分割するタイミングとTTY読み出しが当たるととぶのかなと思ってはいますが、どうやって確かめたらいいんですかね。

2012年3月18日日曜日

Arduino用オシロ、実演中

EventMachineとHTML5でつくる、Arduino用なんちゃってオシロスコープの続き。あなたのウェブブラウザでオシロスコープを実際にお楽しみいただけます。とは言っても波形を見られるだけなんだけどね。

デモンストレーションはRealTime - FakeScopeから。東京Node学園祭でいただいたNode Ninjaのサーバをつかっています。

ながれ

  1. Arduinoからシリアル通信でMacへ測定値を送信
  2. シリアル通信をEventMachineで受けたのち、WebSocketでNode Ninja上の中継サーバへ送信
  3. 中継サーバからブラウザへWebSocketで送信
  4. ブラウザ上で、Flotr2を使ってグラフ化
いま(3月18日23時時点)サーバで見えている波形は、iPhoneのスピーカー部分の振動を拾っているところ。何か音楽がかかっていれば揺れます。

それなりの勢いでWebSocketのデータを流しているので、Node Ninjaさんから怒られないか心配しているところではあります。

これから

ArduinoからMacを経由して中継サーバに送っているところ。ここはEthernet Shieldなどを使って、Arduino自信がサーバへ直接送信できるようになればスルーできます。また、信号の発信元もArduinoである必要はありません。WebSocketサーバにCSV形式で値を投げられるならば、何だってよいのです。ゆくゆくはエンドポイントを公開して、センサーネットワークの受け側にしたりとかしたいですね。

おまけ

なんでもグラフ化してみんなでシェアすればソーシャルグラフじゃね?という駄洒落を名古屋でのLTにておみまいしましたが、微妙なウケ具合でした。負けません。

2012年3月13日火曜日

東京と名古屋でLTをやったらすごいウケた話


まさかIT系のLTでトロンボーンを出す日が来るとはね

この週末は東京と名古屋でLTをやってきました。3月10日の土曜日は文京区の情報処理推進機構にて小江戸らぐ。ここでウケたところで調子にのって、12日月曜は名古屋新栄のPiano Bar Club Adriana a.k.a. 名古屋 Geek Barでも。

内容はというと、ひとつ前のArduinoオシロスコープについて。かるく中身を説明したうえで実際に動かしたら大ウケ。名古屋ではたまたまその日に返してもらったトロンボーンをつかって実演。さらにペアプロ合コンのためにつくったとゲスいネタをひきだしてだめ押し。

合コンは置いといて、実際にものを動かすLTは強いなと。ハードウェアという飛び道具をあやつってネットとリアルをつなぐ、つないだ様子を間近で見えるプレゼン。こういう方向でのプレゼンを繰り広げるエンジニアはあまりいないと信じて、今年は活動していきたいと思います。

2012年3月5日月曜日

EventMachineとHTML5でつくる、Arduino用なんちゃってオシロスコープ

HTML Fake Oscilloscope
Arduinoのアナログ入力で読んだ電圧の表示用に、HTMLでオシロスコープをつくってみたよ。

ソースはこちら→niccolli/FakeScope · GitHub

仕組み

  1. Arduinoからmillis()とanalogRead()の値をシリアル通信で出力
  2. RubyのEventMachineで読み込み、WebSocketで配信
  3. HTMLでグラフに描画
EventMachineでのシリアル通信にem-serialportを、WebSocketにem-websocketを使っています。HTMLのグラフ描画は直でCanvas……とも思ったのですが、flotr2というちょうキレイなグラフの描けるスクリプトにおまかせしています。

Piezo Mike Shield with LM386
Arduinoのほうは値を出力するならなんでもよいのですが、ただのサイン波ではおもしろくないので、指パッチンのときに使った回路を使っています。ブレッドボードからユニバーサル基板に進化しました。

動かしてみた

赤く見切れているものはトランペットです。マイクでトランペットのベルの振動を拾い、Arduino上のシールドで増幅。それをanalogReadで読んだものを表示させています。そこそこぬるぬるしてるよね。

やり残していること

  • 重い
    flotr2などはiOSでも見られる・使えるもののはずなんだけど、MobileSafariでは最終的に固まります。
  • 波形がとぶ
    これはem-serialportのような。このシリアル通信ライブラリはバッファリングがないので、その部分だけ自前で実装しています。このシリアル通信のデータをみていると、ちょっと信用おけない感じがするのです。
  • サンプリング周期が粗い
    これはArduino。loop()のなかでdelay()などを使ってはいないのですが、loop周期が数msなのでus/ns級の波形はたぶん見られません。ここはもう本物のオシロスコープを買えってことかな。
    追記:loop周期の問題ではなく、シリアル通信のボーレートの問題でした。ボーレートを全開にすれば早くなりますが、Ruby側で落とすぶん(上の問題)が増えているようです。

「Rubyつかってみろ」ってことでEventMachineをつかったおもちゃをつくったつもりだったけど、肝心のRuby分はうっかりすくなめ。なんかこう充実してた気がしてたのは、初めてだったからかな。

2012年3月4日日曜日

em-serialport:EventMachineでシリアルポートをつかう

急遽「おまえ、Rubyやれるのか!やれんのか!」的な話が来たのをいいことに、RubyのEventMachineであそんでいます。おれがイベント駆動。イベント駆動といえばArduino。Arduinoが出すなんらかの値はシリアル通信でうけとるのが楽なので、EventMachineでシリアル入力をトリガーにするためのライブラリem-serialportを使ってみます。

例:シリアルポートでうけた値をターミナルに表示させる

#!/usr/bin/env ruby
require 'em-serialport'

#serial = EventMachine.open_serial('/dev/tty.usbserial-A6008iDi', 9600, 8, 1, 0) 

EM.run do
    serial = EM.open_serial('/dev/tty.usbserial-A6008iDi', 9600, 8, 1, 0)

    serial.on_data do |data|
        print data
    end
end

requireはem-serialportのみ。require 'eventmachine'もつけると、名前の衝突かなにかでえエラーがでます。

open_serialの引数は順にシリアルポート名、ボーレート(もちろんスケッチに書いてあるものを)、データビット長、ストップビット、パリティの有無になっています。特に気にするのは前2つで、後ろは基本このままで大丈夫そうですね。4行目に同じものがコメントアウトになっていますが、ここでメソッドを呼び出すとダメみたいです。ループのなかにあるような感じが微妙に気持ち悪いんですけど、こういうものということで。

serial.on_dataが受信後に実行するコールバック関数。いまはprintのみを入れて、ターミナルに表示させているだけです。

Rubyはほぼ初めてなんですが、いままで書いたコードは命令のあとにセミコロンが必須のものばかりだったので、セミコロンなしインデント至上主義のコードに若干とまどっています。がしかし、やってみると楽しいものね。

注意

on_dataの引数で入ってくる値は、シリアルポートで受けた値がバッファを通すことなく直接入ってきます。上の例のようにそのままターミナルに吐き出す場合はよいのですが、値を拾ってスクリプト内でどうこうとなるとバッファに取り込んだうえで改行(\r\n)をめどに分割する必要があります。