モーターを動かしてみる
準備
- 前からロボットを持っていってください.
- コード(メスーメス)を1人12本持っていってください.
- ロボットについている Arduino Mega を抜いて前に持ってきてください.
- 電池の電圧が低ければ前に交換しにきてください.
ファイルの送受信
今回用意したディスプレイは小さいので,プログラムを作成する時には mac で作成して,それをラズパイに送ることができれば便利です.ネットワークを介したファイル送信には, scp, sftp などがあります.
scp
scp を使う場合には
scp ファイル名 アカウント名@通信先IPアドレス:
のようにします.例えば,
scp test.py robot@172.19.xxx.xxx:
です.
ファイルをとってくる場合には
scp アカウント名@送信先IPアドレス:ファイル名 .
のようにします.
sftp
sftp コマンドは相手先にログインし,get で接続先からファイルを取得し,put で接続先にファイルを送信します.
sftp アカウント名@IPアドレス
で接続すると
sftp>
のようなプロンプトで sftp のインタフェースが現れますので,ここで,ls
とすると開いて接続先のファイルのリストが現れます.lcd
とすると自分のコンピュータのファイルのリストが表示されます.cd
で移動もできますので,目的のディレクトリに移動します.lcd
とすると自分のコンピュータでのディレクトリ移動となります.
目的の場所に来たら,
sftp> put test.py
でファイルを送信できます.ファイルを取得する時には,
sftp> get test.py
とします.その他のコマンドは help
コマンドで調べてみてください.終了は bye
あるいは Ctrl-D (コントロールキーを押しながらdキーを押す) です.
samba
頻繁にファイルをやり取りする時には,共有ディレクトリでファイルをやり取りできると便利です.ラズパイには samba という Windows のネットワーク機能を実現するソフトウェアをインストールすることができますので,それを利用するとディレクトリを共有することができます.
sambaを有効にするには以下のようにします.
Terminal で以下のコマンドにより,samba をインストールします.
sudo apt-get update
sudo apt-get upgrade
sudo apt install samba
その後,samba の設定ファイルを nano または pico で編集します.
sudo nano /etc/samba/smb.conf
開いたファイルの最終行に以下のように記述します.
[pi]
comment = robot user file space
path = /home/robot
force user = robot
guest ok = yes
create mask = 0666
directory mask = 0777
read only = no
編集後に,変更を有効化するために Samba を再起動します.
sudo systemctl restart smbd
MacBook Pro で Finder のメニューから「移動」->「サーバーに接続」を選択し,ラズパイのIPアドレスを入力します.
smb://172.19.xxx.xxx
これで,Mac の方でラズパイのフォルダが開けば成功です.
モータードライバー
モーターへの命令信号とモーターを駆動する電力を供給する必要がある. 命令信号に応じて,モーターに大きなパワーの電力を供給するのがモータードライバーです. 命令信号はラズパイから与えられ, モーターを駆動する電力は電池から供給されます. モータードライバーでは 方向を決めて電流が流れるように,Hブリッジという回路が使われています.
今回使用するモータードライバーは OSOYOO Model-X Motor Driver Module です。
このモータードライバーは2種類のモーターを最大4つまで駆動することができます。 今回のロボットでは、2つのモーターを動かすモータードライバーが2つ搭載されており、 4つの車輪を動かしています。
このモータードライバーには多くの端子がありますが、以下のようになっています。
- 入力(命令信号):
- モーター1:IN1, IN2, ENA
- モーター2:IN3, IN4, ENB
- 入力(電力):白い端子(12V, GND)
- 出力(モーター):
- モーター1:K1, K2
- モーター2:K3, K4
K1, K2 | IN1, IN2, ENA の指令で出力されるモーターの端子 |
K3, K4 | IN3, IN4, ENA の指令で出力されるモーターの端子 |
モータードライバーへの入力を見てみましょう.
ENA | IN1 | IN2 | K1, K2 |
---|---|---|---|
0 | X | X | STOP |
1 | 0 | 0 | Brake |
1 | 0 | 1 | 回転 |
1 | 1 | 0 | 逆回転 |
1 | 1 | 1 | Brake |
となっているので、ENA に PWM 信号を、IN1, IN2 にデジタル信号を送ることによって、 モーターの回転を制御できます。 まとめると
ENA PWM 信号 | K1, K2 のモーターの回転速度を制御 |
ENB PWM 信号 | K3, K4 のモーターの観点速度を制御 |
IN1/IN2 | K1, K2 のモーターの回転方向を制御 |
IN3/IN4 | K3, K4 のモーターの回転方向を制御 |
IN1=1 IN2=0 | K1, K2 のモーターを正転 |
IN1=0 IN2=1 | K1, K2 のモーターを逆転 |
IN3=1 IN4=0 | K3, K4 のモーターを正転 |
IN3=0 IN4=1 | K3, K4 のモーターを逆転 |
のようになっています。
モータードライバーとラズパイの配線
-
電源コード: 電池ボックスから出ている赤色・黒色の線が,モータードライバーの12V, GND のソケットに接続されていることを確認してください.
-
モータ指令のコード: そのモータードライバーについて,6本の線が出ている白いプラグで,ENA, IN1, IN2 の線を確認してください.これらの線(黒,紫,緑)をラズパイの GPIO のGNDと PWR以外の場所に接続してください.(GPIO番号はプログラムで使うので覚えておく)
サンプルプログラム
上記の ENA, IN1, IN2 の関係を参考に車輪を動かすプログラムを試してみます.下の例では
- IN1 は GPIO6 に接続.デジタル出力.
- IN2 は GPIO13 に接続.デジタル出力
- ENA は GPIO17 に接続.PWM出力
としています.GPIO の番号は自分の配線した番号に変えてください.
import gpiozero
import time
#####################################
#
# IN1 は GPIO6 に接続.デジタル出力.
# IN2 は GPIO13 に接続.デジタル出力
# ENA は GPIO17 に接続.PWM出力
#
#####################################
in1 = gpiozero.DigitalOutputDevice(pin=6)
in2 = gpiozero.DigitalOutputDevice(pin=13)
ena = gpiozero.PWMOutputDevice(pin=17, frequency=1000)
##################
# 正転
##################
in1.on()
in2.off()
ena.value = 0.5
time.sleep(3) #3秒待つ
##################
# 逆転
##################
in1.off()
in2.on()
ena.value = 0.5
time.sleep(3) #3秒待つ
##################
# 止まる
##################
in1.off()
in2.off()
ena.value = 0.0
time.sleep(3) #3秒待つ
print("bye")
モーターを動かすクラスの作成
それでは1つの車輪を動かすクラスファイルを作成してみましょう.ファイル名は "motor.py" とします.
import gpiozero
class Motor:
def __init__(self, pin_1, pin_2, pin_en):
self.in1 = gpiozero.DigitalOutputDevice(pin=pin_1)
self.in2 = gpiozero.DigitalOutputDevice(pin=pin_2)
self.ena = gpiozero.PWMOutputDevice(pin=pin_en, frequency=1000)
def forward(self, val):
self.in1.on()
self.in2.off()
self.ena.value = val
def backward(self, val):
self.in1.off()
self.in2.on()
self.ena.value = val
def stop(self):
self.in1.off()
self.in2.off()
self.ena.value = 0.0
このように一つの車輪の動作を扱うクラスを作っておくことで,2つのモーターを動かす時には以下のように簡単に記述できます.
from motor import Motor
motor1 = Motor(pin_1=6, pin_2=13, pin_ena=17)
motor2 = Motor(pin_1=13, pin_2=19, pin_ena=26)
motor1.forward(0.3)
motor2.forward(0.3)
time.sleep(3)
motor1.stop()
motor2.stop()
メカナムホイール
今回扱うロボットはメカナムホイールという変わった車輪を使っています.この車輪を独立に回転させることによって,ロボットは自由に前後左右に移動することができます.
課題:
上記の図を参考にメカナムホイールを前後左右に移動させるクラスを作成してみましょう.
from motor import Motor
class Wheel:
def __init__(self):
self.motorFR = Motor(xxxxxxxxxxx) #front right
self.motorFL = Motor(xxxxxxxxxxx) # front left
self.motorRR = Motor(xxxxxxxxxxx) # rear right
self.motorRL = Motor(xxxxxxxxxxx) # rear left
def forward(self, val):
xxxxxxxxxxx
def back(self, val):
xxxxxxxxxxx
def stop(self):
xxxxxxxxxxx
def rotateR(self, val):
xxxxxxxxxxx
def rotateL(self, val):
xxxxxxxxxxx
def right(self, val):
xxxxxxxxxxxx
def left(self, val):
xxxxxxxxxxxx
このプログラムができたら,例えば以下のように使えるはずです.
import time
from wheel import Wheel
robot = Wheel()
# 前進
robot.forward(0.6)
time.sleep(1)
# 止まる
robot.stop()
time.sleep(1)
# 右に回転
robot.rotateR(0.3)
time.sleep(1)
# 止まる
robot.stop()
# 終わり
print("byebye")