Webブラウザ経由でRaspberry Piにつないだ3つのサーボをコントロールして、
Webカメラを上下・左右、そしてズームインとズームアウトさせます。
webIOPiからとりあえずサーボを動かす
まず最初に前回書いたサーボプログラムをwebIOPiに組み込んでみます。
2015年2月28日現在、RPIOがRaspberry Pi 2に対応していないためPi2を使っている場合は下記のコードは動きません。Raspberry Piでサーボコントロール、Part3 Raspberry Pi 2に対応でRPIOなしでサーボをコントロールできるようにしてあるので、そこを合わせて参考にしてみてください。
sudo vim /home/username/myproject/python/my-servo.py import webiopi from RPIO import PWM import time GPIO = webiopi.GPIO servo = PWM.Servo() SERVO_X = 23 SERVO_Y = 24 def setup(): GPIO.output(SERVO_X, GPIO.LOW) GPIO.output(SERVO_Y, GPIO.LOW) servo.set_servo(SERVO_X, 1500) time.sleep(1) servo.set_servo(SERVO_X, 1100) time.sleep(1) servo.set_servo(SERVO_Y, 1400) time.sleep(1) servo.set_servo(SERVO_Y, 1800) time.sleep(1) def destroy(): GPIO.digitalWrite(SERVO_X, GPIO.LOW) GPIO.digitalWrite(SERVO_Y, GPIO.LOW)
webIOPiのconfigにサーボプログラムを追加します。
sudo vim /etc/webiopi/config [SCRIPTS] myservos = /home/username/myproject/python/servo-script.py
webiopiを起動します。
sudo webiopi -d -c /etc/webiopi/config WebIOPi - ERROR - No module named RPIO
WebブラウザでRaspberry PiのGPIOを操作するのにwebIOPiを使っています。ただ、webIOPiはpython3で動いているらしく、サーボをコントロールするためのプラグインであるRPIOはpython2にしかインストールされてませんでした。
python3.2にRPIOをインストールします。
git clone https://github.com/metachris/RPIO.git Cloning into 'RPIO'... remote: Counting objects: 2013, done. Receiving objects: 16% (332/2013), 1.26 MiB | 5 KiB/s cd RPIO sudo python3 setup.py install
少し時間がかかるけど、これでRPIOをpython3にインストールできました。
もう一度webiopiを起動します。
sudo webiopi -d -c /etc/webiopi/config WebIOPi - ERROR - [Errno 98] Address already in use socket.error: [Errno 97] Address family not supported by protocol socket.error: [Errno 98] Address already in use
webiopiが人知れず動き続けていたようです。
一旦webiopiを停止して、デバッグできる形でwebiopiを起動します。
sudo /etc/init.d/webiopi stop sudo webiopi -d -c /etc/webiopi/config
これで前回書いたサーボプログラムをwebIOPiから動かすことができました。
webIOPiを使ってWebブラウザのボタンを使って3つのサーボを動かす
Webブラウザ経由で3つのサーボをコントロールして、Webカメラを上下左右そしてズームさせます。
ここまでくるとLEDコントロールと今まで書いたサーボコントロールの合わせ技だけなので、別段新しいことはやりません。端的にコードだけ載せておきます。よくわからない場合は、下記の記事を読みましょー。
Raspberry PIでLED点灯コントロール、Part3 ネット経由(WebIOPi)でコントロールする
Raspberry PIでLED点灯コントロール、Part4 水槽ライトを設置する
Raspberry Piでサーボコントロール、Part1 上下・左右の2軸を動かす
まずはサーボコントローラを3つのサーボを使って左右上下・ズーム(前後)させるプログラムに修正します。
sudo vim /home/username/myproject/python/servo-script.py import webiopi from RPIO import PWM import time GPIO = webiopi.GPIO servo = PWM.Servo() SERVO_X = 22 SERVO_Y = 24 SERVO_Z = 25 DEFAULT_X = 1500 DEFAULT_Y = 1180 DEFAULT_Z = 1500 CURRENT_X = DEFAULT_X CURRENT_Y = DEFAULT_Y CURRENT_Z = 0 time_stamp = time.time() def setup(): GPIO.output(SERVO_X, GPIO.LOW) GPIO.output(SERVO_Y, GPIO.LOW) GPIO.output(SERVO_Z, GPIO.LOW) def loop(): global time_stamp if (time_stamp <= time.time() - 20): defaultPosition() webiopi.sleep(0.5) @webiopi.macro def defaultPosition(): global time_stamp if time_stamp <= time.time() - 0.2 and (CURRENT_X != DEFAULT_X or CURRENT_Y != DEFAULT_Y or CURRENT_Z != 0): time_stamp = time.time() global CURRENT_X global CURRENT_Y global CURRENT_Z CURRENT_X = DEFAULT_X CURRENT_Y = DEFAULT_Y servo.set_servo(SERVO_X, DEFAULT_X) webiopi.sleep(0.5) servo.set_servo(SERVO_Y, DEFAULT_Y) webiopi.sleep(0.5) servo.set_servo(SERVO_Z, 1400) webiopi.sleep(CURRENT_Z) servo.stop_servo(SERVO_Z) CURRENT_Z = 0 time_stamp = time.time() @webiopi.macro def forward(): global CURRENT_Z, time_stamp if CURRENT_Z < 18 and time_stamp <= time.time() - 0.2: time_stamp = time.time() CURRENT_Z = CURRENT_Z + 1 servo.set_servo(SERVO_Z, 1550) webiopi.sleep(1) servo.stop_servo(SERVO_Z) time_stamp = time.time() @webiopi.macro def backward(): global CURRENT_Z, time_stamp if CURRENT_Z > 0 and time_stamp <= time.time() - 0.2: time_stamp = time.time() CURRENT_Z = CURRENT_Z - 1 servo.set_servo(SERVO_Z, 1400) webiopi.sleep(1) servo.stop_servo(SERVO_Z) time_stamp = time.time() @webiopi.macro def down(): global CURRENT_Y, time_stamp if CURRENT_Y < DEFAULT_Y + 50*10 and time_stamp <= time.time() - 0.2: time_stamp = time.time() CURRENT_Y = CURRENT_Y + 50 servo.set_servo(SERVO_Y, CURRENT_Y) webiopi.sleep(0.5) time_stamp = time.time() @webiopi.macro def up(): global CURRENT_Y, time_stamp if CURRENT_Y > DEFAULT_Y - 50*10 and time_stamp <= time.time() - 0.2: time_stamp = time.time() CURRENT_Y = CURRENT_Y - 50 servo.set_servo(SERVO_Y, CURRENT_Y) webiopi.sleep(0.5) time_stamp = time.time() @webiopi.macro def left(): global CURRENT_X, time_stamp if CURRENT_X < DEFAULT_X + 50*10 and time_stamp <= time.time() - 0.2: time_stamp = time.time() CURRENT_X = CURRENT_X + 50 servo.set_servo(SERVO_X, CURRENT_X) webiopi.sleep(0.5) time_stamp = time.time() @webiopi.macro def right(): global CURRENT_X, time_stamp if CURRENT_X > DEFAULT_X - 50*10 and time_stamp <= time.time() - 0.2: time_stamp = time.time() CURRENT_X = CURRENT_X - 50 servo.set_servo(SERVO_X, CURRENT_X) webiopi.sleep(0.5) time_stamp = time.time() servo.set_servo(SERVO_X, DEFAULT_X) webiopi.sleep(0.5) servo.set_servo(SERVO_Y, DEFAULT_Y) webiopi.sleep(0.5) def destroy(): GPIO.digitalWrite(SERVO_X, GPIO.LOW) GPIO.digitalWrite(SERVO_Y, GPIO.LOW) GPIO.digitalWrite(SERVO_Z, GPIO.LOW)
GPIO22は左右を動かすサーボをコントロールします。
GPIO24は上下を動かすサーボをコントロールします。
GPIO25は前後(物理的にズームさせる)に動かすサーボをコントロールします。
GPIO23は別のところでLEDをコントロールしているので、ここでは使いません。
loop()にwebiopi.sleep(0.5)を入れていますが、これがないとCPUの使用率が100%になってしまうので注意しましょう。
続いて、htmlファイルを修正します。
vim /home/username/myproject/html/index.html <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>WebIOPi | Light Control</title> <script type="text/javascript" src="/webiopi.js"></script> <script type="text/javascript"> webiopi().ready(function() { // Create a "Light" labeled button for GPIO 23 var upButton = webiopi().createButton("upButton", "Up", function(){ webiopi().callMacro("up"); }); var downButton = webiopi().createButton("downButton", "Down", function(){ webiopi().callMacro("down"); }); var leftButton = webiopi().createButton("leftButton", "Left", function(){ webiopi().callMacro("left"); }); var rightButton = webiopi().createButton("rightButton", "Right", function(){ webiopi().callMacro("right"); }); var forwardButton = webiopi().createButton("forwardButton", "Forward", function(){ webiopi().callMacro("forward"); }); var backwardButton = webiopi().createButton("backwardButton", "Backward", function(){ webiopi().callMacro("backward"); }); var defaultPositionButton = webiopi().createButton("defaultPositionButton", "Default", function(){ webiopi().callMacro("defaultPosition"); }); // Append button to HTML element with ID="controls" using jQuery $("#controls").append(upButton); $("#controls").append(downButton); $("#controls").append(leftButton); $("#controls").append(rightButton); $("#controls").append(forwardButton); $("#controls").append(backwardButton); $("#controls").append(defaultPositionButton); }); </script> <style type="text/css"> body{ margin:0;padding:0; } button { width: 140px; } </style> </head> <body> <div id="controls"></div> </body> </html>
あとは物理的にWebカメラとサーボを組み合わせて、
上下左右・ズームできるようにします。
Logicool C270にグレードアップで購入したWebカメラの要らない部分をドリルで破壊してヤスリをかけて、カメラマウントに接着剤で貼り付けます。そしてS35サーボ(900円)と車輪(ホームセンターで1つ90円くらい)と薄い木の板、そしてカメラマウントを組み合わせると・・・
こんな感じになります。電池は単なるオモリです。
オモリがないとちょっとしたことで木のレールに乗り上げてしまいます。
S35サーボで前進・後進させます。
丸いサーボホーンに両面テープをつけて滑らなくします。
あと、長細いヒノキの棒を使ってレールを敷いて進む方向を固定します。
後ろから見るとこんな感じです。
全体図
線が車輪にからまらないように上に引っ張ってます。
最後にブラウザでアクセスしてボタンをクリックしてサーボを動かしてみます。
http://192.168.0.122:8000
複数のボタンが出てきて、そのボタンを押すとサーボが前進したり、後進したり、Webカメラが右を向いたり左を向いたり、上を向いたり下を向いたりします。
今回のサーボコントロールは金魚の金太郎で使っています。ライブ映像の下にあるボタン、Up, Down, Left, Right, Forward, Backward等を押すとライブ映像に使っているWebカメラが動いて右のほうを映したり、左のほうを映したり等などをしてくれます。
コメントを残す