[RazDrone] ラズパイが空を飛ぶまで (0.準備編)

# 連載目次
- 概要 [Raspberry Pi Multicopter](http://qiita.com/keiya/items/2ce743c40d4df88e75ce)
- [ラズパイが空を飛ぶまで (0.準備編)](http://qiita.com/keiya/items/356497327bcb91d03464)
- センサー編
- 制御編
- 飛行編

準備編、センサー編、制御編、飛行編(完)で連載の予定。
進捗があればこの記事を随時、通知付きでアップデートする予定です。

# 前回のエピソード：設計編
* [かんたんな推力、電力、重量の見積もり等をした](http://qiita.com/keiya/items/2ce743c40d4df88e75ce)

# raspberry pi 3 テスト 2016/10/21-2016/10/22
* Rasp3, ヒートシンク, Navio2 が到着(全部Amazon購入)。
* [Navio2はGPSアンテナ、7～14V→5Vスイッチング電源、ワイヤーなど全部コミコミ。] (https://emlid.com/shop/navio2/)

* Raspbian lite をSDHCカードに書き込み
* [慣れているのでUSキーボードに切り替えた。](https://thepihut.com/blogs/raspberry-pi-tutorials/25556740-changing-the-raspberry-pi-keyboard-layout)
    *  `sudo raspi-config` で `Change Keyboard Options` で Generic 101
* [Wifi接続の設定](https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md)
        * アクセスポイント側でRaspのMACアドレスに対してDHCPのIPアドレスの割当を固定
* [スイッチング電源](http://qiita.com/keiya/items/2ce743c40d4df88e75ce#dc-dc-rasp%E7%94%A8)の長時間運用テスト (6.0V-14.8V)
* Navio2をスタックした状態で、半分ビニールをかぶせて温度チェック
* SSHがメインのためGPUのMemory Splitを最低の16MBに減少
* 6V～15VまでDC-DCにかけてラズパイが動作することを確認
    * `> 6V` で低電圧警告付きで安定稼働 (CPU 600MHz 100% + Navio2ボード稼働)
    * `> 6.75V` で電圧警告なしの安定 (CPU 1.2GHz 100% + Navio2ボード稼働)

# モーター テスト 2016/10/24-2016/10/26
* モーターをESCへのPWMでコントロール
    * 12inch propも載せてまわしてみる (1秒だけ回した)
        * たった1秒で親指をけがした ![記念.jpg](https://qiita-image-store.s3.amazonaws.com/0/19148/9ee00898-416d-6106-fed1-2040cfce1382.jpeg)
        * 回転によりめちゃくちゃ線が絡まっている

* ESC USB Linker / BLHeli関連 (Turnigy 20A v2 は BLheli でATMEL BLHeli Bootloader (USB/COM)で焼く)
    * ファームウェアをアップデート
    * 設定で Programming by TX (ESCへの入力で設定を変更できる；これをやるとへんなコマンドをNAVIO2のPWMから出して不意に設定が変わるかもしれない)をOFF

# 組み立て 2016/11/13

![_DSC0271.jpg](https://qiita-image-store.s3.amazonaws.com/0/19148/72d33832-780a-73d8-1fef-6759a4d45aa0.jpeg)

- 六角ねじ や 星ねじのドライバーが届いたので組み立て。
- ESCを無理やり押し込んでいく ![_DSC0272.jpg](https://qiita-image-store.s3.amazonaws.com/0/19148/d865469c-08e7-7804-aa41-392f255da102.jpeg)
- 組むと案外重い ![_DSC0275.png](https://qiita-image-store.s3.amazonaws.com/0/19148/aab4387b-80b2-c4c5-704a-b584dacf97dc.png)
    - 左はiPhone 5s、右はiPad mini 2
    - [計算した重量](http://qiita.com/keiya/items/2ce743c40d4df88e75ce#%E9%87%8D%E9%87%8F)で収まってるかは疑問…秤が無い。
- プロペラが巨大だが干渉はなかった。 ![_DSC0279.jpg](https://qiita-image-store.s3.amazonaws.com/0/19148/ed05b954-10a3-14f1-007b-a979f23bc5bc.jpeg)
    - 手のひらサイズ（半径が）

# プロペラテスト 2016/12/08, 09
Navio2サンプルコードにて回転させる。
固定不足でペラが飛んだり、機体がひっくりかえったりしたものの（また怪我した）、1つのペラだけで一応浮いた。

この部分で、モーターをarming(アーム)する。この操作を行って初めて、モーターを起動できる。
何をしているかというと、送信機（トランスミッター、ラジコン用語的にはプロポ）でスロットル最小値から最大値まで素早く動かし、また最小値に戻すという操作とみなせる。ESCによってアーミングのプロシージャは異なるが、今回はこうやってアームできる。

```C++
        for (double i=SERVO_MIN; i<SERVO_MAX; i+=0.001) {
          pwm.set_duty_cycle(PWM_OUTPUT, i);
          usleep(800);
        }
        printf("max/2\n");
        for (double i=SERVO_MAX; i>SERVO_MIN; i-=0.001) {
          pwm.set_duty_cycle(PWM_OUTPUT, i);
          usleep(800);
        }
```

その次に、最小値から中間値までなだらかに加速させる。

```
        for (double i=SERVO_MIN; i<SERVO_MID; i+=0.001) {
          pwm.set_duty_cycle(PWM_OUTPUT, i);
          usleep(30000);
        }
```

全貌はこちら。

```C++
#include <unistd.h>
#include <stdio.h>
#include "Navio/PWM.h"
#include "Navio/Util.h"

#define PWM_OUTPUT 2
#define SERVO_MIN 1.000 /*mS*/
#define SERVO_MAX 1.750 /*mS*/
#define SERVO_MID SERVO_MIN+(SERVO_MAX - SERVO_MIN) / 5.0 /*mS*/

int main()
{
    PWM pwm;

    if (check_apm()) {
        return 1;
    }

    if (!pwm.init(PWM_OUTPUT)) {
        fprintf(stderr, "Output Enable not set. Are you root?\n");
        return 0;
    }

    pwm.enable(PWM_OUTPUT);
    pwm.set_period(PWM_OUTPUT, 50);
//    while (true) {
        pwm.set_duty_cycle(PWM_OUTPUT, SERVO_MIN);
        sleep(1);
        for (double i=SERVO_MIN; i<SERVO_MAX; i+=0.001) {
          pwm.set_duty_cycle(PWM_OUTPUT, i);
          usleep(800);
        }
        printf("max/2\n");
        for (double i=SERVO_MAX; i>SERVO_MIN; i-=0.001) {
          pwm.set_duty_cycle(PWM_OUTPUT, i);
          usleep(800);
        }
        sleep(1);
        printf("\nmin\n");
        for (double i=SERVO_MIN; i<SERVO_MID; i+=0.001) {
          pwm.set_duty_cycle(PWM_OUTPUT, i);
          usleep(30000);
        }
        sleep(1);

//    }

    return 0;
}
```


# 次回(日程未定)予定
* パワーソースを分電して4つのESCに分配
    * 分電盤か分電ケーブル？を購入。
* わけがわからないPWMの制御を抽象化したい。
    * パーセンテージでスロットルコントロールしたいのと、ステートレスにしたい。
* センサーをいじる!