スマート冷蔵庫開発2:サーボモーターとカメラ撮影

今回の記事ではサーボモータに2軸のサーボモータによる回転とwebカメラを用いることによって冷蔵庫全体を撮影できるようにしたシステムの説明をします.

使用部品 and 製品

カメラマウントの組み立て方については以下の記事を参考にしました↓.

 

SG90サーボ用の2軸カメラマウントが到着: EeePCの軌跡

SG90サーボ用 2軸 カメラマウント 2軸アングル FPV 空撮にも (マウント+2個SG90)
 

今回の広角カメラを使用した理由は広角カメラを縦方向に使用することによって冷蔵庫の内部を出来るだけ広く撮影をするために今回使用しました.普通のwebカメラでもでも動作しますが一部分しか撮影できませんでした.

 

 

サーボモータとカメラマウントとwebカメラを組み合わせると下記のような写真となります.すでに完成されたシステムなのでパワーLEDがついて状態の写真になっています.サーボモータとカメラマウントとの間に隙間があり,ぐらついたため,薄いプラスチックの板を凸で切り取り隙間を埋めています.またwebカメラは台座を取り外して使用します.運良く,カメラマウントにきれいにはまりました.

f:id:raspberry765:20170719165150j:plain

以下の2つの製品はPiZeroでUSB機器を動かすのに使用しました.Pi3で行う場合はUSBポートが存在するため要りません

 

 

私は下向きのケーブルがシステムを作るうえで便利であったため使用しました.写真でみると下記の写真のような感じになります.USBの出力が下方向にくるのでシステム回路が横方向に広がることを防ぐことができます.ただちょっと長いです.そのため,牛乳パックに実装するときはコードをまとめましたが,あまりコードの扱い方としていいものではありませんので,なにかもっといい変換端子がないか模索中です.

f:id:raspberry765:20170718221426j:plain

回路図

コンデンサを挿入した理由は,参考記事にあるようにサーボモーターの動作時(特に始動時)に大量に電流が流れることがあるため、その時の電圧降下による不具合を防止するためだそうです.コンデンサの容量は手元にあったやつを使用しました.サーボモーターの電源電圧5Vはラズパイの5Vからとっています.

参考記事↓

Arduinoで学ぶ基礎からのモーター制御:基礎からのマイコンモーター制御(6):PWMを使ったサーボモーターの制御 (2/3) - MONOist(モノイスト)

 

f:id:raspberry765:20170719174817j:plain

作成プログラム

作成プログラムですがここでのサンプルプログラムは前回の光検出回路のプログラムを使用して明るさが1500以下になったら撮影をサーボモーターを回転させながら撮影するというプログラムを説明します.作成したプログラムでは重要な要素はコマンドプロントによる撮影とpigpioによるpwm制御です.

 

  • 写真の撮影

  pythonを用いて写真の撮影を撮影する方法は調べれば多くあると思います.しかし

ながら私は最初に撮影した方法がfswebcamというコマンドプロント(cmd)を使用して撮影したため,cmdをpythonで実行する方法はないかと探しました.調べていく中でsubprocessというライブラリを使用すれば良いということが分かりこのスマート冷蔵庫ではfswebcamをsubprocessで呼び出して撮影しています,subprocess詳しい説明については以下を参考にしてください.さらにfswebcamについてのインストール方法についても以下を参考にしてください.

  

subprocess – プロセスを生成して連携する - Python Module of the Week

 

fswebcamの参考記事↓

https://www.raspberrypi.org/documentation/usage/webcams/

fswebcamを使う際に多くの引数を使用しているためその解説をします.

sudo fswebcam -F 10 --no-timestamp --no-banner --rotate 90 /home/pi/blog/test1.jpg

-F 10は撮影するフレーム数(露光時間)を意味します.数値が小さいほどぶれないそうです.

--no-timestamp --no-bannerはfswebcamは通常は撮影すると写真下に時間とバーが表示されます.しかしながらパノラマ写真をつくるときこの情報はいらないため,消去する引数となっています

--rotate 90は画像を90度回転(時計回り)させます.これはもともと横向きで撮影するカメラを縦にして撮影しているため,撮影が終わった段階で90度回転してあげることによって元の状態に戻してあげています.

 

   pwm制御にも様々な方法があります.しかしながら前回の記事で紹介した本でも書かれているのですがラズパイの標準のpwmでは精度が悪いため,サーボモータが小刻みにプルプルと振動してしまい撮影に支障がでてしまいます.本ではwiringPiを用いた高精度なpwm信号を使用していますが,スマート冷蔵庫の開発ではpigpioを用いてpwm制御をしました.以下の理由がpigpioを使う理由になります.

 

  • 高精度のPWMの出力ピンが多い!(32本)

WiringPiはpwmの出力pinが2本しかないため,回路設計の柔軟性がありません.

  • 使い方がシンプル!

基本的な高精度pwmを出力するのに以下の2行で終わりです

pi = pigpio.pi()

pi.set_servo_pulsewidth(ピン番号, pwm_width)

  • 自動実行(rc.local)の不具合がwiringPiであった

これが一番の大きな要因です.実は開発当初はwiringPiでサーボモータの制御をやっていたのですが,通常通りにプログラムを実行すると普通に動いていました.しかしながらrc.localで自動実行するようにpythonのプログラムを書いたとこサーボモータが回転しなかったり,途中で停止したりなどの不具合が多発しました.プログラムの自動実行の方法の変更とか調べてみてやってみたのですがうまくいかなかったのでpigpioを使用しています.

  • WiringPiによるpwmの停止のさせ方が分からない

撮影が終わっても永遠にpwm信号を出力しっぱなしであるため,WiringPiのgpioピンの開放プログラムが分かればいいのですが,私の知識不足でできなかっため,pigpioを使用しています.

 

また以下の記事はpigpioの優秀な点を分かりやすくまとめてあってよい参考ブログです.

Raspberry PiのGPIO制御の決定版 pigpio を試す - karaage. [からあげ]

 またpwmの制御についてお世話になった記事です

pigpioでサーボモーターを動かす。 – Blue-black.ink

 

撮影プログラムは前回の光検出回路にif文で条件を加えて検出した光が1500以下になったらサーボモータを回転させ撮影するようなプログラムとなっています.

if data < 1500:
  for pwm_width in range(1350,1700,150):
  print(pwm_width)
  sleep(0.5)
  pi.set_servo_pulsewidth(pin_az, pwm_width)
   

pwm_widthについては上記の参考記事でだいたい1500がサーボの角度中央のところにくるとかかれていたため,1500を中心に1350と1650の位置にカメラが回転するようにしました.

そしてsubprocess

subprocess.call(camera,shell = True)

で撮影をするcmdを呼び出します

sleep(0.5) #このsleepがないとサーボがしっかり動かない

sleepをしないとサーボが回転する時間がなく,回転しきれないままで次の命令にいってしまうため,sleepを入れています,

また,撮影する写真の名前が重複しないように名前を変更しています

count = count +1

camera = camera.replace('test'+str(count-1),'test'+str(count))

 

 

 

gist.github.com

 以上がサーボモータとカメラの連携による解説になります.プログラムや回路などまだまだ改善すべき所や非効率な部分があると思います.多分,間違っているところとかもあるかもしれません.随時記事の内容を見直し更新していきたいと思います.最後までお読みいただきありがとうございました!