はじめに
obnizOSを搭載したM5StickCに内蔵された角速度センサーをコントローラーにして、ブラウザ上の3Dモデルを動かしたいと思います。
ブラウザ上に3Dモデルを描画する方法として、A-Frame(ブラウザ上に簡単にVRや3Dを作成できるフレームワーク)を使用します。
完成品
M5StickCの角速度センサを使ったプログラム。#obniz #M5StickC pic.twitter.com/VpEXBfRjtC
— kohei.w (@koheiw4) January 10, 2020
用意するもの
#作成手順
1. プログラムを書く
最終プログラムは以下になります。
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
<script src="https://aframe.io/releases/latest/aframe.min.js"></script>
<script src="https://unpkg.com/obniz@3.1.0/obniz.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/m5stickcjs/m5stickc.js"></script>
<style>
#title{
text-align: center;
margin-top: 20px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div id="obniz-debug"></div>
<h1 id="title">M5StickC 3D</h1>
<a-scene>
<a-cube id="cube" position="0 1.5 0" rotation="40 0 0" width="1.6" height="0.8" depth="3.4" color="#FF6600">
<a-plane position="0 0.42 -0.5" rotation="90 0 0" width="0.8" height="1.7" color="#333333"></a-plane>
</a-cube>
</a-scene>
<script>
const m5 = new M5StickC('OBNIZ_ID_HERE');
console.log("connecting");
m5.onconnect = async function(){
console.log("conncected");
let imu = m5.wired("MPU6886",{i2c:m5.m5i2c});
let data = await imu.getGyroWait();
let cube = document.getElementById("cube");
let a,b,c,x,y,z;
[a,b,c,x,y,z] = [data.x,data.z,data.y,0,0,0];
async function gyro(){
let data = await imu.getGyroWait();
x += (data.x-a)/5;
y += (data.z-b)/5;
z -= (data.y-c)/5;
cube.setAttribute("rotation",{x:x,y:y,z:z});
}
let interval = setInterval(gyro,200);
}
</script>
</body>
</html>
aframe.js, obniz.js, m5stickc.jsをそれぞれ読み込みます。
obniz.jsを読み込んだ後に、m5stickc.jsを読み込むようにしてください。
<script src="https://aframe.io/releases/latest/aframe.min.js"></script>
<script src="https://unpkg.com/obniz@3.1.0/obniz.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/m5stickcjs/m5stickc.js"></script>
<a-scene>
<a-cube id="cube" position="0 1.5 0" rotation="40 0 0" width="1.6" height="0.8" depth="3.4" color="#FF6600">
<a-plane position="0 0.42 -0.5" rotation="90 0 0" width="0.8" height="1.7" color="#333333"></a-plane>
</a-cube>
</a-scene>
const m5 = new M5StickC('OBNIZ_ID_HERE');
let imu = m5.wired("MPU6886",{i2c:m5.m5i2c});
let data = await imu.getGyroWait();
ディスプレイが水平な状態にしてM5StickCを置くと、角速度の値は(x : 0, y : 0, z : 0)になるはずですが、実際に取得してみると、値には少しズレがあります。
そのため、最初にディスプレイが水平な状態で角速度の初期値を取得し、a,b,cに代入します。
その後、data.x, data.y, data.zのそれぞれから初期値 a, b, cを引くことでズレを無くしています。
gyro()という関数を0.2秒に一度実行して、回転角 x, y, zを導出し、<a-cube>のrotation属性に代入することで、M5stickCの動きに合わせて3Dモデルも同じ動きをします。
2. M5StickCを電源に繋ぐ
電源が入ってもディスプレイには何も表示されません。起動したのかわかりづらいですが、電源ボタンを何度も押さないようにしましょう。
3. 実行
実行するとこのようにM5StickCの動きに合わせて、ブラウザ上の3Dモデルも動きます!
M5StickCの角速度センサを使ったプログラム。#obniz #M5StickC pic.twitter.com/VpEXBfRjtC
— kohei.w (@koheiw4) January 10, 2020
最後に
今回は3Dモデルを動かしましたが、M5StickCをコントローラーにしたゲームなどを作ってみるのも面白いかもしれません。色々試してみたいと思います!
最後まで読んでいただきありがとうございました。