[mac][js]Myoとhueを使って腕の動きに合わせて照明をつけたり、消したりしてみる


ジェスチャー操作が可能になる「Myo」というデバイスが家に転がっていたので、「hue」と組み合わせて、腕の動きに合わせて照明をつけたり、消したりしてみました。

電気を操る実験

hilotterさん(@hilotter)が投稿した動画 –

Myoとhueの公式ドキュメントのソースを組み合わせることでできたので、手順メモを残しておきます。

1. Myo初期設定

まずはMyoのセットアップから。

公式サイトにアクセスして、「Downloads」から「Myo Connect for Mac 1.0.0」をダウンロードします。

Myo Connectを起動するとチュートリアルが表示されるので、画面に従ってMyoの設定を行います。

チュートリアルが完了すると、ジェスチャーでMacの操作を行うことが可能になります。

ジェスチャーの認識がうまくされない時は、カスタムのキャリブレーション設定を行うこともできます。

「Armband Manager」=>「CALIBRATION」で「Custom Profile」を選択すると、設定画面になります。

myo1

2. MyoのジェスチャーをNode.jsで受け取れるようにする

SDKを使った場合はC++での実装になるようだったので、他の言語でも扱えないかなと思い調べてみたところ、myo.jsというnpmが公式から提供されていました。

ということで今回はNode.jsを使って実装することにしました。

まずはインストール。

npm install myo

myo.jsのドキュメントを見ながらイベント通知を受け取れるようにしてみます。

// myo_sample.js

var Myo = require('myo');

//Start talking with Myo Connect
Myo.connect();

Myo.on('connected', function(data, timestamp){
    console.log('connected!')
});

Myo.on('fist', function(){
    console.log('fist');
});

Myo.on('fist_off', function(){
    console.log('fist_off');
});

Myo.on('fingers_spread', function(){
    console.log('fingers_spread');
});

Myo.on('fingers_spread_off', function(){
    console.log('fingers_spread_off');
});

Myo.on('wave_in', function(){
    console.log('wave_in');
});

Myo.on('wave_in_off', function(){
    console.log('wave_in_off');
});

Myo.on('wave_out', function(){
    console.log('wave_out');
});

Myo.on('wave_out_off', function(){
    console.log('wave_out_off');
});

Myo.on('double_tap', function(){
    console.log('double_tap');
});

Myo.on('double_tap_off', function(){
    console.log('double_tap_off');
});

上記を保存して実行してみます。

この状態でMyoを操作すると、ジェスチャーに合わせてイベントを取得することができます。

node myo_sample.js

fist
fist_off

3. hueをNode.jsで操作できるようにする

続いてはhueの設定です。

hueの場合はnode-hue-apiというnpmを使用するとNode.jsからhuwを操作することができるようです。

ドキュメントを読みながら、まずはローカルネットワークにあるhueのipアドレスを取得します。

// hue_ip.js

var hue = require("node-hue-api");

var displayBridges = function(bridge) {
    console.log("Hue Bridges Found: " + JSON.stringify(bridge));
};

// --------------------------
// Using a promise
hue.nupnpSearch().then(displayBridges).done();

上記を実行します。

node hue_ip.js

Hue Bridges Found: [{"id":"xxxxx","ipaddress":"xxx.xxx.xxx.xxx"}]

これでhueブリッジのipアドレスが分かったので、ブリッジにユーザを追加します。

// hue_bridge.js

var HueApi = require("node-hue-api").HueApi;

var hostname = "xxx.xxx.xxx.xxx",
    newUserName = null // You can provide your own username value, but it is normally easier to leave it to the Bridge to create it
    userDescription = "device description goes here";

var displayUserResult = function(result) {
    console.log("Created user: " + JSON.stringify(result));
};

var displayError = function(err) {
    console.log(err);
};

var hue = new HueApi();

// --------------------------
// Using a promise
hue.registerUser(hostname, newUserName, userDescription)
    .then(displayUserResult)
    .fail(displayError)
    .done();

上記を実行します。

node hue_bridge.js
{ [Api Error: link button not pressed] message: 'link button not pressed', type: 101 }  # hueブリッジの真ん中のボタンを押す

# 再実行
node hue_bridge.js
Created user: "xxxxxxxx"

これでユーザが作成できました。

続いて先ほど取得した、ipアドレスと、ユーザ情報を使ってライト情報を取得します。

// hue_light.js

var HueApi = require("node-hue-api").HueApi;

var displayResult = function(result) {
    console.log(JSON.stringify(result, null, 2));
};

var host = "xxx.xxx.xxx.xxx",
    username = "xxxxxxxx",
    api;

api = new HueApi(host, username);

// --------------------------
// Using a promise
api.lights()
    .then(displayResult)
    .done();

実行するとライト情報が取得できるので、今回使用するライトのIDをメモします。

今回はID3のライトを使用することにしました。

node hue_light.js
{
  "lights": [
    {
      "id": "1",
      "name": "Lounge Living Color",
      "type": "Extended color light",
      "modelid": "LCT001",
      "uniqueid": "00:17:88:01:xx:xx:xx:xx-xx",
      "swversion": "xxxx"
    },
    ・・・・

Node.jsからライトを操作してみます。

ライトをつけて、5秒後に消すようにしてみました。

// hue_light_on.js

var hue = require("node-hue-api"),
    HueApi = hue.HueApi,
    lightState = hue.lightState;

var displayResult = function(result) {
    console.log(result);
};

var displayError = function(err) {
    console.error(err);
};

var host = "xxx.xxx.xxx.xxx",
    username = "xxxxxxxx",
    api = new HueApi(host, username),
    state = lightState.create();

// --------------------------
// Using a promise

// Set the lamp with id '3' to on
api.setLightState(3, state.on())
    .then(displayResult)
    .fail(displayError)
    .done();

setTimeout(off, 5000);

function off() {
  api.setLightState(3, state.off())
      .then(displayResult)
      .fail(displayError)
      .done();
}

これでNode.jsからhueの操作ができるようになりました。

4. Myoとhueを組み合わせる

ここまでで、Myo、hueのそれぞれがNode.js経由で操作可能になったので、最後はMyoとhueを組み合わせてみます。

ソースコードも単にこれまでのサンプルを組み合わせただけになっています。

// myo_hue.js

var Myo = require('myo'),
    hue = require("node-hue-api"),
    HueApi = hue.HueApi,
    lightState = hue.lightState,
    host = "xxx.xxx.xxx.xxx",
    username = "xxxxxxxx",
    api = new HueApi(host, username),
    state = lightState.create();

var displayResult = function(result) {
    console.log('hue success: ' + result);
};

var displayError = function(err) {
    console.error('hue error: ' + err);
};

//Start talking with Myo Connect
Myo.connect();

Myo.on('connected', function(data, timestamp){
    console.log('connected!')
});

Myo.on('fist', function(){
    console.log('fist');
    api.setLightState(3, state.off())
       .then(displayResult)
       .fail(displayError)
       .done();
});

Myo.on('fingers_spread', function(){
    console.log('fingers_spread');
    api.setLightState(3, state.on())
       .then(displayResult)
       .fail(displayError)
       .done();
});

これで上記を実行します。

node myo_hue.js

すると、動画でお見せしたように、グーで照明オン、パーで照明オフにすることができました。

電気を操る実験

hilotterさん(@hilotter)が投稿した動画 –

今回はとりあえずサンプルを組み合わせただけでしたが、ジェスチャーで操作できるのは楽しいですね。

また面白い使い方を見つけたらなんか作ってみようと思います。