追記
WebSocket用のミドルウェアがDiscordで公開されていましたので、最新のソフトウェア(Gemini)でもWebSocket通信(with leapjs)ができることを確認しました。そちらもあわせてお読みください。
ULTRALEAP(leapmotion)のV5(Gemini)&(Win11 or Mac)でもWebSocketが使えたよ〜🎉 - memorandums
はじめに
卒業研究で頑張っている学生さんを支援する目的で、私も調査したメモになります。動かすまでにハードルが色々あって。。。こりゃ大変でした。とりあえず色々な方のWebに公開してくれた情報のおかげで動かすことができました。leapmotionがいつまでレガシーアプリを公開しているかによりますね。。。僕はとりあえず保存しておきました。Mac版はもうリンク切れ(というかHerokuのアプリエラー)でダウンロードできませんでした。インターネット・アーカイブにもなくて。。。このアプリがないせいで、WebSocketを使う方式ではもうMacではLeapMotionは使えません。
手順
まず、WindowsにLeapMotionのレガシーアプリをいれます。これがいつまで公開され続けるかが微妙です。とりあえずこの版でWindows11で動作しますので、とりあえず自分用に保存しておいた方がよいと思います。新しいアプリでは私がトライした限りではWebSocketは動作しないようです。たぶんですが。。。
ZIPを解答してインストールしてください。WindowsPCにLeapMotionを接続してインストールしたアプリを起動します。タスクトレイにLeapMotionコントローラ(バッテリーのようなアイコン)が出てきますのでクリックすると設定画面が出てきます。そこの全般を選択して「Webアプリケーションを許可」をチェックしApplyを押します。これでLeapMotionは準備完了です。一応、動作確認のためタスクトレイのLeapMotionコントローラアイコンを右クリックしてビジュアライザを起動して手が映ればOKです。
続いて、LeapMotionをp5jswebeditorで動作確認してみます。参考にさせていただいたのはいつもお世話になっている@youtoyさんの記事です。
HTMLに以下の2行を追加して。
<script src="https://cdn.jsdelivr.net/npm/leapjs@1.1.1/leap-1.1.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/leapjs-plugins@0.1.12/main/leap-plugins-0.1.12.min.js"></script>
sketch.jsに以下を書けば動くはずです。やっているのは3本の指の角度(内積)を取ってその値を画面に反映している感じです。この辺(leapjs)のAPIの仕様は特にドキュメントがないので、GitHubで公開されているexampleを眺めればライブラリ自体のソースコードまで追わなくてもだいたいいけるはずです。
const controller = new Leap.Controller();
function setup() {
createCanvas(500, 500);
noLoop();
controller.on("frame", function (frame) {
var hand = frame.hands[0];
if (hand){
var dot1 = Leap.vec3.dot(hand.direction, hand.thumb.direction);
var dot2 = Leap.vec3.dot(hand.direction, hand.indexFinger.direction);
var dot3 = Leap.vec3.dot(hand.direction, hand.middleFinger.direction);
var w2 = width / 2;
background(255);
line(w2, 50, w2 + dot1.toPrecision(2) *w2, 50);
line(w2, 100, w2 + dot2.toPrecision(2) *w2, 100);
line(w2, 150, w2 + dot3.toPrecision(2) *w2, 150);
}
});
controller.connect();
}
function draw() {}
とりあえず、ここまででp5jswebeditorとleapmotionが繋がったので、あとはこれにobnizをつけることになります。p5jswebeditorでobnizを動かす記事もぐぐるとまたまた@youtoyさんが記事を書いてくれています。
HTMLに以下を追加します。
<script src="https://unpkg.com/obniz@3.x/obniz.js" crossorigin="anonymous" ></script>
そして、sketch.jsを以下にします。コツとしてはobnizがconnectしてから、LeapMotionのcontroller.onを定義しているところですね。obnizがロードされていない状態で上の方でon定義してもうまくいかないからです。
const controller = new Leap.Controller();
function setup() {
createCanvas(500, 500);
noLoop();
var obniz = new Obniz("OBNIZ_ID_HERE",{local_connect : false});
obniz.onconnect = async function() {
console.log("obniz connected");
controller.on("frame", function (frame) {
var hand = frame.hands[0];
if (hand){
console.log(hand.direction);
// obniz.display.clear();
// obniz.display.print(hand.direction);
}
});
controller.connect();
};
}
function draw() {}
で、さらに、サーボモータの制御をいれたのが以下です。
const controller = new Leap.Controller();
function setup() {
createCanvas(500, 500);
noLoop();
var obniz = new Obniz("OBNIZ_ID_HERE",{local_connect : false});
obniz.onconnect = async function() {
var servo = obniz.wired("ServoMotor", {gnd:0, vcc:1, signal:2});
console.log("obniz connected");
controller.on("frame", function (frame) {
var hand = frame.hands[0];
if (hand){
var dot = Leap.vec3.dot(hand.direction, hand.thumb.direction);
background(255); // デバッグ用
var th = dot.toPrecision(2);
text(th, 50, 100); // デバッグ用
servo.angle(180*th);
}
});
controller.connect();
};
}
function draw() {}
p5jsを知らないとちょっとつらいかもですが、そもそもobnizでサーボを制御するだけなら画面はいらないですが、text関数を使って値を描画しながらプログラミングできるとより複雑なコードを書こうとしたときに役立つと思います。console.logでは見えないですからね。。。
はい、とりあえず、ここまでできたところが以下になります。フィルタリングもしていませんから微妙な動作になっていますが、ゼミ生がやろうとしていることは実現できているはずです。あとは工夫が必要ですね。
ちなみにobnizの開発といえば開発コンソールを使うべきかと思いましたが、LeapMotionと組み合わせたらうまく動作しなかったんですね。。。なので諦めました。
一応、p5jswebeditorのリンクも貼っておきますね。