15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

p5.toioのα版リリースについて

Last updated at Posted at 2020-05-17

サマリ

p5.jsの環境でtoio™のプログラミングを簡単に楽しめるライブラリp5.toioの[α版(v0.5.0)をリリース] (https://tetunori.github.io/p5.toio/dist/0.5.0/p5.toio.min.js)いたしました。https://github.com/tetunori/p5.toio

ブラウザからアクセスするだけで、下記の様なサンプルをすぐに確認・制作できます。
toioのCubeと、p5.js及びp5.toioの多様なライブラリ群を利用することで、今まで画面内に閉じていたプログラミングの表現を簡単に現実世界へと拡張することが出来ます。
芸術作品だけでなく、プロトタイプ作成や、デーリーコーディング、ゲーム制作、小学生からのテキストプログラミングなど色々と使ってみてください。(α版なので、いろいろ制約事項有ります。)

P5 Editorでもすぐに始められますよ!(OpenProcessingは非対応:sob:
P5 Editor: p5.toio basic sample

成果物

minifyした成果物はこちらですが、TypeScriptで書いた元のソースコード群もどうぞ。
※詳細は後述ですがAPI Referenceもあるよ。
いずれもMIT Licenseです。

開発モチベーション

課題

toio™Core Cubeを使って趣味で色々なものを作ってきて、下記の課題を感じています。

  • 手軽に開発できない
    • Node.jsはまだ導入が簡単な部類だが、とはいえ『yarn/npm install実行したのに、なんか動かない』問題でどれだけの人類の心を折ってきただろうか。ほんとの初心者にはつらいと思う。
  • toio™Visual Programmingは手軽だけどスケールしない
    • コピペできない、成果物をシェアしにくい、凝ったロジックを作ると膨大なブロック数になり、メンテは・・・
    • 別途アプリ立ち上げが必要だったり、始めるまでにステップ数が最小ではない
  • 個人的にはWebBluetoothを良く使うが、手続きが多くてしんどい
    • 俺はただ、ランプをつけたいだけなのに、なぜこんなにコード行数必要なのだ?何回Promiseさせるんだい・・・と。
    • ↑WebBluetoothは悪くなく、クラス化していない自分が悪い。
  • toioの制御ライブラリがプリミティブなものしか存在しない。
    • もうMath.atan2の計算したくない。
  • 成果物をシェアするのに、毎回GitHubリポジトリ作るのは面倒だな
  • JSの開発環境に関する知識が周回遅れになってしまっていて、話題についていけないので、モダンな開発手法に再チャレンジしたい

きっかけ

全然別の話題ですが、最近Daily Coding勢のツイートがよくタイムラインに表示されており、P5 EditorOpenProcessingなどのオンラインツールを使って、気軽に楽しそうにプログラミングをし成果物をシェアされていました。
早速僕もp5.jsの勉強がてらOpenProcessingで色々作っては公開する日々を続けてみましたが、これは良い。
本当に気軽だし、p5.jsのライブラリも多いのでエンドレスなやりこみ要素もある。

この手軽さでtoioもプログラミングできないか?と思い、P5 EditorでWebBluetoothを仮実装してみたところうまく動作したので、課題を解決するソリューションを作ってみようと奮起した次第であります。

課題解決の方針

下記を満たす、JSライブラリp5.toioを作成する

  • URLにアクセスするだけで、手軽に始められる、使える、創れる。 ⇒ toio™初心者歓迎
  • P5 Editorで動作する ⇒ URLで作品シェアできる。
  • WebBluetoothでスマホ・PC問わず、広く使える
  • 面倒な処理はぜーーーんぶラップしてAPI提供 ⇒ 『追いかけっこ』すら1行とか。
  • JSのClass, ES6記法, TypeScript, ESLint, Prettier, TypeDoc, Jest, Docusaurus など自分にとって新しい技術領域にチャレンジする。

p5.toioのライブラリ構成

p5.toioは2つのクラスP5tCubeP5tIdから構成されています。
P5tCubeクラスは、キューブを簡単にコントロールするためのたくさんのAPIやユーティリティを提供します。詳細はP5tCube Interfaceでご確認ください。
また、P5tIdクラスは、toio™のマットやカード、ステッカーなどに印刷されているtoio™IDについてのAPI・プロパティ群となっています。こちらも、P5tId Interfaceをご参照ください。

なお、今回説明した2クラスはp5.jsに特化する形でライブラリ化していますが、この2つのクラス以外は通常のWebBluetoothでもほぼ同等の機能が使用可能なので、そちらもぜひご利用ください。

使い方

動作環境

toio™Core Cube

少なくとも1つは必要です。最近単売が始まったので、お手軽に導入できますね。Chargerも忘れずに!
また、本ライブラリを使う際は、スマホアプリから最新のFWへアップデートを御願いします

PC環境

本ライブラリはWebBluetoothへ依存しているため、下記の環境での動作となります。

  • OS: Windows, MacOS, Android。iOS/iPadOSは非サポート。
  • Browser: Google Chromeを強く推奨。

また、P5 Editorでは動作確認できていますが、OpenProcessingは残念ながら、動作出来ませんでした。(iFrameでSketchが動く都合、WebBluetoothに必要なユーザーアクションが不正と判断されるため)

ライブラリのインポート

<head>の中で、2つのp5.jsスクリプトp5.jsp5.sound.min.jsの後に、1行読み込んでください。

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/addons/p5.sound.min.js"></script>

<!-- INSERT HERE -->
<script src="https://tetunori.github.io/p5.toio/dist/0.5.0/p5.toio.min.js"></script>

Minifyする前のライブラリも一応あるので、そちらでもOKです。

<script src="https://tetunori.github.io/p5.toio/dist/0.5.0/p5.toio.js"></script>

スケッチで使う

1. Cubeと接続しよう

API P5tCube.connectNewP5tCube()をコールして、Promiseresolveされた、P5tCubeインスタンスを受け取ってください。これだけで、すべてのAPIにアクセス可能です!簡単!
なお、このAPIはWebBluetoothに依存しておりますので、接続の処理は必ず、ユーザーアクションの関数mouseClicked()keyPressed()などで実施してください。さもなくばエラーが出てしまいます。

const gCubes = [];

function mouseClicked() {
  P5tCube.connectNewP5tCube().then( cube => {
    // 'cube' is an instance of connected toio™Core Cube.
    // Now you can call any API!
    gCubes.push( cube );
  } );
}

P5 Editor Sample 1: Turn Light On

2. APIを発行しよう

使用例 1: ランプを点灯する

P5tCubeインスタンスがあれば、API発行は簡単です。
得られたインスタンスがcubeだとして、ランプを白につけてみましょう。

// Turn the light on with white
cube?.turnLightOn( 'white' );

Done. これだけ。
P5 Editor Sample 1: Turn Light On

こんな感じで、全ての機能にアクセスできますので、詳しくは、下記のTypeDoc API Referenceを参照してください。後日、ちゃんとした説明のドキュメント作成します。 (2020/05/23更新済)

使用例 2: MIDI メロディーを再生する

// Play sequence C-D-E
cube?.playMelody( [ 
  { note: 0x3C, duration: 0x1E }, 
  { note: 0x3E, duration: 0x1E }, 
  { note: 0x40, duration: 0x1E } 
] );

P5 Editor Sample 2: Play MIDI melody

使用例 3: マウスのX座標の方を向く

複数のキューブをtoioCollectionの土俵マットの右上においてください。複数のキューブがマウスのX座標の方を追いかけて回転します。

// Keep on gazing at mouse point
for( const cube of connectedCubeArray ){
  const x = Math.floor(mouseX * 300 / windowWidth + 200);
  const y = 144;
  const speed = 115; 
  cube?.turnToXY( x, y, speed );
}

P5 Editor Sample 3: Keep on gazing at mouse point

使用例 4: 2つのキューブのインタラクション

2つのキューブをtoioCollectionの土俵マットの上においてください。

// Keep on gazing at the othre Cube
const speed = 115;
cubeP?.turnToCube( cubeQ, speed );

P5 Editor Sample 4-1: Keep on gazing at the other Cube

// Keep on chasing the othre Cube
const moveType = P5tCube.moveTypeId.withoutBack;
const speed = 80;
cubeP?.moveToCube( cubeQ, speed, moveType );

P5 Editor Sample 4-2: Keep on chasing the other Cube

使用例 5: カラータイルのマット

キューブをtoioCollectionのカラータイルマットの上においてください。

  // Set background color with touched colored tile on mat
  const color = P5tId.ColorTileMat.getTileColor(cube?.x, cube?.y);
  background( color );

P5 Editor Sample 5: Change background color with touched mat color

3. Eventを受信しよう

本ライブラリでは、各種通知の取り扱い方法として、addEventListenerと、p5.jsっぽいコールバック関数の定義(mouseClicked()keyPressed()等と一緒)の両方をサポートしております。

使用例 6: addEventListner

// Button press event
const type = 'buttonpress';
cube?.addEventListener(type, ()=>{
  console.log(type);
});
// Posture change event
const type = 'sensorposturechange';
cube?.addEventListener(type, (posture)=>{
  console.log(type, posture);
});

P5 Editor Sample 6: addEventListner

使用例 7: コールバック関数定義

もしこれらの関数が定義されていたら、通知が発生次第コールバックされます。

const cubePositionIdChanged = (info) => {
  console.log('cubePositionIdChanged!', info);
}

const cubeStandardIdChanged = (info) => {
  console.log('cubeStandardIdChanged!', info);
}

P5 Editor Sample 7: Callback definition

以下に全てのコールバック関数定義をリストアップします。

const onButtonPressed()
const onButtonReleased()
const onBatteryLevelChanged(batteryLevel: number)
const onFlatChanged(flat: boolean)
const onCollisionOccurred()
const onDoubleTapped()
const onPostureChanged(posture: string)
const onPositionIdChanged(info: positionIdInfo)
const onStandardIdChanged(info: standardIdInfo)

Tips

パフォーマンスを上げるには

CubeのAPIコールにはasyncを使おう

もちろんPC環境にもよりますが、Cubeへのコマンドとp5.js上の描画処理等をシーケンシャルに動かすと両方のパフォーマンスが落ちてしまうことが多いです。
そのため、それほど高いフレームレートを要求しないCubeのAPI発行はは下記の様に非同期関数としてもらえると、全体のパフォーマンスが向上します。

function draw() {
  // Cube control command with async
  asyncCubeControl();

  // Then code your sketch...
  ellipse( mouseX, mouseY, 20, 20 );
}

async function asyncCubeControl() {
  // Cube control.
}

フレームレートあげる

このライブラリでは、僕のプアなPC環境でも満足に動くように、WebBluetooth経由のAPI発行レートを15fpsに抑えています。(どんなに早く発行しても、15fpsを超えるものは破棄される)
そのため、位置情報の追従などは、若干精度に問題があるように感じるかたもいらっしゃると思います。そんなときはCubeのフレームレートを変更(上限30fps)してあげると、パフォーマンス向上する場合がありますので、お試しください。新しいMacBookなどではめっちゃ改善しますよ。

cube?.setFrameRate(30);

わかっている問題点

特定のWindows環境でのみですが、moveToMulti APIが、3位置以上の指定をするとエラーが出てしまっています。Mac等では問題ない。

制約事項

p5.toioはまだα版(0.5.0)のため、テストコードや詳細なAPIの説明資料、豊富なサンプル等が内包されていません。また、API仕様も改変する可能性もありますので、ご了承くださいませ。
次回のβ版(0.8.0)ではそのあたりも改善したものにする予定ですので、ご期待してお待ちください。

Enjoy!!!

15
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?