こんにちは! けい(Twitter)です。
前回ラズパイPicoで作ったライントレースロボットの進化verを作ったので、ご紹介していきたいと思います。
前回の記事
目次
前回と今回の比較
前回のロボットの構成
前回は、以下の構成でライントレースロボットを作りました。
- マイコン:ラズパイPico
- モータードライバ:DRV8833
- モーター:タミヤのダブルギヤボックス
- ライントレースセンサ:1つ
- 回転:旋回のみ
詳しくは前回の記事を読んでみて下さい。
今回の改良点
今回は、以下の構成でライントレースロボットを作りました。
- マイコン:ラズパイPico
- モータードライバ:DRV8833
- モーター:タミヤのダブルギヤボックス
- ライントレースセンサ:3つ
- 回転:超信地旋回を追加
- pwmによるモータ速度調整機能を追加
ハード面ではセンサーの追加、ソフト面では超信地旋回と速度調整機能を追加しました。
ロボットのハードウェア
ライントレースセンサーの追加
前回同様のライントレースセンサーを増やして、スペーサーで固定しました。
また、センサーが外向きになる方がかっこいいので、向きを変えてみました。
回路図
図では単三電池が2本ですが、実際には3本の4.5Vで全ての電力を供給しています。
プログラム
ソースコード
電源が入ると自動でプログラムが実行されるように、「main.py」というファイル名でRaspberry Pi Picoにファイルを保存します。
from machine import PWM, Pin
import utime
class Robot:
def __init__(self):
self.IN1 = PWM(Pin(1))
self.IN2 = PWM(Pin(2))
self.IN3 = PWM(Pin(3))
self.IN4 = PWM(Pin(4))
self.IN1.freq(1000)
self.IN2.freq(1000)
self.IN3.freq(1000)
self.IN4.freq(1000)
def forward(self,v):
self.IN1.duty_u16(duty(v))
self.IN2.duty_u16(0)
self.IN3.duty_u16(duty(v))
self.IN4.duty_u16(0)
def right(self,v):
self.IN1.duty_u16(duty(v))
self.IN2.duty_u16(duty(v))
self.IN3.duty_u16(duty(v))
self.IN4.duty_u16(0)
def left(self,v):
self.IN1.duty_u16(duty(v))
self.IN2.duty_u16(0)
self.IN3.duty_u16(duty(v))
self.IN4.duty_u16(duty(v))
def right_spin(self,v):
self.IN1.duty_u16(0)
self.IN2.duty_u16(duty(v))
self.IN3.duty_u16(duty(v))
self.IN4.duty_u16(0)
def left_spin(self,v):
self.IN1.duty_u16(duty(v))
self.IN2.duty_u16(0)
self.IN3.duty_u16(0)
self.IN4.duty_u16(duty(v))
def back(self,v):
self.IN1.duty_u16(0)
self.IN2.duty_u16(duty(v))
self.IN3.duty_u16(0)
self.IN4.duty_u16(duty(v))
def stop(self):
self.IN1.duty_u16(duty(100))
self.IN2.duty_u16(duty(100))
self.IN3.duty_u16(duty(100))
self.IN4.duty_u16(duty(100))
def release(self):
self.IN1.duty_u16(0)
self.IN2.duty_u16(0)
self.IN3.duty_u16(0)
self.IN4.duty_u16(0)
class Photo_sensor:
def __init__(self):
self.sensor_1 = Pin(6, Pin.IN)
self.sensor_2 = Pin(7, Pin.IN)
self.sensor_3 = Pin(8, Pin.IN)
self.value = [0]*3
def read_sensor(self):
self.value[0] = self.sensor_1.value()
self.value[1] = self.sensor_2.value()
self.value[2] = self.sensor_3.value()
return self.value
def duty(percent):
return int(65025*percent*0.01)
robot = Robot()
sensor = Photo_sensor()
value_old = [0, 0, 0]
utime.sleep(1)
while True:
value = sensor.read_sensor()
# 真ん中が黒
if value[1]==1:
if value[0]==value[2]:
robot.forward(80)
elif value[0]==1:
robot.left_spin(80)
elif value[2]==1:
robot.right_spin(80)
# 真ん中が白
else:
if value[0]==1:
robot.left_spin(80)
elif value[2]==1:
robot.right_spin(80)
else:
if value_old[0]==1:
robot.left_spin(100)
utime.sleep(0.2)
elif value_old[2]==1:
robot.right_spin(100)
utime.sleep(0.2)
else:
robot.forward(80)
value_old = value
コード解説
4~53行目が、ロボットの駆動系のクラスです。
ここの部分に、今回新たに超信地旋回用の関数、「left_spin」「right_spin」を追加しました。
また、pwm信号でモーターにかかる電圧を調整できるようにしました。
55~66行目が、ライントレースセンサーのクラスです。
この部分で、センサー3つそれぞれの白と黒を読み取る関数を作成しています。
76行~が、メインループです。
主に、真ん中が黒か白かでプログラムを二分化しています。
ここの部分はまだまだ改良の余地があるので、皆さんでもぜひ挑戦してみて下さい。
実際にロボットを動かしてみた
動かした様子をyoutubeにアップしました。
なんとか試行錯誤の結果、コースを走破することができました。
始めてライントレースロボットを作ってみて、やはり一筋縄ではいかなかったなというのが所感です。
>> ライントレースロボットを作ろう ①センサー1つ