obnizでドライブしたい！FPS視点ラジコンを作ろう[obniz編]


## はじめに

LEGOとobnizでラジコンを作ったので、その作り方を紹介します。
今回は動力部分『obnizでのモーター制御とコントローラー』の作り方を紹介します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/b4d42567-6b35-1814-6edf-a2c1e4be6716.jpeg" width="350">

## 参考

- [obniz ゆるメカトロ車 LEGO構成をレシピを整えたメモ](https://www.1ft-seabass.jp/memo/2019/12/17/obniz-car-recipe/)
    - obnizでのモーター制御のスクリプトや車体の作り方について参考にさせて頂きました


## 冬空の下でドライブしてみた

タイトルに偽り無し。ちゃんとドライブしました。ラジコンにはカメラを付けているので、FPS視点（ラジコン視点）でも楽しめます。いやぁ～ラジコンたのしい

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">カメラ搭載ラジコンカー。ラジコン視点／操作画面／三人称視点をまとめてみた。<a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a> <a href="https://twitter.com/hashtag/RaspberryPi?src=hash&amp;ref_src=twsrc%5Etfw">#RaspberryPi</a> <a href="https://twitter.com/hashtag/LEGOTechnic?src=hash&amp;ref_src=twsrc%5Etfw">#LEGOTechnic</a> <a href="https://t.co/E7Ex0tgQDG">pic.twitter.com/E7Ex0tgQDG</a></p>&mdash; j4amountain (@zsipparu) <a href="https://twitter.com/zsipparu/status/1212689251822759938?ref_src=twsrc%5Etfw">January 2, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 完成図

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/fa52fe27-af10-d548-bc0a-318030616342.jpeg" width="400">

このようにIoTデバイス(ラズパイ、obniz)と、給電用のバッテリーを2つ搭載しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/2ffbf6e0-6e67-8721-cacb-01201012ba35.png" width="400">

## 今回紹介するのはobnizのモーター制御

後輪のモーター制御には、obnizを使用しています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/8b4ff7df-da6e-53a4-81b9-cd30256a25af.jpeg" width="350">

左車輪のモーターをobnizの0,1に、右車輪のモーターをobnizの10,11に接続します。赤と黒の配線を図のように接続します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/e6cf43df-6776-2061-e287-3a4577751374.png" width="350">

※今回使用したモーターはこちらです → [赤い歯車モーター](https://www.amazon.co.jp/gp/product/B07WHPRMM7/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1)

## 制御の概要

Windows上にNodejsでWebサーバーを用意し、obnizを制御するスクリプト`controler.html`を用意します。 ※Webサーバーは必須ではありません。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/c9d73c67-45fd-a1e7-b005-52bf2d495561.png" width="400">

`controler.html`は、githubに置きました　→ [controler.htmlのソース](https://github.com/zgw426/obniz-RadioControl/blob/master/controler.html)
11行目の『obniz-ID』を持っているobnizのIDに書き換えます。これで準備完了です。あとはcontroler.htmlをブラウザで開けばコントローラーとして使えます。

## コントローラーの説明

コントローラーは、用意したWebサイト（例：`http://localhost/controler.html`）にアクセスすると開きます。コントローラー画面はこんな感じです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/c058e12e-bf41-88d5-563c-295a2948fbcf.png" width="400">


操作は、画面に指をタッチします（マウスでは操作できません）
指と中心点との位置関係（指の距離、指の角度）でラジコンの動きを制御します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/9cb4b33e-b706-c9c4-c41d-97160c759b4f.png" width="550">

## スクリプトの説明

`controler.html`のJavaScriptについて補足します。

```html

<body ontouchmove="event.preventDefault()">
```

`ontouchmove・・・`は、iOSでページ全体のスクロールを無効にしています。コントローラーを指で操作したときにスクロールしないようにしています。


```javascript

var motor1 = obniz.wired("DCMotor", {forward:0, back:1}); // 左車輪のモーター
var motor2 = obniz.wired("DCMotor", {forward:10, back:11}); // 右車輪のモーター
```

`forward`,`back`に設定している番号は、obnizデバイスの端子の番号です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/1bfb4a63-075d-288b-5764-a96d15dcb03c.png" width="350">



```javascript

let x1 = div_x ;
let y1 = div_y ;
let x2 = event.changedTouches[0].pageX - div_x ;
let y2 = event.changedTouches[0].pageY - div_y ;
```

x1,y1は、コントローラー用の円の中心点です。
x2,y2は、画面にタッチしている指の座標です。中心点(x1,x2)を原点とした場合の座標にしています。

```javascript

let mpow  = Math.round( Math.sqrt( Math.pow( x2-x1, 2 ) + Math.pow( y2-y1, 2 ) ) ) ; // 2点間の距離
if( mpow >=100 ) mpow = 100;
```

円の中心(x1,y1)とタップした指の位置(x2,y2)間の距離を算出します。距離が100を超える場合は、値を100とします。この値が、モーターの出力になります。数値が高いほどモーターの回転速度が上がりラジコンが速く移動します。

```javascript

let angle = ( Math.atan2( y2 - y1, x2 - x1 ) * 180 / 3.1415 ).toFixed(2);
```

タップした指の位置(x2,y2)の角度を算出します。


```javascript

el_hitarea.addEventListener('touchend', function(event) {
    console.log("[debyg] now_x=0 now_y=0");
    motor1.stop();
    motor2.stop();
}, false);
```

タップした指が画面から離れるとモーターが止まります。

---

これで説明は以上です。

## 関連リンク

- 車体の作り方はこちらにかきました。
    - [obnizでドライブしたい！FPS視点ラジコンを作ろう[車体編]](https://note.com/agw/n/nef10a27ff18a)

## おまけ

そーいえば年明けてた。2020年の干支はネズミだそうです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/f092b2a0-c532-3c65-874e-3aaa141fdf11.jpeg" width="350">