モーターを動かしてみる

準備

  • 前からロボットを持っていってください.
  • コード(メスーメス)を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")