• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Web socketドロンくん その後-
 

Web socketドロンくん その後-

on

  • 1,192 views

nodejsを利用し、マイコンを使わずにモータで動くおもちゃを遠隔制御してみる実験。

nodejsを利用し、マイコンを使わずにモータで動くおもちゃを遠隔制御してみる実験。

Statistics

Views

Total Views
1,192
Views on SlideShare
1,192
Embed Views
0

Actions

Likes
2
Downloads
3
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Web socketドロンくん その後- Web socketドロンくん その後- Presentation Transcript

    • WebSocketドロンくん~その後~『Webアプリによるフィジカルコンピューティング』SAKURAボードユーザ会 あなたの心もSAKURA色 葉桜の木の下de交流会2013/4/4Yuuichi Akagawa
    • 自己紹介• Yuuichi Akagawa (あかがわ ゆういち)• USBホストネタ大好き• 本業は某SI企業でインフラ担当• 電子工作やプログラミングは趣味での活動• 仕組みを知ることが好きなので、最終的な作品に至ることがほとんど無いCopyright©2013 Yuuichi Akagawa 2
    • OSC2012東京Fallで発表しましたCopyright©2013 Yuuichi Akagawa 3• WebSocket(Node.js + Socket.IO)を利用した遠隔制御の実験• Webアプリでフィジカルコンピューティングという提案• みんなBluetoothでやってるからちょっと斜めで• 当初はAndroid側をアプリとして実装したものの、後にJavaScriptのみでイケるということに気付く• 実用性よりも「ネタ」を重視で• 昨年の東京Node学園祭2012に出せればウケたのに
    • ちょっとおさらいCopyright©2013 Yuuichi Akagawa 4
    • WebSocketとは• リアルタイムWeb– 現在多く利用されている、XMLHttpRequest(XHR)によるAjaxポーリングやCometを代表とするロングポーリングではTCPハンドシェイクが都度発生したりHTTPコネクションを長時間占有するなど、Webサーバの負荷が高いという欠点がある。– これを解決するためにHTML5の一部としてブラウザから直接TCP接続を実現する独自プロトコルの策定が始まった。(現在はHTML5とは独立。RFC6455)– 2011年末にようやく仕様確定し、メジャーなブラウザでは問題無く利用できる状況にある。Copyright©2013 Yuuichi Akagawa 5
    • 主要ブラウザのWebSocketサポート状況プラットフォーム ブラウザ バージョンDesktop OS Internet Explorer 10以上Firefox 6以上Chrome 14以上Safari 6以上Opera 12.1以上Android 標準ブラウザ 未サポートChrome 18以上Firefox 7以上Opera mobile 12.1以上iOS Safari 6以上Copyright©2013 Yuuichi Akagawa 6ほぼどれでも使える。Android版ChromeはOSが4.0以上で無いと動作しないが、Firefoxであれば2.2以上で使えるので、なんとかなるかと。
    • Node.jsとは• サーバサイドJavaScript実行環境http://nodejs.orgGoogle V8 JavaScriptエンジン採用シングルスレッド(JavaScriptだもんね)イベント駆動(非同期)モデルnvmというバージョンマネージャやnpmというパッケージマネージャが揃っているサーバサイドもJavaScriptでコードが書けるのは素敵だと思うCopyright©2013 Yuuichi Akagawa 7
    • Socket.IOとは• クロスプラットフォームリアルタイムWebライブラリhttp://socket.ioNode.js用のライブラリサポートプロトコルWebSocketが使えないブラウザでもXHR等に自動フォールバック• WebSocket• XHR• Flash Socket• JSONP PollingCopyright©2013 Yuuichi Akagawa 8
    • Copyright©2013 Yuuichi Akagawa 9WebSocketドロンくんドロンくんとは今岡通博氏考案のAndroid端末による音声認識ロボット。http://www.ospn.jp/press/20110516no10-useit-oss.htmlDTMFによる制御や、ブレッドボードで回路を実装するというお手軽構成。今回は音声認識の代わりにWebSocket経由でコントロールできるようにしました。
    • Copyright©2013 Yuuichi Akagawa 10DTMF (Dual-Tone Multi-Frequency)• 説明するまでもないとは思いますが、電話の「ピ・ポ・パ」ってやつです• 正式には「ITU-T勧告Q.24」• これを4bitのI/Oとして取り出すDTMFデコーダを活用する(2個 ¥300)高群(Hz)1209 1336 1477 1633低群(Hz) 697 1 2 3 A770 4 5 6 B852 7 8 9 C941 * 0 # D
    • DTMFモータドライバ回路図Copyright©2013 Yuuichi Akagawa 11
    • ブレッドボードにちょうど載る規模Copyright©2013 Yuuichi Akagawa 12
    • Copyright©2013 Yuuichi Akagawa 13コマンド送信HTML5 ready Web Browser(スマホのブラウザでもOK)Socket.IO moduleEC2コマンド配信(ブロードキャストも可能)プロトコルはWebSocketorXHR(Ajax)DTMFNode.js + Socket.IOを利用したWebSocketによる遠隔制御DTMFデコーダ+モータードライバDTMF_0.ogg...DTMF_#.oggFirefoxvar audio = new Audio(“/sounds/”+file);audio.play()DTMF音声ファイルダウンロード
    • サーバサイドコード例Copyright©2013 Yuuichi Akagawa 14var express = require(express‘) , routes = require(./routes);var app = module.exports = express.createServer();// Configurationapp.configure(function(){app.set(views, __dirname + /views);app.set(view engine, jade);app.use(express.bodyParser());app.use(express.methodOverride());app.use(app.router);app.use(express.static(__dirname + /public));});app.configure(development, function(){app.use(express.errorHandler({ dumpExceptions: true, showStack:true }));});app.configure(production, function(){app.use(express.errorHandler());});// Routesapp.get(/control, function(req, res) {res.render(control, {title:Socket.IO Control});});app.get(/recv, function(req, res) {res.render(recv, {title:Socket.IO Receiver});});// Socket.IOvar io = require(socket.io).listen(app);var chats = [];var sockets = {};// broadcast functionfunction broadcast(method,message) {for (var n in sockets) {sockets[n].emit(method,message);}chats.pop;}io.of(/in).on(connection, function(socket) {sockets[socket.id] = socket;socket.on(control.add, function(data) {data.time = Date.now();chats.push(data);broadcast(control.add, data);});socket.on(disconnect, function() {delete sockets[socket.id];});});app.listen(8001);app.jsこれだけでWebサーバとして動作する。ここがサーバ実装部分・コネクション受付・データ受信・データ配信全部やってる。fork()とかpthread_create()とかなにそれって感じ。
    • 操作画面ページコード例Copyright©2013 Yuuichi Akagawa 15script(src=http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js)script(src=/socket.io/socket.io.js)script(type=text/javascript)// add chat logfunction addlog(data) {var date = new Date(data.time);console.log(date);$(li#log).replaceWith( <li id="log"> +data.cmd+ ( + date.getHours() + : + date.getMinutes()+ : + date.getSeconds() + )</li>);}var socket = io.connect(http://example.com:8001/in);socket.on(control.add, function(data) {addlog(data);});function send(data) {socket.emit(control.add, {cmd:data} );return false;}h3 WebSocketドロンくんdivtabletrtdinput(type=button,class=btn,value=FwdL, onClick=send(1))tdinput(type=button,class=btn,value=Forward, onClick=send(2))tdinput(type=button,class=btn,value=FwdR, onClick=send(3))trtdinput(type=button,class=btn,value=Turn L, onClick=send(4))tdinput(type=button,class=btn,value=Stop, onClick=send(5))tdinput(type=button,class=btn,value=Turn R, onClick=send(6))trtdinput(type=button,class=btn,value=BkL, onClick=send(7))tdinput(type=button,class=btn,value=Back, onClick=send(8))tdinput(type=button,class=btn,value=BkR, onClick=send(9))divulli#logviews/control.jadeExpress(Webフレームワーク)+ Jade(テンプレートエンジン)を利用。※http://example.com:8001/controlにアクセスするとこれを返す。
    • 制御用ページコード例Copyright©2013 Yuuichi Akagawa 16script(src=http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js)script(src=/socket.io/socket.io.js)script(type=text/javascript)//DTMF mapvar DTMFtable = [];DTMFtable[1] = 4;DTMFtable[2] = 5;DTMFtable[3] = 1;DTMFtable[4] = 6;DTMFtable[5] = D;DTMFtable[6] = 9;DTMFtable[7] = 8;DTMFtable[8] = 0;DTMFtable[9] = 2;//DTMFaudiovar DTMFaudio = null;var SOUND_PATH = "/sounds/";// Get supported sound formatvar AUDIO_EXT = (function(){var audio = new Audio();var ext = "";if (audio.canPlayType("audio/ogg") == maybe) { ext="ogg"; }return ext;})();//Sound playvar play = function(tone) {// Get Filenamevar name = DTMF_ + DTMFtable[tone];var file_path = SOUND_PATH + name + . + AUDIO_EXT;if(DTMFaudio != null){DTMFaudio.pause();DTMFaudio.currentTime = 0;DTMFaudio = null;}DTMFaudio = new Audio(file_path);DTMFaudio.play();};//Sound playvar play = function(tone) {// Get Filenamevar name = DTMF_ + DTMFtable[tone];var file_path = SOUND_PATH + name + . + AUDIO_EXT;if(DTMFaudio != null){DTMFaudio.pause();DTMFaudio.currentTime = 0;DTMFaudio = null;}DTMFaudio = new Audio(file_path);DTMFaudio.play();};var socket = io.connect(http://176.34.45.101:8009/in);socket.on(control.add, function(data) {play(data.cmd);});function send(data) {socket.emit(control.add, {cmd:data} );return false;}h1 HTML5 Delonkunviews/tank.jade ※http://example.com:8001/tankにアクセスするとこれを返す。
    • 今後の予定• Android端末側Android端末のカメラの画像をWebSocketで送信して操作画面に表示したい。音声ファイル再生ではなく、Web Audio APIで自力発音したい。• サーバ側スクリプト操作側と操作される側のペアリングを実現したいCopyright©2013 Yuuichi Akagawa 17
    • で、それから半年が過ぎた。Copyright©2013 Yuuichi Akagawa 18
    • 要素技術の動向• WebRTC (getUserMedia)Desktop OSでのサポート状況はまずまずAndroidではChromeβとOpera mobileで利用可能• Web Audio APIDesktop OSのサポート状況はまずまずAndroidでは未だ使えないiOSのSafariではサポート→DTMFダイヤラの実装例あり!Copyright©2013 Yuuichi Akagawa 19
    • 主要ブラウザのサポート状況プラットフォーム ブラウザ WebScoketAudioのAutoPlayWebRTCgetUserMediaWeb Audio APIDesktop OS Internet Explorer ○ ○ × ×Firefox ○ ○ ○ ×Chrome ○ ○ ○ ○Safari ○ ○ × ○Opera ○ ○ ○ ×Android 標準ブラウザ × × × ×Chrome ○ × △ ×Firefox ○ ○ × ×Opera mobile ○ × ○ ×iOS Safari ○ × × ○Copyright©2013 Yuuichi Akagawa 202013/4/3現在
    • 主要ブラウザのサポート状況プラットフォーム ブラウザ WebScoketAudioのAutoPlayWebRTCgetUserMediaWeb Audio APIDesktop OS Internet Explorer ○ ○ × ×Firefox ○ ○ ○ ×Chrome ○ ○ ○ ○Safari ○ ○ × ○Opera ○ ○ ○ ×Android 標準ブラウザ × × × ×Chrome ○ × △ ×Firefox ○ ○ × ×Opera mobile ○ × ○ ×iOS Safari ○ × × ○Copyright©2013 Yuuichi Akagawa 21どちらかが両方サポートされてないと困る。2013/4/3現在○○○××××××
    • モバイルでの対応はもう一息• Desktop OSでは動作可能なレベル• ○が2つ付いてるブラウザが無いんだな• Androidはブラウザ毎にWebRTCかAudio APIのどちらかしかサポートされていない• しかも、Audioのautoplayに対応しているのはFirefoxだけ→その他ブラウザではユーザの介入が必要Copyright©2013 Yuuichi Akagawa 22
    • Chromeβ for Androidに実装してみる• 映像取得処理getUserMedia()でカメラと接続カメラからの映像をCanvasに描画CanvasのデータをtoDataURL()でエンコード上記で取得したデータをそのままWebSocketで送出• 音声再生コマンドに応じて、Audioのsrcにパスを設定autoplay非対応なので、最初だけ再生ボタンを押す必要ありCopyright©2013 Yuuichi Akagawa 23
    • Copyright©2013 Yuuichi Akagawa 24コマンド送信HTML5 ready Web Browser(スマホのブラウザでもOK)Socket.IO moduleさくらのVPSコマンド配信DTMFWebSocketを利用したJavaScriptによる遠隔制御DTMFデコーダ+モータードライバDTMF_0.ogg...DTMF_#.oggChrome for AndroidDTMF音声ファイルはキャッシュマニフェストを利用してローカルに保存キャプチャ画像送信キャプチャ画像配信WebRTCを利用して内蔵カメラからの映像を取得する急激な円安進行により、AWSが割高になったのでさくらのVPSに引っ越し
    • まとめ• JavaScriptだけでなんとか画像配信までできた• なぜか画像がモノクロだけど• ちょっと荷が重いので高レイテンシーだぞ• あと半年くらい待てば、Androidでもフル機能がサポートがされるのではないかと期待• WebRTCがきちんと実装されれば、WebSocetではなくStreaming APIで滑らかな映像配信ができるはず• 次回はWeb Audio APIでDTMFもね❤Copyright©2013 Yuuichi Akagawa 25
    • マイコンもコンパイラもいらないWebアプリでフィジカルコンピューティング。*:゜☆ヽ(*’∀’*)/☆゜:。*。Copyright©2013 Yuuichi Akagawa 26
    • おしまいCopyright©2013 Yuuichi Akagawa 27