光るミニ四駆「MINI 4WD LASER CIRCUIT」の作り方

# MINI 4WD LASER CIRCUITとは
2021年11月にオープンした「[トイロパーク グランツリー武蔵小杉 powered by リトルプラネット](https://litpla.com/space/toylo_musashikosugi/ "ホームページへ")」に設置された、**ミニ四駆の体験を拡張するデジタルサーキット**です。
ミニ四駆に特殊な小さいシールを貼って走らせると、そのミニ四駆にまるでアニメのようなエフェクトが出ます。
もちろん自身でカスタマイズして持ち込んだマシンにもエフェクトを出すことができます。
![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667381/9fa962a6-26a6-8a5d-4ac3-12fd451e16fa.jpeg)
実際の動画をツイートされている方がおられましたので、僭越ながらそちらの方のツイートを貼らせていただきます。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">武蔵小杉にできたレーザーミニ四駆。昨日行ったのですが、会社の人も気になってたみたいで、朝会とかでこの話題で持ちきりでした。小さなタグを愛車に貼り付けるとプロジェクションマッピングされます。ARゴーグルなどないらないので、周りで見てる人も楽しめるし、愛車を持ち込めば、より楽しめます！ <a href="https://t.co/27SJpWe2Ki">pic.twitter.com/27SJpWe2Ki</a></p>&mdash; Fumitoshi Ogata (@oggata) <a href="https://twitter.com/oggata/status/1463325469705601025?ref_src=twsrc%5Etfw">November 24, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

このレーザーサーキットですが、ありがたいことに予想以上の反響があり仕組みについて聞かれることも多かったため、今回仕組み解説の記事を書かせていただくことにしました。

# 仕組み解説
### ざっくり解説と全体の機材構成
超ざっくり説明しますと、**天井に取り付けたセンサ（AzureKinect）の赤外線カメラでミニ四駆に付けたシール（反射素材）を検知し、プロジェクターでその位置にエフェクトを投影する**といった仕組みになっています。
↓機材構成全体（オフィスの開発エリアで再現した際のものです）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667381/425bff78-e8de-10a8-d7f8-d1239c573676.png" width="400">

↓ミニ四駆とシール
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667381/4e6f09d1-04a8-89fe-ed34-d88e12c87ac7.jpeg" width="400">

### 赤外線検出でのトラッキングについて
赤外線カメラでは、赤外線を飛ばしてその飛ばした赤外線がどのくらい反射するかを検出することができます。
そのため、リフレクターなどの**反射素材を使用すると赤外線をそのまま反射することができるため、赤外線カメラの画像上だと反射素材付近は真っ白となって検出**できます。
実際に赤外線カメラでミニ四駆をトラッキングしている様子はこんな感じです。
![ezgif-1-31a321f594aaa.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667381/234d8746-840b-2b5a-c589-402b444691d0.gif)
ミニ四駆に貼ったシール（反射素材）の位置が白色として検知できており、その箇所に赤い印を付けています。

後はこの赤外線カメラの画像からOpenCVの色検出で白色の座標を取得し、プロジェクターでの投影位置に射影変換で位置合わせすれば、実際のミニ四駆の位置にプロジェクターからエフェクトを投影できるという仕組みです。

##### なぜ赤外線検出にしたの？
大きく分けて以下の2点です。
①センサ1つでコース全体をトラッキングできるため
②ミニ四駆側には小さいシールを貼るだけで良いため（かつシールが安いため）

ミニ四駆はコースは結構大きいですが、ミニ四駆本体は小さくとても速いというのが特徴です。
これを、可能な限り少ないセンサで（運用・保守のため）、かつミニ四駆側にほぼ手を加えずに（ユーザーへの手間の軽減）、かつ可能な限りコストを抑えてという条件で検討して行き着いたのがこの手法でした。
※行き着く途中の紆余曲折はもう少し↓に書きました

##### なぜ赤外線カメラはAzureKinectにしたの？
仕組み的には単純な赤外線カメラでも良かったのですが、大きく以下の3つの理由からAzureKinectにしました。
①画角が広い
②精度が良い（ノイズが少ない）
③グローバルシャッターで扱いやすい
今回のレーザーサーキットでは、コースは広く取りたいけどミニ四駆に貼るシールは小さくしたいという需要を満たすために、上記の①と②を特に重視して選定しました。

### 大変！エフェクトがミニ四駆の速さに付いていかないの！
さて、上記の赤外線検出でミニ四駆のトラッキングとエフェクト投影までできるようになりましたが、実はAzureKinectの赤外線カメラは30FPSしか出ません。
なので、そのままエフェクトを投影してもミニ四駆本体とエフェクトとの間にこんな感じで遅延が出てしまいます。
![ezgif-1-e6d9d867ca.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667381/9488d983-dc2d-5a69-8aa5-591750ebdced.gif)
この対策として、**位置推定**をする仕組みを導入しました。
ミニ四駆は基本的に一定速度で走行する（厳密にはカーブ時や坂道などは速度が違うのですが、肉眼だと分からないレベル）ので、この走行速度さえ取れてしまえば後は遅延を考慮した位置にエフェクトを出せばピッタリ合うはずという仮定のもと、過去の数フレーム分の位置データから速度を算出し「**過去にこの位置にいたなら今はきっとこの位置にいるはずだろう**」という位置推定を実装しました。
![ezgif-1-4aed49703f.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667381/3976ce53-24a3-dd2b-3934-5e20a558a262.gif)
おおよそこの仕組みで問題なくミニ四駆と同じ位置にエフェクトを投影することができました。
これはミニ四駆がどんなに速かろうと原理としては同じなため、どんな速さのマシンでもピッタリの位置にエフェクトを出すことが可能になってます。

# 途中の紆余曲折
### ①短距離センサで途中まで作って頓挫した話
ミニ四駆をトラッキングしようという話が出た時に、まず思いついたのが超短距離センサを使用する方法でした。
例えばこのようなセンサです（https://www.switch-science.com/catalog/2518/ ）
ミニ四駆は高さが低く（およそ2~5cm）かつ速いので、短距離を正確かつ高レスポンスで検知できるセンサをコースのすぐ上に設置すればいけるのではと考えました。
センサをコース上に何か所か設置し、それぞれの通過時間から速度を算出し、その予測位置にエフェクトを投影するという仕組みです。
実際に作ったものがこちら
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">「レーザーミニ四駆」の体験拡張コンテンツ<br>「MINI4WD LASER CIRCUIT」を鋭意開発中。<br><br>おもちゃの世界を”体験拡張”させる、新しい挑戦です。<a href="https://twitter.com/hashtag/%E3%83%9F%E3%83%8B%E5%9B%9B%E9%A7%86?src=hash&amp;ref_src=twsrc%5Etfw">#ミニ四駆</a> <a href="https://twitter.com/hashtag/mini4wd?src=hash&amp;ref_src=twsrc%5Etfw">#mini4wd</a> <a href="https://twitter.com/hashtag/PlaceHolder?src=hash&amp;ref_src=twsrc%5Etfw">#PlaceHolder</a> <a href="https://t.co/7bur9KExBb">pic.twitter.com/7bur9KExBb</a></p>&mdash; リス博士達 | アナログとデジタルを繋ぐアトラクション作り| プレースホルダ (@doctor_risu) <a href="https://twitter.com/doctor_risu/status/1432280301556748289?ref_src=twsrc%5Etfw">August 30, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
動画の右の方に木のヤグラがあると思うのですが、この下に各レーン1つずつの合計2つ短距離センサを設置し、それぞれを通過したタイミングで速度算出とエフェクトへの反映を行っています。（ついでにラップ計測もしてます）

パッと見問題無さそうに見えるのですが、下記の理由から途中で断念しました。
①メンテナンス性の悪さ
→本番はもっと大きいコースでセンサの数も増えるが、どれかのセンサが壊れた場合やセンサをコントロールしているraspberry piが壊れた場合の修理が大変（パークの運営スタッフに修理を任せるには難易度が高くエンジニアが修理に駆け付けなければならない）、かつセンサ自体がコースに近い位置にあるためミニ四駆が吹っ飛んで当たってしまったり誤って手で触ってしまったり壊れる可能性が高い。

②コースアウトが正確に取れない
→センサを通過したかどうかして見ていないので、どの位置でコースアウトしたかが曖昧。かつ2台ほぼ近い位置で走っていたミニ四駆がいたとして、どちらがコースアウトしたか見分けるのが難しい。

③誤検知の可能性がある
→短距離センサなのでセンサから物体までの距離しか見ておらず、ミニ四駆であろうが無かろうがその地点を通過した物はすべて検知してしまう。（極端な話手を突っ込んだだけでも検知する）

これらの問題は実は開発する前からある程度予想を立てていました。
しかし、当初は**ミニ四駆側に何も細工をせずにトラッキングしたい**という話があり、それならばこの手法が良いのではと考えて作っていました。
途中でシールを貼るくらいならば許容という話になり赤外線での検出方式に方向転換しました。

### ②深度カメラで作ろうとしてうまくいかなかった話
AzureKinectには深度カメラも付いており、およそ5mの距離までは検知できると公式ホームページに記載されています。（https://docs.microsoft.com/ja-jp/azure/kinect-dk/hardware-specification ）
もし、この深度カメラの精度が良いのであればこれまた**ミニ四駆側に何も細工をせずにトラッキングできる**のではないかと思い検証してみました。
その動画がこちら
![ezgif-2-5213fbb17b.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667381/11e0af56-a669-76b7-6915-5cbf605f685a.gif)
黒く動いている箇所がミニ四駆の箇所です。一見上手く検知できているように見えるのですが、実はこれちゃんと距離が取れていない箇所が黒くなっているだけで、実際には正しい距離が一切検知できていません。
どうやら速すぎる物体などはそのピクセル周辺が無効化されるロジックが入っているそうです。（https://docs.microsoft.com/ja-jp/azure/kinect-dk/depth-camera ）
これはこれで無効化されたピクセル周辺にミニ四駆がいると想定することもできるかと思ったのですが、
①ミニ四駆が静止している場合には無効化されないので検知できない
②動いているミニ四駆が100%無効化されるとは限らない
③ミニ四駆の高さ（2~5cm）を正確に検知するには3.5m離れた位置（天井にセンサを取り付けた場合）からでは精度が怪しい
という問題があり、この深度カメラでの方法も断念しました。

# おわりに
拙い文章で読みづらい箇所もあったと思いますがすみません。初めての記事投稿なのでお許しを。
どのくらい深い内容まで書くか悩んだのですが、一旦コードなどには触れない範囲でざっくり全体像が掴みやすいよう心掛けて書きました。
もっと深くまで知りたいなどご要望有ればご意見いただけますとありがたいです。

今後も開発中のアトラクションや作ったコンテンツの開発秘話や技術共有など、可能な限り記事を書いていこうと思いますのでよろしくお願いいたします。

また、弊社は一緒に働いてくれるメンバーを募集しておりますので、興味を持っていただけましたらぜひ一度↓のホームページを覗いてみていただけると幸いです。
https://placeholder.co.jp/contents/recruit