MAGIC WAND

https://github.com/RiTa-23/magic_wand

Next.js

TypeScript

Python

杖を振る&呪文を唱えるで現実世界に魔法を起こす!

RiTa

ひろ

ゆっちん

アリス

推しアイデア

杖を振る&呪文を唱えるで現実世界に魔法を起こす!

作った背景

テーマ「wind or wave」→風魔法、水魔法使おう!

推し技術

YOLO + ONNXでブラウザ上でリアルタイムキーポイント検出! スマートプラグで現実に魔法を起こす!

プロジェクト詳細

概要

Magic Wand は、「音声による呪文詠唱」と「杖のジェスチャー」を組み合わせて、スマートホームデバイスを魔法のように操作する体験型Webアプリケーションです。

ユーザーは魔法使いになりきり、呪文を唱えながら杖を振ることで、部屋の照明や家電を操作できます。音声とジェスチャーの両方が揃った時だけ魔法が発動する仕様により、誤作動を防ぎつつ没入感のある体験を実現しています。

使用技術

速さと安定を求めた技術スタック!

  • devbox で環境構築の手間をゼロ+mac/windows間のトラブルを減らす
  • Bun と oxlint、Vitest を組み合わせて、インストール・チェック・テストの待ち時間を従来の数分から数秒に短縮する

フレームワーク・ランタイム

Next.js (App Router) — Reactフレームワーク TypeScript — 型付き言語 React 19 — UIライブラリ Bun — パッケージマネージャ / ランタイム Devbox — 開発環境管理

開発ツール

Vitest — テストランナー oxlint — Linter Prettier — Formatter GitHub Actions — CI/CD CodeRabbit — AIコードレビュー Babel React Compiler — React最適化コンパイラ

AI/ML・画像認識

Roboflow — 学習データのアノテーション・データセット管理 Python(Google Colab) — モデル学習・開発環境 ONNX Runtime Web — 杖検出モデル推論 (YOLOv8-pose) 独自実装 — ジェスチャー認識(軌跡の方向転換回数ベース)

 mediapipe使ってません!今回はYOLO+ONNXで実装しました。

ブラウザAPI

Web Speech API — 音声認識(日本語) WebHID API — Joy-Con接続 Web Bluetooth API — Phomemo M02Sプリンター接続 getUserMedia API — カメラ映像取得

IoT連携

tp-link-tapo-connect — TP-Link Tapoスマートプラグ制御

使用ハード

Joy-Con(R) スマートプラグ マジカルワンド(USJの杖)

デモ動画

本番実装デモ

実際に杖を振って詠唱をすることで魔法を起こすデモ動画

テスト実装デモ

Joy-Con IRカメラによる杖振り検知デモ

キーポイント検出(YOLO + ONNX)による杖の軌道検出デモ

キーポイント検出(YOLO + ONNX)による杖のジェスチャー判定(V字)

画面UI

タイトル image ホーム image 接続確認 image 接続テスト画面 image image プレイ画面 image image image image チュートリアル image image image image image image 呪文一覧 image
image
image image 設定画面 image

入力方式

image

連携デバイス

image

魔法発動の仕組み(インテントゲート)

image

  1. 音声認識 — 呪文の詠唱を検出・照合(信頼度 ≥ 0.8)
  2. ジェスチャー認識 — 杖の軌跡を判定(信頼度 ≥ 0.7)
  3. 照合 — 呪文に対応するジェスチャーが 7秒以内に揃えば発動
  4. 実行 — TP-Link Tapoスマートプラグの制御 or Phomemoプリンターで印刷

AI/ML・画像認識の実装

最終的に400枚以上の学習データを用意(写真を撮影)し、Roboflowというツールを使用して人力アノテーション作業!!!

自前で学習用データを用意&アノテーションをして、実際にモデル学習をさせたのは初めてでしたが、かなり根気のいる作業でした...

今回はwandのクラス(杖全体)とtip(杖先)とgrip(持ち手)の2点のキーポイントを検出させるキーポイント検出で画像認識の実装をしました。 image image Roboflow作成のデータセットを用いてGoogle Colabでモデル学習させ、ONNX形式でエクスポート image 出力したONNXファイルをONNX Runtime Webを用いてブラウザ上で推論を実行させています image

Joy-Con (R) IRカメラ・IMUセンサーの実装概要

思ったよりJoy-Con IRカメラがしょぼかったので最終的には本番実装には含めませんでしたが、試行錯誤しながらテスト実装頑張ったのでそちらも紹介させてください

Nintendo_Switch_Reverse_Engineering ↑こちらのリポジトリを参考に実装を進めました

WebHID API を使い、ブラウザからJoy-Con (R) のIRカメラとIMU(加速度・ジャイロ)を直接制御しています。

【通信の流れ】 ブラウザ (WebHID API) ←→ Bluetooth HID ←→ Joy-Con (R) ├─ MCU (STM32) → IRカメラ └─ IMU → 加速度センサー + ジャイロスコープ

初期化シーケンス:

  1. navigator.hid.requestDevice() でJoy-Con (R) に接続(vendorId: 0x057e)
  2. IMUを有効化(サブコマンド 0x40)→ レポートモードを 0x31 に設定
  3. MCUをスタンバイ → IRモードに切り替え → IRレジスタ(解像度・露出・LED強度)を書き込み
  4. 50ms間隔のポーリングでIR・IMUデータを同時受信開始

データ受信(レポートID 0x31 の1パケットに全て含まれる):

  • Byte 2-3:ボタン状態(ビットマスクで各ボタンを抽出)
  • Byte 12-23:IMUデータ(加速度XYZ + ジャイロXYZ、各16bit signed LE)
  • Byte 48〜:MCU/IRカメラデータ

IRカメラの2モード:

  • CLUSTERING(0x06):光点の座標・強度・サイズを最大16個検出 → 杖トラッキングに使用
  • IMAGE_TRANSFER(0x07):160×120グレースケール画像を64フラグメントで転送

IMUセンサー:

  • 加速度(accel)・ジャイロ(gyro)の3軸生値をリアルタイム取得

USJの杖は杖の先にある再帰反射材に赤外線を当て、反射した赤外線をIRカメラで捉えることで杖の振りを検知しているらしいです。それを再現したかったのですが、残念ながらJoy-ConのIRカメラでは実力不足でした...

Joy-Con IRカメラによる杖振り検知デモ ↑テスト実装の成果 至近距離であれば動いていることは検知できました。軌道もなんとなくは取れています。

reddit:ハリーポッターの杖のセンサー

杖振り検知における技術の無駄遣いポイント

mediapipeを使えばサクッと終わりそうな杖振り検知(ハンドトラッキングで杖を握っている手をトラッキングするなど)をあえて行わず、ロマンを求めて以下のような実装を行いました ↓

  • わざわざUSJの本家の仕組みを再現したいという理由で赤外線ライト+IRカメラでの杖振りのテスト実装を行った点
    • Nintendo Switch Joy-ConのIRカメラをwebアプリ実装に組み込んでいる先人が見つからず、情報が全然落ちていなかったので実装に苦労しました
  • 上記の実装がIRカメラの実力不足で思ったよりうまくいかなかったが、せっかくなのでJoy-Conを開発に組み込みたかったので慣性計測での杖振り入力も実装
  • しかし、せっかくならUSJの杖を使った実装を行いたい!ということで、ハッカソン本番1日目から学習用データを400枚以上用意し、アノテーション+ハッカソン中に機械学習を行い、yolo + onnxによるキーポイント検出を実装した点

妥協して簡単に実装できる方法がありながら、わざわざロマンとこだわりで上記の3つの杖振り検知の実装を行う技術の無駄遣いをしました!

Iot連携・ハードウェアハックの実装概要

現実で魔法を使えるようになりたい!!!
そんな欲望をかなえるため、Webブラウザと扇風機やグリップライトなどのハードウェアを直接制御するためのIot基盤を構築しました。

Web Bluetoothによるプリンターハック(おみくじ機能)

通常は専用のネイティブアプリからしか動かせないサーマルプリンター(今回使用した機種は、Phomemo M02S)を、ブラウザからWeb Bluetooth APIを叩いて直接制御しています。中間サーバーを一切挟まないモダンな構成にしました!
単にテキストを送るだけでなく、おみくじの結果を動的に<canvas>で合成しています。さらにその画像データを、プリンターが解釈できる1bitのモノクロバイナリ(0と1の配列)にディザリング・2値化変換する処理をTypeScriptでフルスクラッチ実装しました。データをBluetoothのMTUに合わせてチャンク分割し、ESC/POSライクな独自コマンドを付与して送信するという、低レイヤーな制御をWebフロントエンドの技術だけでやり切りました。

スマートプラグ周りの技術の無駄遣いポイント

今回のプロダクトのコア部分はスマート電源タップ(TP-Link Tapo P300)が担っています。このスマート電源タップをプログラムからAPI経由でハックし、「風(扇風機)」「光(クリップライト)」「火(偽の炎ライト)」といった魔法の属性に合わせて、プログラムで指定しているコンセントポートのON/OFFを自動制御しています。

極めつけは水属性の魔法(アグアメンティ)です。「魔法で水を出したい」というただそれだけの理由で、わざわざAmazonで物理的な水中ポンプを購入。それをスマートプラグに繋ぎ、発動時に2秒間だけ水を噴き出させるという異常な執念で魔法を再現しました。 僕としては今回のプロダクトが今まで作った中で一番ハックツハッカソンしてると思いました!

開発メンバー

ひろ:音声認識 / IMUのジェスチャー判定 ゆっちん:UI担当 リタ:JoyCon IMU / 杖のキーポイント検出 アリス:IoT連携

RiTa

@rita