LoginSignup
7
4

More than 3 years have passed since last update.

ラズパイにて、ラジコンカーを自作する-その2

Last updated at Posted at 2020-03-15

はじめに

ラズベリーパイにて、自作のラジコンカーをつくったので紹介します。
今回は、制御になります。

output_7853_2.gif

ラジコンカー関連の記事

紹介する内容

  • ラズパイ側のラジコン制御

作るものの全体

rajikon-qiita2.png

ラズパイ側のプログラムです。

作業環境

  • ラズベリーパイ3
    • Raspbian Buster with desktop and recommended software
      • Version:February 2020
      • Release date:2020-02-13
      • Kernel version:4.19
      • Python3.7

作業手順

今回は、Pythonで実装します。
まずは、モータードライバのクラスを作ります。

モータードライバの制御

コードは、ラズパイで動くモノを作るを参考にさせていただきました。(ほぼ同じ)

コード : ta7291p.py

import RPi.GPIO as GPIO

STATE_STOP = 0
STATE_ON = 1

class Motor:

    def __init__(self, pina, pinb, pwmpin):
        self.state = STATE_STOP
        self.pina = pina
        self.pinb = pinb
        self.pwmpin = pwmpin
        self.duty = 0

        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)

        GPIO.setup(self.pina, GPIO.OUT)
        GPIO.output(self.pina, GPIO.LOW)

        GPIO.setup(self.pinb, GPIO.OUT)
        GPIO.output(self.pinb, GPIO.LOW)

        GPIO.setup(self.pwmpin, GPIO.OUT)
        GPIO.output(self.pwmpin, GPIO.LOW)

        self.pwm = GPIO.PWM(self.pwmpin, 80)
        return

    def setspeed(self,duty):
        self.duty = duty
        if self.state == STATE_ON:
            self.pwm.ChangeDutyCycle(self.duty)
        return self.state

    def accelon(self,back = False):
        if back == False:
            GPIO.output(self.pina, GPIO.HIGH)
            GPIO.output(self.pinb, GPIO.LOW)
        else:
            GPIO.output(self.pina, GPIO.LOW)
            GPIO.output(self.pinb, GPIO.HIGH)

        if self.state == STATE_STOP:
            self.pwm.start(self.duty)

        self.state = STATE_ON
        return self.state

    def acceloff(self):
        GPIO.output(self.pina, GPIO.LOW)
        GPIO.output(self.pinb, GPIO.LOW)
        self.pwm.stop()
        self.state = STATE_STOP
        return self.state

    def brakeon(self):
        GPIO.output(self.pina, GPIO.HIGH)
        GPIO.output(self.pinb, GPIO.HIGH)
        self.pwm.stop()
        GPIO.output(self.pina, GPIO.LOW)
        GPIO.output(self.pinb, GPIO.LOW)
        self.state = STATE_STOP
        return self.state

"GPIO.setwarnings(False)"は、WARNINGを非表示

ラジコンカーの制御

ラジコンカー部分の制御は以下となります。

コード : picar.py

from ta7291p import Motor
import time

FRONT_LEFT_WHEEL_PIN_A = 17
FRONT_LEFT_WHEEL_PIN_B = 4
FRONT_LEFT_WHEEL_PWMPIN = 27

FRONT_RIGHT_WHEEL_PIN_A = 18
FRONT_RIGHT_WHEEL_PIN_B = 23
FRONT_RIGHT_WHEEL_PWMPIN = 24

REAR_LEFT_WHEEL_PIN_A = 6
REAR_LEFT_WHEEL_PIN_B = 13
REAR_LEFT_WHEEL_PWMPIN = 19

REAR_RIGHT_WHEEL_PIN_A = 20
REAR_RIGHT_WHEEL_PIN_B = 12
REAR_RIGHT_WHEEL_PWMPIN = 21

class PiCar():

    def __init__(self):
        self._motors = {}
        self._motors["front_left"] = Motor(FRONT_LEFT_WHEEL_PIN_A, FRONT_LEFT_WHEEL_PIN_B, FRONT_LEFT_WHEEL_PWMPIN)
        self._motors["front_right"] = Motor(FRONT_RIGHT_WHEEL_PIN_A, FRONT_RIGHT_WHEEL_PIN_B, FRONT_RIGHT_WHEEL_PWMPIN)
        self._motors["rear_left"] = Motor(REAR_LEFT_WHEEL_PIN_A, REAR_LEFT_WHEEL_PIN_B, REAR_LEFT_WHEEL_PWMPIN)
        self._motors["rear_right"] = Motor(REAR_RIGHT_WHEEL_PIN_A, REAR_RIGHT_WHEEL_PIN_B, REAR_RIGHT_WHEEL_PWMPIN)

        self._speed = 0
        self.state = 0
        self.set_speed(100)
        return


    def set_speed(self, speed):
        self._speed = speed
        for key in self._motors:
            self._motors[key].setspeed(speed)
        return


    def turn_left(self):
        print("turn_left : run")
        for key in self._motors:
            if "rear" in key:
                self._motors[key].setspeed(int(self._speed * 0.7))
            else:
                self._motors[key].setspeed(self._speed)

            if "left" in key:
                self._motors[key].accelon(back=True)
            if "right" in key:
                self._motors[key].accelon()
        print("turn_left : over")
        return


    def turn_right(self):
        print("turn_right : run")
        for key in self._motors:
            if "rear" in key:
                self._motors[key].setspeed(int(self._speed * 0.7))
            else:
                self._motors[key].setspeed(self._speed)

            if "left" in key:
                self._motors[key].accelon()
            if "right" in key:
                self._motors[key].accelon(back=True)
        print("turn_right : over")
        return


    def forward(self):
        print("forward : run")
        for key in self._motors:
            self._motors[key].setspeed(self._speed)
            self._motors[key].accelon()
        print("forward : over")
        return


    def back(self):
        print("back : run")
        for key in self._motors:
            self._motors[key].setspeed(self._speed)
            self._motors[key].accelon(back=True)
        print("back : over")
        return


    def brake(self):
        print("brake : run")
        for key in self._motors:
            self._motors[key].brakeon()
        print("brake : over")
        return


    def acceloff(self):
        print("acceloff : run")
        for key in self._motors:
            self._motors[key].acceloff()
        print("acceloff : over")
        return


    def debug_proc(self):
        time.sleep(5)
        # Check for each tire
        # for key in self._motors:
        #     print(key)
        #     time.sleep(1)
        #     self._motors[key].setspeed(100)
        #     self._motors[key].accelon()
        #     time.sleep(1)
        #     self._motors[key].accelon(back=True)
        #     time.sleep(1)
        #     self._motors[key].acceloff()

        # Check : operation function
        self.forward()
        time.sleep(1)
        self.brake()
        time.sleep(1)
        self.turn_left()
        time.sleep(1)
        self.turn_right()
        time.sleep(1)
        self.acceloff()
        time.sleep(1)
        self.back()
        time.sleep(1)
        self.acceloff()



if __name__ == '__main__':
    pi_car = PiCar()
    pi_car.debug_proc()

下記のコマンドを実行で、動作確認をします。

 $ python picar.py

正しく動作すれば、
前進→ブレーキ→左旋回→右旋回→停止→バック→停止
の順に動作します。

さいごに

次の記事が最後の予定です。
ネットワーク越しに制御したいと思います。

参考

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4