0

コミケ88情報

同人誌に参加しました。
1日目(14日、金曜) 東パ-60b 電脳学論の会です。

  • h264のアルゴリズム解説
  • ベイズ統計
  • Arduinoと150円で赤外線学習リモコンを作る

みたいな内容です。



ほぼ売り切れた。
とくに良かったのは、中身見た人のちょうど50%が面白がって買って行ってくれたことで、なんか最近そういう風に褒められるのがなかったのでうれしい。癒やされた。

あと面白かったのが俺と長時間話し込んだ人は全員買わずに去っていく。

0

JavaScript情報の収集

LDRでazuさんのはてブを見たりもしているんだけど、自分JavaScriptガチ勢ではないのと流れが速いのとで追い切れなかったりする。

最近はお風呂で湯船につかっている時にタブレットでmenthasを見てる。
http://menthas.com/javascript

どういうアルゴリズムなのか詳細はよくわからないけど、わりと面白い記事が流れてきてしかもノイズが少ない。内容面白いのに3,4人しかbookmarkしてない記事も流れてきて掘り出し物感もある。

LDRをタブレットで快適に見る方法があればまた違う気もするけど、良い方法が無い

あとmenthasにはRSSもあるのでそっちもLDRに登録して見てる http://menthas.com/javascript/rss

0

Arduino MicroをUSB MIDIデバイスにする

MIDIデバイスを自作し、ブラウザのWeb MIDI APIと通信した。
rkistner/arcoreを使ったら簡単にできた。

もともとLeonardo以降のATMega32U4を使っているArduinoはMPU内にUSB機能が内蔵されていて、その部分もプログラマブルなのでキーボードやマウスにしたりとかできる。

セットアップ


% git clone git@github.com:rkistner/arcore.git
% cd arcore/
% ./install.sh

~/Documents/Arduino/hardware/arcore にシンボリックリンクが貼られる。Arduino IDEを再起動するとターゲットボードが増えてるので選択する。



プログラムを書く


analogReadでセンサーを読んでMIDI channel1にコントロールメッセージを送る。analogReadは10bitだがMIDIデータは7bitなので下3bitを捨てる。
MIDIEventの0x0Bはコントロールメッセージという意味。0xB0は10110000で下4bitの1〜16でMIDIチャンネルを表すので論理和する。(0から始まるので、この場合チャンネル2になる)
3、4番目の引数は7bit(0~127)ならなんでもいい。
void setup() {
}

int an;

void loop() {
an = analogRead(0);
if(MIDIUSB.available()){
MIDIEvent e = {0x0B, 0xB0|1, 10, an>>3};
MIDIUSB.write(e);
}
}

ChromeのWeb MIDI APIがちょうどコントロールメッセージをonmessageイベントで受信できるので、ブラウザからMIDIデバイス化したArduinoのセンサーが読めるようになった。
http://shokai.github.io/WebMidiAPIStudy/dump/

関連:AndroidタブレットでWeb MIDI API


USBシリアル通信と併用もできる。ブラウザにMIDIデータが流れるし、同時にArduino等のシリアルコンソールを開くとそっちにも数値が流れてくる。
void setup() {
pinMode(13, true);
Serial.begin(9600);
}

int an;

void loop() {
an = analogRead(0);
if(MIDIUSB.available()){
MIDIEvent e = {0x0B, 0xB0|1, 10, an>>3};
MIDIUSB.write(e); // MIDI送信
}
Serial.println(an); // シリアル通信からもAD変換器の値を送ってみる

// 動作確認用にLEDを点滅させる
digitalWrite(13, true);
delay(100);
digitalWrite(13, false);
delay(100);
}

0

PlatformIOでArduino開発する

PlatformIOというArduino/mbed/MSP430などに対応したパッケージマネージャ兼ビルドツールをセットアップした。

PlatformIO


http://platformio.org
https://github.com/platformio/platformio

本体はPythonで書かれている。

たしか半年ほど前に気づいたんだけど、githubのArduino関係のリポジトリにlibrary.jsonというファイルを追加するプルリクが大量に送られていた。何だこりゃと思ったらplatformioの中の人が新しいパッケージマネージャ作ったから〜と送りまくっていた。library.jsonはNode.jsのpackage.jsonを参考にしているらしくてだいたい同じ仕様になっている。

地道な努力のおかげかすでに260個もライブラリが登録されている

そもそもArduinoにはパッケージマネージャなどという物は存在していなくてzipでダウンロードしてArduino.appの中に突っ込むという感じだった。ライブラリが簡単にインストールできるだけでもとてもありがたい。library.jsonには別ライブラリへの依存関係も書けるので、単一巨大でモノリシックではない小さなライブラリを作るのも楽になりそう。

ビルドツールとしても、inoと違ってArduino IDEを使わず、ビルド環境をプロジェクトルートのplatformio.iniに基いて自前でセットアップしてくれるので、GitHubにプルリクが来たらCIサービス上でビルドする、とかできるはず。便利そう。


インストール


参考:Installation — PlatformIO 2.2.0 documentation

環境はMac OSX Yosemiteで最初から入っているPython2.7.9を使っている。

% pip install platformio
% pip install --egg scons
これでplatformioコマンドが使えるようになった。
pipはPythonのパッケージマネージャでeasy_installの置き換えとして出来た物らしい。


プロジェクトを作る


その前にターゲットのマイコンボードを確認しておく。Arduino Microでやりたいので
% platformio boards | grep -i micro

たくさん出てきた。Blend Microもある。他にDigisparkやTIのMSP430等もあった。

micro atmega32u4 16Mhz 28Kb 2Kb Arduino Micro
168pa16m atmega168p 16Mhz 15Kb 1Kb Microduino Core (Atmega168PA@16M,5V)
168pa8m atmega168p 8Mhz 15Kb 1Kb Microduino Core (Atmega168PA@8M,3.3V)
328p16m atmega328p 16Mhz 31Kb 2Kb Microduino Core (Atmega328P@16M,5V)
328p8m atmega328p 8Mhz 31Kb 2Kb Microduino Core (Atmega328P@8M,3.3V)
32u416m atmega32u4 16Mhz 28Kb 2Kb Microduino Core USB (ATmega32U4@16M,5V)
1284p16m atmega1284p 16Mhz 127Kb 16Kb Microduino Core+ (ATmega1284P@16M,5V)
1284p8m atmega1284p 8Mhz 127Kb 16Kb Microduino Core+ (ATmega1284P@8M,3.3V)
644pa16m atmega644p 16Mhz 63Kb 4Kb Microduino Core+ (Atmega644PA@16M,5V)
644pa8m atmega644p 8Mhz 63Kb 4Kb Microduino Core+ (Atmega644PA@8M,3.3V)
blendmicro16 atmega32u4 16Mhz 28Kb 2Kb RedBearLab Blend Micro 3.3V/16MHz (overclock)
blendmicro8 atmega32u4 8Mhz 28Kb 2Kb RedBearLab Blend Micro 3.3V/8MHz
uview atmega328p 16Mhz 31Kb 2Kb SparkFun MicroView
sparkfun_promicro8 atmega32u4 8Mhz 28Kb 2Kb SparkFun Pro Micro 3.3V/8MHz
sparkfun_promicro16 atmega32u4 16Mhz 28Kb 2Kb SparkFun Pro Micro 5V/16MHz


ディレクトリを作ってinitする

% mkdir tmp
% cd tmp/
% platformio init --board micro
–boardオプションは複数指定できるらしい。
ビルド成功後に自動的にボードに書き込むか質問される。yesにしておいた。


コードを書く

src/にあればファイル名は何でもいいっぽい

src/main.ino
void setup(){
pinMode(13, true);
}

void loop(){
digitalWrite(13, true);
delay(500);
digitalWrite(13, false);
delay(500);
}


ビルド

% platformio run
最初にrunした時、Arduinoのビルド環境を自動でセットアップしはじめる。すぐ終わる。
~/.platformio/ に保存されていて、 .pioenvs/ にコピーされる。

ビルド成功すると自動的にArduino Microに書き込まれてプログラムが動き出す。この設定は platformio.ini に書かれている。

自動アップロードを無効にしている場合はtargetにupload指定でできる。
% platformio run --target upload

逆にアップロードしない場合は
% platformio run --target ./
もともと–targetはビルドするソースコードがあるディレクトリを指定するオプションみたいだけど、uploadが指定された時だけカレントディレクトリをビルドしてArduinoに書き込むらしい。あとclean指定で中間ファイル削除とか。なんか実装がやっつけっぽい?


ビルド環境


今使っているビルド環境の情報はplatformsコマンドで確認できる
% platformio platforms list
% platformio platforms show atmelavr


ライブラリのインストール


ArduinoをMIDIデバイス化してみたかったので、何か無いか探してみる
% platformio lib search midi
% platformio lib install 62
ライブラリは通し番号で管理されているらしい。名前が重複しても良いようにする為か?

これをインストールしてみた。
http://platformio.org/#!/lib/show/62/MIDI

いきなり src/main.ino 内で #include <MIDI.h> と書いて使えた。
でもこのライブラリはデジタルIOをMIDI化する物だったので、欲しかったのとちょっと違う。
まあとりあえずライブラリのインストールが一発でできて、すぐ使える事がわかった。


気になる事

ライブラリは ~/.platformio に保存されてグローバルに使われる。プロジェクト毎にどのライブラリのどのバージョンを使っているかを記録する仕組みが無いみたい。
プロジェクト毎に使用ライブラリのバージョンを固定して、別のマシンでも同じライブラリを一発でインストールできるようになってないと、あるプロジェクトでupdateをかけたら別のプロジェクトがビルドできなくなったりするので良くないと思う。
ライブラリ作者も、後方互換性が無いアップデートができないので実装速度が落ちる。

ライブラリを公開する時にメタデータを書くlibrary.jsonには別ライブラリをdependenciesプロパティで指定できるみたいなので、たぶんそのうちplatformio initで作ったプロジェクトにも依存解決機能が付くと思う。

まあ現状でもinoと同等の機能を持っていて、Arduino IDEに依存してない分だけinoより良さげ。

0

ES6の勉強をした

Web DB Press vol.87のES6の特集を読みながら、ES6を勉強した。とてもわかりやすかった。
紹介されている機能をちょこちょこと試す細かいスクリプトを色々書いたりメモを取ったりしたのでまとめておく。色々な機能があった。

https://github.com/shokai/es6-study

最近Web MIDI APIを使ってたんだけど、そのインタフェースがES6のPromiseとfor-ofで回す新しいIteratorとTypedArrayで実装されていたので、今後ブラウザに増える新しいAPIがES6前提で作られるなら普段からES6で書くようにしたほうがいいかなと思った。

個人的にはcoffeeの方がES6よりちょっと好き。でもfor-of文がES6で新しく増えたMapやIteratorを使う時に重要なんだけど、coffeeのfor-of文は別の意味があるので、coffeeからES6のAPIを使うのは辛そうな気がしている。一応IteratorはforEachで回せるけど


ES6の機能メモ

(coffeeとの比較みたいな感想入り)

Promise

非同期処理の新しいインタフェース。ScalaのFutureみたいなやつ。

変数の初期化

var foo = "zanmai";
var bar = "kazusuke";
var obj = {foo, bar};
// オブジェクト初期化省略記法
// {foo: "zanmai", bar: "kazusuke"} というオブジェクトができる

分割代入

var [foo, bar] = ["zanmai", "kazusuke"]; // 配列を配列で受けるとそれぞれ変数に代入できる
[a, b] = [b, a]; // 入れ替えもできる

class構文がある

extendsとかもできる。superで呼び出す
ほぼcoffeeのclassと同じ感じ
static/setter/getterを設定する修飾子がある
 class User extends EventEmitter2{
constructor(name){
super({delimiter: ":", wildcard: true}); // superで継承元を呼び出す
this.name = name; // プロパティを持てる
}
get website(){ // getter設定
return "http://github.com/"+this.name;
}
}
組み込みクラス(Array等)も継承で拡張できる
これまでArrayなどにメソッドを生やしたりすると全体に影響が及んでいたのが解決できる

Arrow Function

 var sum = (a, b) => {
return a + b;
}
functionを=>で書ける
外側のthisが引き継がれる
coffeeの=>と同じ
thisを引っ張ってきたくなければ今まで通りfunctionを使う


Generatorがある

function()*{ yield foo; }
値を複数回返せる機構
returnではなくyieldで返す
Rubyのblock+yieldと同じ

requireのかわりにexport/import

requireの挙動が複雑だったので仕様を直したもの
babelではrequireに変換される
export function foo(){ ~~~~ };
// module.exports.foo = function(){ ~~~ }; と同じ

export default function(){ ~~~ };
// defaultを付けると、module.exports = function(){ ~~~ }; と同じ

import foo from "foo";
// var foo = require("foo"); と同じ

import {EventEmitter2} from "eventemitter2";
// 部分的にrequireできる。var EventEmitter2 = require("eventemitter2").EventEmitter2; と同じ
// coffeeでrequireの左辺に{ }付けた時と同じ挙動

import {aaa, bbb} from "foo";
// 複数の子をまとめてrequireできる
// var aaa = require('foo').aaa;
// var bbb = require('foo').bbb; と同じ
classを1つだけ提供する時は
export default class ClassName { ~~ } で提供し
import className from “ClassName”; で読み込む

ユーティリティ関数を複数提供する時は、exportとimport {name}で部分的に読み込めるようにすると良さそう?

色々と関数が追加されている

String.repeat(num); // 文字列をくり返す
Array.from(obj); // 新規Arrayインスタンス作成
Object.assign(target, source1, source2...); // targetにsourceのプロパティをmix-inする

テンプレート文字列がある

`my name is ${this.name}`
バッククオートで囲う
${}の中が評価される

タグ付きテンプレート文字列

例えば
gyazz`gyazz記法を[[展開]]できる`
と書くと、 gyazz記法を<a href=”./展開”>展開</a>できる
function gyazz(templates, …values){ 処理して文字列を返す }
のような関数を宣言しておけば使える
`の前に関数名を書いて変換器を指定する
function gyazz(templates, ...values){
console.log("---gyazz markup start---");
var reg = /\[{2}([^\[\]]+)\]{2}/g;
var str = "";
for(var i = 0; i < templates.length; i++){
str += templates[i] || "";
str += values[i] || "";
}
if(!reg.test(str)){
return str;
}
return str.replace(reg, "<a href=\"./$1\">$1</a>");
}

2/8/16進数

0b1010
0xFA
0o70
接頭辞で書ける

デフォルトパラメータ

 var foo = function(name="shokai"){ console.log(name); };
foo("hoge"); // => hoge
foo(); // => shokai
引数なしの時の初期値を設定できる

可変長引数

var foo = function(...bar){ (略) }
barをArrayとして受け取れる
変数名の前に...を付ける
es5では特殊変数argumentsを見なければできなかった
関数宣言時に書けるのでぱっと見わかりやすい
静的解析ツールの支援も受けやすそう

スプレッドオペレータ

[1,2, ...[5,6,7]] // [1,2,5,6,7] になる

// Underscoreのrangeと組み合わせると強い
[..._.range(1,5), 11, 12, ..._.range(20,23)] // [1,2,3,4,5,11,12,20,21,22,23] になる

var [a,b,...c] = [1,2,3,4,5,6,7]; // 分割代入と組み合わせ
// a => 1
// b => 2
// c => [3,4,5,6,7]

定数

 const NAME = "shokai";
NAME = "zanmai"; // 代入できない
console.log(NAME); // => shokai

ブロックスコープ変数

letで宣言する
 if(true){
let name = "shokai";
console.log(name); //=> shokai
}
console.log(name); // name is not defined
for(let i = 0; i < 10; i++){ // varで宣言すると全部10になる
setTimeout(function(){
console.log(i); // 1,2,3,4,5,6,7,8,9,10
});
}
letがあるので、coffeeのdo (args) -> が必要なくなる


イテレータ

for(let i of arr){ console.log(i); }
// MapやSetはkey, valueで回せる
for(let [k,v] of map){ }

TypedArray

型付き配列
var arr = new Uint8Array(8); // 8bit型
arr[0] = 256; // これは8bit超えてるので代入されない。例外は発生せず代入処理だけが実行されない
arr[1] = 255; // 代入できる
WebGLやWebMIDIなど大量のデータを処理する時に速い
Nodeのbuffer由来
length等いくつかのプロパティが無い
Arrayに変換すればok
var arr2 = Array.prototype.slice.call(arr);

Proxy

Rubyのmethod missingと同等の事ができる
現状Firefoxでしか動かない?


実行環境・ツール


ES6をそのまま実行できる環境


ローカルで実行するちょっとしたスクリプトとかだと、いちいちコンパイルせずにES6のまま実行できると良い

Chrome
だいたいそのままes6が動く
Arrow Function以外
Chrome拡張とか作るならいきなりES6で書いても良さげ

Firefox
だいたいそのままes6が動く
Proxyもたしか動くはず
classが無い

Node.js
0.12なら--harmonyオプションを付けるとes6が実行できる
rest parameterやspread operatorが使えない

iojs
class, Generatorなど多くの機能をサポートしてる
--harmonyオプションを付ければもっと色々使える
--harmony_rest_parametersや--harmony_arrow_functionsなども必要に応じてONにできる
サーバーで実行するならiojsで良さそう。herokuでもengine指定すれば使える

babel/register
babelに含まれているpolyfill
ブラウザでもサーバーでも動くのでわりと良さそう
プログラムの頭で
require("babel/register")();
しておくと、以後ES6コードをrequireするとふつうに実行できる
Nodeのrequire関数がフックされて拡張されるらしい
最初のregisterするファイルにはes6を書けない、syntax errorになる
Node0.10でもfor-of文が動かせる

babel-node
babel付属の実行コマンド
es6を直接実行できる
Node0.10でもfor-of文が動かせる

osascript
MacのAppleScript実行コマンドだったが、YosemiteでJavaScriptでも書けるようになった。ES6が一部サポートされている。
分割代入とspread operatorとMapとSetが動く。
Promiseはオブジェクトはあるけど呼び出すとエラーが返る

ES6をふつうのJavaScript(ES5)に変換するツール


色々なブラウザ環境で実行させるとしたらES5に変換するのが現実的

babel
es6をes5に変換するトランスパイラ
元6to5
node 0.12なら問題なし、node 0.10でもiteraotr系以外動くJSが作れる
ES6でライブラリを書いてnpmに公開するとかにオススメ
新し目のブラウザでの実行もbabelで良さそう

traceur
es6をes5に変換
Google製

Browserify+babelify
es6からブラウザjsに変換、requireを辿って1ファイルに固めてくれるのでnode_modulesも読み込める

lint

ESLint+babel-eslint
es6をlintできる


ES6を実際使う

ES6は各ブラウザでもサポートしている機能としてない機能がバラバラなのでbabelでES5に変換してやるのが良いようだ。
ただ、for-ofのiteratorはbabelで変換すると変換後のコードにSymbol.iteratorが含まれているのでNode 0.10だと動かない。Node 0.12だと動く。

あとProxyはFirefoxでしか動かないっぽい。

色々試した感じ、例えばES6で書いてbabelで変換してからNodeのライブラリとしてnpmで配布する時はfor-ofだけ使わないように意識すれば事故は起こらないはず。
(MapやTypedArrayみたいな新しい組み込み型は使わないとして)


ES6と変換後のES5の動作をブラウザでも手軽に確かめたかったので、ちょっとしたツールを作った。
こんなかんじでgithubに置いてあるES6/ES5が実行できる

Herokuでも動いてて、サーバーはES6で書いてbabel-nodeで実行してる
https://shokai-es6-study.herokuapp.com/