二足歩行ロボット Rapiro を Node.js で制御  [1] サーボとLED制御のテスト

#やりたいこと

## 最終目標
1. 二足歩行ロボット [Rapiro](http://www.rapiro.com/ja/) の制御を、標準の Arduino IDE（C/C++）ベースから、JavaScript（Node.js）ベースに移植し、Rapiro を IoT デバイスっぽくする
 * かつ、PCでの制御ではなく、Rapiro 内部に搭載した Raspberry Pi での制御とし、完全無線化を図る
 * 全機能の移植が難しくとも、最低限、10個の基本動作は移植・再現する

2. 可能な限り、[書籍「二足歩行ロボット 工作＆プログラミング（リックテレコム）」](http://www.ric.co.jp/book/contents/book_995.html)の改造内容も移植する
 * 距離センサの搭載
 * 静電容量タッチセンサの搭載など

3. この Rapiro をベースに、さらに賢そうな遊び方を模索する

## 今回 [1] の目標
* Rapiro 内部への Raspberry Pi の搭載
* [Node.js](https://nodejs.org/ja/) + [johnny-five](http://johnny-five.io/) での動作テスト
 * サーボが制御できることを確認し、直立状態に校正
 * LEDが制御できることを確認し、任意の色で発光


# 方法

## 機材
* [Rapiro](http://www.rapiro.com/ja/)（[組み立てマニュアル](http://www.rapiro.com/ja/assembly-manual/)に従って組み立て済のもの）
 * あらかじめ[標準プログラム（ファームウェア）](https://github.com/Ishiwatari/RAPIRO)で各サーボのトリム調整をし、__トリムの値を控えておく__
* [Rapiro 用 ACアダプタ](https://www.switch-science.com/catalog/1940/)（[スイッチサイエンスで動作確認済のもの](http://wiki.rapiro.com/page/ac-adaptor_ja/)）
 * 将来的な運用時には電池も使うが、開発時は電源ON状態が長くなるためACアダプタを使用
* Raspberry Pi 3 Model B
 * [NOOBS_v2_1_0](https://www.raspberrypi.org/downloads/noobs/) をインストール済
 * SSH や VNC によるリモート操作の設定済
 * 無線LAN 設定・接続済
 * シリアル通信の設定済（[こちらの手順](http://qiita.com/mkoku/items/111e6ec21395065f0c28)で）
 * Node.js のインストール済（[こちらの手順](http://qiita.com/mkoku/items/111e6ec21395065f0c28)で）
* PC（Windows10、[Arduino IDE](https://www.arduino.cc/en/main/software) が動けばなんでもよい）
* USBケーブル（Micro-B、Rapiro メイン基板に StandardFirmata を書き込むため）

## 手順

### Raspberry Pi 3 Model B を Rapiro に搭載
* Rapiro の [Wiki ページ](http://wiki.rapiro.com/page/try-to-fit-bplus/)の通りに加工して搭載（[Model B 用のアタッチメント](https://www.switch-science.com/pressrelease/20151007_rapiro-b2-attachment/)も付属していましたが、今回は使いませんでした）
* Rapiro メイン基板から生えているケーブルの6ピンコネクタを、Raspberry Pi の GPIO に接続（具体的には以下の画像をご参考まで）

![C1OnOhrUkAAOedk.jpg](https://qiita-image-store.s3.amazonaws.com/0/157570/f0c5ef69-9d45-9f75-6806-586e866fffe0.jpeg)

### Rapiro メイン基板に StandardFirmata を書き込む
* Rapiro の電源（Raspberry Pi にも供給される）は切っておく
* Rapiro メイン基板とPCをUSBケーブルで接続し、Arduino IDE で StandardFirmata を書き込む
 * ボードは「Arduino/Genuino Uno」を選択
* 書き込みが終わったらUSBケーブルを抜く
* [Rapiro メイン基板の仕様](http://www.rapiro.com/ja/rapiro-board-specifications/)（サーボやLEDのピン番号など）を勉強しておく

### サーボとLED制御テスト用のコードを書く

* Rapiro（Raspberry Pi）の電源を入れ、Raspberry Pi 上で以下のコードを作成（またはPCで作成して Raspberry Pi に FTP する）
 * 例として home/pi/rapiro_test/app.js として作成
 * 控えておいたトリムの値を、変数 trim に入れる

```js:app.js
// Rapiro制御ボードをNode.jsで制御
// Raspberry Pi 版　2017.01.08　by mkoku
// 　・全サーボを初期状態（直立）にする
// 　・LEDを適当な色にする

'use strict';                       // 厳格モードにする

const five = require('johnny-five'); // johnny-fiveモジュールを使う
const rapiro = new five.Board({     // Rapiro制御ボードを取得
    port: '/dev/ttyAMA0'            // ポート名（環境による）
});

const SVONUM = 12;                  // サーボの個数
let   servo = [];                   // サーボアレイオブジェクト
const pinServoDC = 17;              // サーボに電源供給しているピン番号（17=A3ピン）

const LEDNUM = 3;                   // LEDの個数（RGB）
let   led = [];                     // LEDアレイオブジェクト

const trim = [                      // サーボのトリム（微調整、個体に依存）
     -7,  2,  0,  0,  0,  0,  0,  0,-10,  6,  9,-12
];

const stand = [                     // サーボの初期位置（直立状態）
     90, 90,  0,130, 90,180, 50, 90, 90, 90, 90, 90 
];

let   ledBrightness = [             // LEDの各色の強さ [R, G, B]
    0, 0, 0
];


rapiro.on('ready', function() {     // Rapiro制御ボードがreadyなら

    // サーボの接続
    servo[0]  = new five.Servo(10); //  0: 頭部・回転    （左0     90  右180）
    servo[1]  = new five.Servo(11); //  1: 腰部・回転    （左0     90  右180）
    servo[2]  = new five.Servo(9);  //  2: 右肩・上下    （上180   0   下0）
    servo[3]  = new five.Servo(8);  //  3: 右肩・開閉    （開40    130 閉130）
    servo[4]  = new five.Servo(7);  //  4: 右手・開閉    （開120   90  閉70）
    servo[5]  = new five.Servo(12); //  5: 左肩・上下    （上0     180 下180）
    servo[6]  = new five.Servo(13); //  6: 左肩・開閉    （開130   50  閉40）
    servo[7]  = new five.Servo(14); //  7: 左手・開閉    （開70    90  閉120）
    servo[8]  = new five.Servo(4);  //  8: 右脚・回転    （外股180 90  内股0）
    servo[9]  = new five.Servo(2);  //  9: 右足・捻り    （外裏180 90  内裏0）
    servo[10] = new five.Servo(15); // 10: 左脚・回転    （外股0   90  内股180）
    servo[11] = new five.Servo(16); // 11: 左足・捻り    （外裏0   90  内裏180）
    // サーボへの電源供給開始
    this.pinMode(pinServoDC, five.Pin.OUTPUT)
    this.digitalWrite(pinServoDC, 1);
    // 各サーボをrapiroの初期位置（直立）へ
    for (let s = 0; s < SVONUM; s++) {
        servo[s].to(stand[s] + trim[s]);
    }

    // LEDの接続
    led = new five.Leds([6, 5, 3]); // [R, G, B]
    // LEDの色を変更
    ledBrightness = [255,  0,  0];  // 好みの色に設定 [R, G, B] (0-255)
    for(let l = 0; l < LEDNUM; l++) {
        led[l].brightness(ledBrightness[l]);
    }

});
```

### 動作確認

* [johnny-five](http://johnny-five.io/) をインストール

```
pi@raspberrypi:~ $ npm install johnny-five
```

* Raspberry Pi で 以下のように実行

```
pi@raspberrypi:~/rapiro_test $ node app.js
```

* Rapiro のサーボに通電され、直立し、目のLEDが指定した色に光ればOK

## 少し解説
* Rapiro では、サーボへの電源が常時流れているのではなく、17番ピンから供給されているようで、サーボを動かす時は、17番ピンのデジタル出力をHIGH(1)にする必要があります
* はじめ johnny-five の Servos オブジェクト（複数のサーボを一括でアタッチできる）を使おうとしましたが、なぜかうまく動かなかったので、Servo オブジェクトでひとつひとつアタッチしました
* それ以外は特に難しい部分はないと思います


# まとめ
大きくつまずくことなくできました。
[次回 [2]](http://qiita.com/mkoku/items/490606b5c70eeb9e5ea3) では、ポージングのプログラムと、ブラウザから操作できる簡易なユーザインタフェースを作りたい考えです。

最新コードは以下にあります。
https://github.com/mkokubun/rapiro.js