ラズパイカメラでFPVラジコンカー自作
ラズパイカメラモジュールを入手したので前々からやってみたかったFPVラジコンカーを作ってみました。
FPV(First Person View)とはドローンやラジコンにカメラを搭載して、映像を観ながら機体を操作する技術です。今回はスマホをコントローラにして自作してみました。
目次
ラズパイカメラモジュールでストリーミング
hackster.ioのコンテストの賞金sparkfunギフト$30券でラズパイカメラモジュールゲットしました!
Sparkfunは送料が安かったです。一番グレードの低いコースで送料$4.17でした。
但し、トラッキングはできず遅いです。5/2に発注して5/23に届きました。
国内だと以下が一番安いでしょうか。
今回はラズパイZero(+WiFi USB ドングル)にこのカメラを接続してストリーミングします。
せっかくなのでラズパイZeroのケースも買いました。カメラ穴が空いたフタもあり専用カメラモジュール用ケーブルも同梱でます。スタイリッシュ!
カメラ認識
ラズパイZeroとカメラモジュールが接続されたのでカメラを認識させます。
ストリーミング設定
カメラ動画ストリーミングにはMJPG-streamerを使用します。
上記ブログはwebカメラを使用したのでのですが今回はカメラモジュールですのでインストール方法が異なりました。
MJPG-streamerインストール
1 2 3 4 |
$ sudo apt-get install libjpeg8-dev cmake $ git clone https://github.com/jacksonliam/mjpg-streamer.git mjpg-streamer $ cd mjpg-streamer/mjpg-streamer-experimental $ make |
mjpeg sreamer起動
1 2 |
$ cd mjpg-streamer/mjpg-streamer-experimental $ ./mjpg_streamer -o "./output_http.so -w ./www -p 8080"-i "./input_raspicam.so -fps 15 -x 320 -y 240" |
320✕240ピクセル、15フレームでストリーミングします。画面を回転させる場合は -rotで回転角度指定。
1 |
$ ./mjpg_streamer -o "./output_http.so -w ./www -p 8080"-i "./input_raspicam.so -fps 15 -x 320 -y 240 -rot 90" |
ブラウザでストリーミング
1 |
http://ラズパイZeroのローカルIPアドレス:8080/?action=stream |
で見れます♪
ちょっと遅延がありますが。。。できました!!
参考
ラジコンカー組み立て
以前作ったラジコンカーをベースに組み立てました。
またラズパイカメラは2軸のカメラマウントで動かせるようにします。
構成
部品
- BLE搭載マイコンAdafruit Feather 32u4 Bluefruit LE
- モータドライバDRV8835
- マイコン用リチウムイオンポリマー電池400mAh
- ダブルギヤボックス
- SG90サーボ用 2軸 カメラマウント
- ラズパイ用モバイルバッテリー
blynk設定
ここではスマホのblynkアプリでBLEでマイコン制御し車とカメラを動かします。
新規プロジェクトを作成します。ハードウェアではAdafruit製品がまだないのでとりあえずArduino UNOを選択。Conection TypeにはBLEを指定します。
AUTH TOKENはArduinoコード生成時に使用しますのでメール送信します。
ウィジェットとしてVideo Streaming、BLE、ジョイスティック、スライダーを2個 配置します。
URLにhttp://ラズパイZeroのローカルIPアドレス:8080/?action=streamを指定してラズパイカメラの映像を表示します。
ジョイスティックの設定はヴァーチャルピンV0に2軸の数値を出力します。
x, yの値はそれぞれ最小-255 最大255としました。モータを制御して車を動かします。
2軸カメラマウンタを動かすスライダ値はそれぞれヴァーチャルピンV1, V2に出力し最小-255 最大255としました。またSend on ReleaseはOFFにしてスライダを動かす途中でもデータ送信するようにします。
Arduinoプログラム
BlynkのArduino用 最新ライブラリは以下にあります。
https://github.com/blynkkk/blynk-library
[スケッチの例] -> [Blynk] -> [Boards_BLE]-> [Adafruit_Feather_32u4_BLE]を参考にコード生成しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
#define BLYNK_PRINT Serial #define BLYNK_USE_DIRECT_CONNECT #include <BlynkSimpleSerialBLE.h> #include <SPI.h> #include <Adafruit_BLE.h> #include <Adafruit_BluefruitLE_SPI.h> //#include <Wire.h> #include <Servo.h> // You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = "Blynkアプリで取得したAUTH TOKEN"; // SHARED SPI SETTINGS (see adafruit webpages for details) #define BLUEFRUIT_SPI_CS 8 #define BLUEFRUIT_SPI_IRQ 7 #define BLUEFRUIT_SPI_RST 4 // Optional but recommended, set to -1 if unused #define BLUEFRUIT_VERBOSE_MODE true // Create ble instance, see pinouts above Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST); //pin name const int forwardL = 11; const int rearL = 13; const int forwardR = 5; const int rearR = 6; long Speed; long SpeedL, SpeedR; Servo servoX, servoY; // create servo object to control a servo //ジョイスティック BLYNK_WRITE(V0) { long x = param[0].asInt(); long y = param[1].asInt(); Serial.print("x: "); Serial.print(x); Serial.print(" y: "); Serial.print(y); Speed = sqrt(x*x+y*y); if(Speed > 255){ Speed = 255; } Serial.print(" Speed: "); Serial.println(Speed); if(y >= 0){ if(x >= 0){ SpeedL = 0; SpeedR = abs(x); }else{ SpeedL = abs(x); SpeedR = 0; } analogWrite(forwardL, Speed - SpeedL); analogWrite(rearL, 0); analogWrite(forwardR, Speed - SpeedR); analogWrite(rearR, 0); }else{ if(x >= 0){ SpeedL = 0; SpeedR = abs(x); }else{ SpeedL = abs(x); SpeedR = 0; } analogWrite(forwardL, 0); analogWrite(rearL, Speed - SpeedL); analogWrite(forwardR, 0); analogWrite(rearR, Speed - SpeedR); } } //2軸カメラマウント X軸 BLYNK_WRITE(V1) { int x = param.asInt(); x = map(x, -255, 255, 180, 0); servoX.write(x); } //2軸カメラマウント Y軸 BLYNK_WRITE(V2) { int y = param.asInt(); y = map(y, -255, 255, 150, 30); servoY.write(y); } void setup() { Serial.begin(9600); servoX.attach(A4); //2軸カメラマウント X軸用サーボ servoY.attach(A5); //2軸カメラマウント y軸用サーボ ble.begin(BLUEFRUIT_VERBOSE_MODE); ble.factoryReset(); // Optional ble.setMode(BLUEFRUIT_MODE_DATA); Blynk.begin(auth, ble); } void loop() { Blynk.run(); } |
動作
Blynk越しのストリーミングだと遅延 更に大きい。。。
やっぱコントローラとは別機でモニタリングしてヘッドマウントディスプレイに仕込みたいな♪
あとラズパイzeroのUSB WiFiドングル ジャマ(´;ω;`)。。。はやくWiFI、BLE内蔵のRaspberry Pi Zero Wほしいなぁ。