私的AI研究会 > AIbot Proj.1

AI Robot Project

ハードウェア外観と設計図

GPIO 関連回路図

● fig.6
 LED・スイッチ・スピーカー・オーディオアンプ
ケースの作成・基板実装・配線
● fig.9
 LED・DCモーター
キャタピラーロボットの組み立て

● 別のドライバ基板()Pololu DRV8835 Dual Motor Driver Carrier)を使用する場合。接続ピンに若干の変更あり。

ドライバ基板の説明

モーター駆動の基本プログラム ※ 2020/07/25 更新

 aibot.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# aibot.py
# AI Robot Controle Library on Raspberry Pi4
#

import RPi.GPIO as GPIO
import sys
import time

duty = 70

class MotorCtrl_base:
    
    def __init__(self, in1, in2, led):
        
        if in1 > 0:
            self.in1 = in1
            GPIO.setup(self.in1, GPIO.OUT)
            self.pwm1 = GPIO.PWM(self.in1, 100)
            self.pwm1.start(0)
        
        if in2 > 0:
            self.in2 = in2
            GPIO.setup(self.in2, GPIO.OUT)
            self.pwm2 = GPIO.PWM(self.in2, 100)
            self.pwm2.start(0)
        
        if led > 0:
            self.led = led
            GPIO.setup(self.led, GPIO.OUT)
        
    def fwd(self):                          # 回転(正転)
        self.pwm1.ChangeDutyCycle(0)
        self.pwm2.ChangeDutyCycle(duty)
        
    def back(self):                         # 回転(逆転)
        self.pwm1.ChangeDutyCycle(duty)
        self.pwm2.ChangeDutyCycle(0)
        
    def stop(self):                         # 停止
        self.pwm1.ChangeDutyCycle(0)
        self.pwm2.ChangeDutyCycle(0)
        
    def led_on(self):                       # ON
        GPIO.output(self.led, GPIO.HIGH)
        
    def led_off(self):                      # OFF
        GPIO.output(self.led, GPIO.LOW)
        
class MotorCtrl:
    def __init__(self):
        GPIO.setmode(GPIO.BCM)
        self.dcmotor1 = MotorCtrl_base(in1=25, in2=24, led=0)           # 右モーター
        self.dcmotor2 = MotorCtrl_base(in1=23, in2=22, led=0)           # 左モーター
        self.led_right = MotorCtrl_base(in1=0, in2=0, led=12)           # 右LED
        self.led_left = MotorCtrl_base(in1=0, in2=0, led=13)            # 左LED
        
    def stop(self):
        self.dcmotor1.stop()
        self.dcmotor2.stop()
        self.led_right.led_off()
        self.led_left.led_off()
        
    def reset(self):
        self.dcmotor1.reset()
        self.dcmotor2.reset()
        self.led_right.led_off()
        self.led_left.led_off()
        
    def forword(self):
        self.dcmotor1.fwd()
        self.dcmotor2.fwd()
        
    def wait_forword(self, cn):
        for i in range(cn):
            self.fwd_led()
            
    def fwd_led(self):
        self.led_right.led_on()
        self.led_left.led_on()
        time.sleep(0.5)
        
    def back(self):
        self.dcmotor1.back()
        self.dcmotor2.back()
        
    def wait_back(self, cn):
        for i in range(cn):
            self.back_led()
        
    def back_led(self):
        self.led_right.led_on()
        self.led_left.led_on()
        time.sleep(0.25)
        self.led_right.led_off()
        self.led_left.led_off()
        time.sleep(0.25)
        
    def turn_left(self):
        self.dcmotor1.fwd()
        self.dcmotor2.back()
        
    def wait_turn_left(self, cn):
        for i in range(cn):
            self.turn_left_led()
        
    def turn_left_led(self):
        self.led_left.led_on()
        self.led_right.led_on()
        time.sleep(0.25)
        self.led_left.led_off()
        time.sleep(0.25)
        
    def turn_right(self):
        self.dcmotor1.back()
        self.dcmotor2.fwd()
        
    def wait_turn_right(self, cn):
        for i in range(cn):
            self.turn_right_led()
        
    def turn_right_led(self):
        self.led_right.led_on()
        self.led_left.led_on()
        time.sleep(0.25)
        self.led_right.led_off()
        time.sleep(0.25)
        
    def left(self):
        self.dcmotor1.stop()
        self.dcmotor2.fwd()
        
    def wait_left(self, cn):
        for i in range(cn):
            self.left_led()
        
    def left_led(self):
        self.led_right.led_off()
        self.led_left.led_on()
        time.sleep(0.25)
        self.led_left.led_off()
        time.sleep(0.25)
        
    def right(self):
        self.dcmotor1.fwd()
        self.dcmotor2.stop()
        
    def wait_right(self, cn):
        for i in range(cn):
            self.right_led()
        
    def right_led(self):
        self.led_left.led_off()
        self.led_right.led_on()
        time.sleep(0.25)
        self.led_right.led_off()
        time.sleep(0.25)
        
    def led_off(self):
        self.led_left.led_off()
        self.led_right.led_off()
        
if __name__ == '__main__':
    motor = MotorCtrl()
    motor.stop()
    motor.led_off()
    
    args = sys.argv
    if 2 <= len(args):
        duration = sys.argv[2]
        if sys.argv[1] in {"stop"}:
            motor.stop()
        elif sys.argv[1] in {"forword"}:
            motor.forword()
            motor.wait_forword(int(duration))
            motor.stop()
        elif sys.argv[1] in {"back"}:
            motor.back()
            motor.wait_back(int(duration))
            motor.stop()
        elif sys.argv[1] in {"turn-left"}:
            motor.turn_left()
            motor.wait_turn_left(int(duration))
            motor.stop()
        elif sys.argv[1] in {"turn-right"}:
            motor.turn_right()
            motor.wait_turn_right(int(duration))
            motor.stop()
        elif sys.argv[1] in {"left"}:
            motor.left()
            motor.wait_left(int(duration))
            motor.stop()
        elif sys.argv[1] in {"right"}:
            motor.right()
            motor.wait_right(int(duration))
            motor.stop()
        else:
            print("Need Argument;forword, right, left, turn-right, turn-left, back or stop")
            
    else:
        print("Command Format: aibot [forword|right|left|turn-right|turn-left|back|stop] [count(0.5sec)]")
        
    GPIO.cleanup()

端末ターミナルからリモートコントロール ※ 2020/07/25 更新

 aibotrm.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# aibotrm.py  <<このソースコードは IDE デバッグはできない>>
# AI Robot Remort Program on Raspberry Pi4
#

from kbhit import *
import aibot
import sys
    
if __name__ == '__main__':
    atexit.register(set_normal_term)
    set_curses_term()
    
    motor = aibot.MotorCtrl()
    motor.stop()
    motor.led_off()
    ledmod = 0
    kb = ' '
    print("AIbot Control Ok! 'i,m,j,l,k,,u,o' or 'q'")

    while 1:
        # key push check & Motor control
        if kbhit():
            kb = getch()
            if kb == 'q':
                print(" ## Break       ##")
                motor.stop()
                motor.led_off()
                ledmod = 9
            elif kb == 'A' or kb == 'i':
                print(" ** Forword     **")
                motor.forword()
                ledmod = 1
            elif kb == 'B' or kb == 'm':
                print(" ** Bsck        **")
                motor.back()
                ledmod = 2
            elif kb == 'C' or kb == 'j':
                print(" ** Left        **")
                motor.left()
                ledmod = 3
            elif kb == 'D' or kb == 'l':
                print(" ** Right       **")
                motor.right()
                ledmod = 4
            elif kb == '2' or kb == 'o':
                print(" ** Right turn  **")
                motor.turn_right()
                ledmod = 5
            elif kb == '1' or kb == 'u':
                print(" ** Left turn   **")
                motor.turn_left()
                ledmod = 6
            elif kb == 's' or kb == 'k' or kb == ' ':
                print(" !! Stop        !!")
                motor.stop()
                ledmod = 0
            else:
                print("AiBot Standby OK !!!!")
            
        # LED mode set & wait 0.5sec
        if ledmod == 0:
            motor.led_off()
        elif ledmod == 1:
            motor.fwd_led()
        elif ledmod == 2:
            motor.back_led()
        elif ledmod == 3:
            motor.left_led()
        elif ledmod == 4:
            motor.right_led()
        elif ledmod == 5:
            motor.turn_right_led()
        elif ledmod == 6:
            motor.turn_left_led()
        elif ledmod == 9:
            break
        else:
            pass
        
    ledmod = 0
    print("Program Finished !!!")
    

自立走行の準備

タクトスイッチの入力待ちプログラム ※ 2020/07/15 更新

 wait.py

# -*- cording: utf-8 -*-

import time
import RPi.GPIO as GPIO

LED = 21
BUTTON  = 20

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED, GPIO.OUT)
GPIO.setup(BUTTON, GPIO.IN)

GPIO.add_event_detect(BUTTON, GPIO.FALLING)

while True:
    if GPIO.event_detected(BUTTON):
        print ("Raspberry Pi Switch ON !!")
        break
    else:
        GPIO.output(LED, GPIO.HIGH)
        time.sleep(0.5)
        GPIO.output(LED, GPIO.LOW)
        time.sleep(0.5)
 
GPIO.cleanup()
print ("Start OK !!!")

自動起動のためのシェルスクリプト

 aibot_boot.sh

#!/bin/bash

cd ~/Programs/aibot

python wait.py


echo "Motor Test Program Start..."
python aibot.py forword 6
python aibot.py back 6
python aibot.py left 4
python aibot.py right 4
python aibot.py turn-left 3
python aibot.py turn-right 3
python motor3.py stop 1

echo "Aibot Start..."
$ chmod u+x aibot_boot,sh
$ ./aibot_boot.sh

自動起動の設定

 1. 自動起動ファイルを作成する。

 aibot_boot.service

Description=Aibot boot
[Service]
ExecStart=/bin/bash /home/pi/Programs/aibot/aibot_boot.sh
WorkingDirectory=/home/pi/Programs/aibot/
Restart=always
User=pi
[Install]
WantedBy=multi-user.target

 2. 自動起動用のサービスファイルをコピーする。

$ sudo cp aibot_boot.service /etc/systemd/system/

 3. systemdにユニットファイルを追加・更新したことを通知する

$ sudo systemctl daemon-reload

 4. 自動起動を登録する。

$ sudo systemctl enable aibot_boot.service
$ sudo systemctl start aibot_boot.service

 5. 登録を確認する。

$ sudo systemctl status aibot_boot.service

  active となっていたら登録完了。

自動起動したサービスの停止

自動起動したサービスの削除

cronを使って起動時にプログラムを走らせる

Pythonでリアルタイムにキーボード入力を処理する方法

Pythonではreadcharというライブラリを使う。

参考資料


Last-modified: 2020-07-25 (土) 14:20:48