Raspberry Pi でブラウザから操作できるラジコン戦車を作る – ライブ(監視)カメラと組み合わせる –


■ライブ(監視)カメラと組み合わせる

Raspberry Pi で

・ブラウザから操作できるラジコン戦車

を作るシリーズ第七回目。

第六回までで、

・ブラウザから操作できるラジコン戦車

としては実質的に完成している。

が、折角ならラズパイの専用カメラモジュールと組み合わせ、

・ライブ(監視)カメラ付きラジコン戦車

にしていきたい。

ということで、今回は、

・ライブ(監視)カメラと組み合わせる

ということをやっていこうと思う。

具体的にやることは以下の通り。

では、各々について記載していく。



■ライブ(監視)カメラを作る

ライブ(監視)カメラを搭載したラジコン戦車を作るためには、

まずはラズベリーパイ自体をライブ(監視)として動くようにする

ということが必要になる。

この方法自体は、

ブラウザから操作できるライブ(監視)カメラを作る!

で既に記載しているが、WebIOPi のインストールなど、

重複する内容もいくつかある。

よってどちらかというと、

専用カメラモジュールを使う!
カメラマウントを組み立てる!
サーボモーターを動かす!
Raspberry Pi でレンズ型カメラを作る!

を順に実現するのがよいかと思う。

その後、カメラマウントを作る際に使った、

サーボモーターを操作できるようにしていくが、

既に WebIOPi をインストールしているので、

この後、ラジコン戦車の操作用プログラムや操作用画面と

組み合わせていく。

■カメラモジュールを車体に載せる

専用カメラモジュールを搭載したカメラマウントを組み立てたら、

これを車体に載せていく。

こちらも好きに載せればよいのだが、

輪ゴムやセロハンテープで固定するのが一番早い。

私も色々試してみたが、車体の組み方によって、

固定できたりできなかったりした。

今回の組み方であれば、専用カメラモジュールの

ケーブル長の関係もあって、以前試した載せ方は

あまり適さなくなっていた。

ということで、結局以下の様にセロハンテープで止めた。



■操作用プログラムを作る

専用カメラモジュールを搭載し、

カメラとして動くようになれば、

今度は、カメラも合わせてブラウザから操作出来るようにするため、

操作用のプログラムを修正していく。

ラジコン戦車の際に作成した、

・Remote_Controller.py

を、以下の様に変更する。


import webiopi
import pigpio

GPIO = webiopi.GPIO
pi = pigpio.pi()

# ラジコン戦車用パラメータ設定
tank_left_f = 9
tank_left_b = 11
tank_right_f = 23
tank_right_b = 22

# 監視カメラ用パラメータ設定
pin_pan = 18  # 左右方向の GPIO ピン番号
pin_tilt = 17 # 上下方向の GPIO ピン番号

# 監視カメラの初期位置宣言と設定
pos_pan_def = 1500
pos_tilt_def = 1300

# 監視カメラの現在位置宣言と初期位置への設定
pos_pan_current = pos_pan_def
pos_tilt_current = pos_tilt_def

# 監視カメラの最大位置宣言と初期値設定
pos_pan_max = 2300
pos_tilt_max = 2200
pos_pan_min = 700
pos_tilt_min = 700

def setup():
  # ラジコン戦車用 GPIO ピン設定
  pi.set_mode(tank_right_f, pigpio.OUTPUT)  
  pi.set_mode(tank_right_b, pigpio.OUTPUT)  
  pi.set_mode(tank_left_f, pigpio.OUTPUT)  
  pi.set_mode(tank_left_b, pigpio.OUTPUT)  

  # 監視カメラ用 GPIO ピン設定
  GPIO.setFunction(pin_pan, GPIO.PWM)
  GPIO.setFunction(pin_tilt, GPIO.PWM)
  pi.set_servo_pulsewidth(pin_pan, pos_pan_def)
  pi.set_servo_pulsewidth(pin_tilt, pos_tilt_def)

def loop():
  webiopi.sleep(0.5)

# ラジコン戦車用マクロ関数
@webiopi.macro
def tfront():
  #前進
  pi.write(tank_right_f, 1)
  pi.write(tank_right_b, 0)
  pi.write(tank_left_f, 1)
  pi.write(tank_left_b, 0)
  
@webiopi.macro
def tback():
  #後退
  pi.write(tank_right_f, 0)
  pi.write(tank_right_b, 1)
  pi.write(tank_left_f, 0)
  pi.write(tank_left_b, 1)
  
@webiopi.macro
def tright():
  #右旋回
  pi.write(tank_right_f, 0)
  pi.write(tank_right_b, 1)
  pi.write(tank_left_f, 1)
  pi.write(tank_left_b, 0)
  
@webiopi.macro
def tleft():
  #左旋回
  pi.write(tank_right_f, 1)
  pi.write(tank_right_b, 0)
  pi.write(tank_left_f, 0)
  pi.write(tank_left_b, 1)
  
@webiopi.macro
def tstop():
  #停止
  pi.write(tank_right_f, 1)
  pi.write(tank_right_b, 1)
  pi.write(tank_left_f, 1)
  pi.write(tank_left_b, 1)
  
# 監視カメラ用マクロ関数
@webiopi.macro
def defaultPosition():
  # 初期位置への設定
  pi.set_servo_pulsewidth(pin_pan, pos_pan_def)
  pi.set_servo_pulsewidth(pin_tilt, pos_tilt_def)
  pos_pan_current = pos_pan_def
  pos_tilt_current = pos_tilt_def
  
@webiopi.macro
def right():
  # 右方向への移動
  global pos_pan_current
  if pos_pan_current > pos_pan_min:
    pos_pan_current -= 100
    pi.set_servo_pulsewidth(pin_pan, pos_pan_current)
    
@webiopi.macro
def left():
  # 左方向への移動
  global pos_pan_current
  if pos_pan_current < pos_pan_max: pos_pan_current += 100 pi.set_servo_pulsewidth(pin_pan, pos_pan_current) @webiopi.macro def up(): # 上方向への移動 global pos_tilt_current if pos_tilt_current > pos_tilt_min:
    pos_tilt_current -= 100
    pi.set_servo_pulsewidth(pin_tilt, pos_tilt_current)
    
@webiopi.macro
def down():
  # 下方向への移動
  global pos_tilt_current
  if pos_tilt_current < pos_tilt_max:
    pos_tilt_current += 100
    pi.set_servo_pulsewidth(pin_tilt, pos_tilt_current)
    
def destroy():
  GPIO.setup(pin_pan,  GPIO.IN)
  GPIO.setup(pin_tilt, GPIO.IN)	
      

なお、各コードの意味に関しては、

WebIOPi で遠隔操作(サーボモータ制御編)!

に記載しているため、こちらを見ていただきたい。



■操作用画面を修正する

操作用プログラムを修正すれば、次は操作画面。

作りたい画面はこんな感じ。

ポイントは三つ。

1. 戦車操作用ボタンと同様にカメラ操作用ボタンを作る
2. カメラからの画像を iframe で取り込む
3. 戦車用ボタン + 画像 + カメラ用ボタン、と並べる

で、これを実現するため、WebIOPi の

index.html を以下の通り修正する。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<title>Raspberry Pi ラジコン戦車コントローラー</title>
<script type=”text/javascript” src=”/webiopi.js”></script>
<script type=”text/javascript”>
webiopi().ready(function(){
var callBack = function(macro, args, response){
}
<!– 戦車操作用ボタン –>
var BtnTS = webiopi().createButton(“tank-s”, “停止”, function(){
webiopi().callMacro(“tstop”,[], callBack);
});
$(“#tank-s”).append(BtnTS);

var BtnTR = webiopi().createButton(“tank-r”, “右折”, function(){
webiopi().callMacro(“tright”,[], callBack);
});
$(“#tank-r”).append(BtnTR);

var BtnTL = webiopi().createButton(“tank-l”, “左折”, function(){
webiopi().callMacro(“tleft”,[], callBack);
});
$(“#tank-l”).append(BtnTL);

var BtnTF = webiopi().createButton(“tank-f”, “前進”, function(){
webiopi().callMacro(“tfront”,[], callBack);
});
$(“#tank-f”).append(BtnTF);

var BtnTB = webiopi().createButton(“tank-b”, “後退”, function(){
webiopi().callMacro(“tback”,[],callBack);
});
$(“#tank-b”).append(BtnTB);

<!– カメラ操作用ボタン –>
var defaultBtn = webiopi().createButton(“defaultBtn”, “初期位置”, function(){
webiopi().callMacro(“defaultPosition”,[], callBack);
});
$(“#control-def”).append(defaultBtn);

var rightBtn = webiopi().createButton(“rightBtn”, “右方向”, function(){
webiopi().callMacro(“right”,[], callBack);
});
$(“#control-r”).append(rightBtn);

var leftBtn = webiopi().createButton(“leftBtn”, “左方向”, function(){
webiopi().callMacro(“left”,[], callBack);
});
$(“#control-l”).append(leftBtn);

var upBtn = webiopi().createButton(“upBtn”, “上方向”, function(){
webiopi().callMacro(“up”,[], callBack);
});
$(“#control-u”).append(upBtn);

var downBtn = webiopi().createButton(“downBtn”, “下方向”, function(){
webiopi().callMacro(“down”,[],callBack);
});

$(“#control-d”).append(downBtn);
webiopi().refreshGPIO(true);
});
</script>
<style type=”text/css”>
button {
display: block;
margin: 5px 5px 5px 5px;
width: 150px;
height: 100px;
font-size: 24pt;
font-weight: bold;
color: white;
}
</style>
</head>

<body>
<div align=”center”>
<table>
<tr>
<td>
<table border=0 cellspacing=”10″ cellpadding=”0″>
<tbody>
<tr>
<td>&nbsp;</td>
<td><div id=”tank-f”></div></td>
<td>&nbsp;</td>
</tr>
<tr>
<td><div id=”tank-l”></div></td>
<td><div id=”tank-s”></div></td>
<td><div id=”tank-r”></div></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><div id=”tank-b”></div></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</td>
<td>
<iframe width=”640″ height=”480″ src=”http://192.168.0.1/html/”></iframe>
<!–<img width=”640″ height=”480″ src=”http://10.57.1.65:9000/?action=stream” /> –>
</td>
<td>
<table border=0 cellspacing=”10″ cellpadding=”0″>
<tbody>
<tr>
<td>&nbsp;</td>
<td><div id=”control-u”></div></td>
<td>&nbsp;</td>
</tr>
<tr>
<td><div id=”control-l”></div></td>
<td><div id=”control-def”></div></td>
<td><div id=”control-r”></div></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><div id=”control-d”></div></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
</div>
</body>
</html>

なお、カメラ画像の取り込みを、

RPi_Cam_Web_Interface ではなく、

mpeg stream で実現したい場合には、

ブラウザから操作できるライブ(監視)カメラを作る(Mjpg-streamer 編)!

と同様の変更を実施してもらえればよい。

これで、

・画像を表示しながらラジコン、カメラを操作する

ということが実現出来たことになる。



■動作を確認する

ここまで出来たら、

WebIOPi から DC モーターを制御する

でやった通り、最終調整をするのみ。

raspberry pi を再起動した上で、

ブラウザから raspberry pi にアクセスし、

WebIOPi にログインして動作させてみればよい。

意図どおりに動かない場合、

・GPIO のピン番号が間違っている
・プログラムの記述(コピペ)ミス

などが考えられるため、これらを見直せばよいと思う。

■まとめ

2018 年年明け早々から、

・Raspberry Pi でブラウザから操作できるラジコン戦車を作る

ということに取り組んできたが、

記事の再整理を含め、今回で一通り完了した。

正直、自分一人でここまでできるとは思っていなかったが、

各種サイトに記載していただいている内容を参考にしながら、

なんとかここまでやってこれた。

その過程において、

・自分の環境ではうまくいかなかった

ということも多々あったため、今回、

・この通りにやれば誰でも作れる

というレベルを目指し、この記事を書いてきた。

実際にはこの記事の通りやったとしても、

うまくいかない人がいるかもしれない。

が、一人でも多くの方に、

・この記事どおりにやったらうまく言った!

と言ってもらえるとうれしいことこの上ない。

次に何を作ろうか、はまだ決まっていないが、

自分の力で動くものを作れる

というのは本当に楽しいことなので、

今後も何かを作っていきたいと思う。




Copyright (c) 2017 Webmaster of this site All Rights Reserved.
カテゴリー: ラズパイで電子工作 タグ: , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください