【爆誕!!】障害物検知ロボット・トマロボくん開発
さてみなさまこんにちは。
まぶちでございますよ。
今日は障害物を検知して自分で動いていくロボットを開発しました。
なづけてトマロボくんです
超音波センサー自動検知ロボット
この可愛らしい外観
今回は動画を御覧ください。
You Tube#ショート動画
お風呂の排水口からつまみ出してきた住人
こと前回のモジャボットver1から
ver2になり、多少改善
そしてver3になり洗練されてきました。
そもそも、コードが無駄に長いのでモジャモジャになるのがわかりました。
そのためコードの整理を行っております。
オールバックのような洗練された外観
今回は自動検知センサーをつけてみました。
SR04という超音波距離センサーです。
ちょうど目の位置についております。
これが、毎回距離を測ります。
超音波センサーが音速で反響音を計算し距離を測定します。
障害物まで25センチを下回るとキャタピラの動きを変えて方向転換していきます。
直進から障害物を検知するとLEDが切り替わります。
●ロボット概要●
制 御 :ラズベリーパイ・ピコ (550円)スイッチサイエンス
ドライバ :モータードライバーDRV8833(300円)電子工作ショップ
超音波ユニット:SR-04 (300円)電子工作ショップ
モーター :タミヤセット・なんかの余り(2,800円)おもちゃ屋さん
制御電源モバイルバッテリー: 5V3A大容量タイプ
動力用 電源ユニット: 単三乾電池1.5V×4本直列 6V
モーター動力用 LED: 5mm 青、黄
●説明●
①立ち上げ プログラムは、ラズパイピコに電源を入れると立ち上がります。 青色LEDが点灯し、電源を入力したことを検知
②動作 制御がモーター動力をONし、クローラーが前進します。
③障害物検知 一定間隔ごとに超音波センサーが距離を測定します。 直進をしていきます。
④障害物退避運動 25cm以内になったら、障害物ありと検知し、数マイクロ秒後退動作が入って障害物から退避 クローラーの左前進、クローラーの右後退が同時に動く超信地旋回を行います。
配線関係はラズパイピコというマイコンをつかったので、たったこれだけです。
奥側のグリーンがラズパイピコ基板です。
手前側がモータートライバです。
プログラム言語はPythonで組んでおり、ラズパイのSRAM264KBに内部保存されています。
main.py
で保存すれば起動時プログラムが自動的に走る仕組みになっております。
ソースコード
※ワードプレスの仕様でインデントが効きません。申し訳ありません。
#トマロボくんの動作プログラム
#をつけるとコメント文となり、人間にしか読み込めません。
#1.ライブラリのインポートエリア
from machine import Pin
#マシンモジュールをインポート
import utime
#タイムモジュールをインポート
#2.ピン番号指定エリア
#ここからピン番号を指定していきます。
trigger = Pin(16, Pin.OUT)
echo = Pin(17, Pin.IN)
#エコーピンはエコーを入れるので、IN(入力にする。)
LF = Pin(11, Pin.OUT)#モーターの左前進 LEFTFOWARD
LB = Pin(12, Pin.OUT)#モーターの左後退
RF = Pin(1, Pin.OUT)#モーターの右前進
RB = Pin(2, Pin.OUT)#モーターの左後退
BL = Pin(28, Pin.OUT)#点灯LED、直進時
YL = Pin(22, Pin.OUT)#点灯LED、障害物検知
#3.障害物検知関数定義エリア
#障害物検知関数を定義(モジュールを引っ張ってきました。)
def read_distance():
global t #グローバル変数として定義。関数外でも使えるようにしてます。
#以下、ライブラリからコピー
trigger.low()
utime.sleep_us(1)
trigger.high()
utime.sleep(0.00001)
trigger.low()
while echo.value() == 0:
signaloff = utime.ticks_us()
while echo.value() == 1:
signalon = utime.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0343) / 2
print("distance: ",round(distance,1),"cm")
t = distance
#distanceをtという変数に代入
return t
#return tで、戻り値をtにて定義
#4.直進時通電確認LED点灯エリア
#直進時ブルーのLED点灯・通電確認用
BL.value(1)
#一旦停止
LF.value(0)
RB.value(0)
LF.value(0)
RF.value(0)
utime.sleep(0.8)
BL.value(0)
#5.for文による1500回動作反復エリア・メインプログラム
#トライエクセプト構文を使って、例外時にすべてのモーターを止めるようにしてます。
try:
for i in range(1500):
#for文を使って1500回繰り返す。while文だと永遠に稼働してしまう。
t=read_distance()
#このタイミングでセンサー値をひろう。ここが最も重要なタイミング
#基本は直進
YL.value(1)#イエローLEDを点灯させる。
LF.value(1)
RF.value(1)
utime.sleep(0.3)
utime.sleep(0.01)
utime.sleep(0.05)
YL.value(0)
#条件分岐、もし超音波センサーの戻り値が25cm以内ならば、以下の動作
if t < 25:
utime.sleep(0.01)
#チャタリング等微小な差分を消すため、タイムスリープ
BL.value(1)
#ブルーLEDを点灯(ここでセンサーがifに入ったことを認識。)
LF.value(0)
RF.value(0)
#0.3秒、一旦停止する。
utime.sleep(0.3)
LB.value(1)
RB.value(1)
utime.sleep(0.3)
#退避行動・0.3秒後退する。これは退避行動で、そのまま回転すると前輪があたるため、少し後退させたい。
LB.value(0)
#レフト後退信号を止める。これをしないと次のLFと合算になり、ブレーキが発動、前進しなくなる。
utime.sleep(0.01)
#いちいち0.01のタイムスリープを入れるのは、モーターの逆起電力対策
#ハード対策として、セラミックコンデンサを入れると良いらしい。
LF.value(1)
RB.value(1)
utime.sleep(0.7)
#0.7秒間超信地旋回
#片方だけの旋回よりも倍の速度で旋回が可能。
LF.value(0)
RB.value(0)
LB.value(0)
RF.value(0)
BL.value(0)
utime.sleep(0.6)
#一旦全停止すべての信号を解除
#例外時の対策エリア
except KeyboardInterrupt:
#ctrl+cで全停止させることができる。ここで下の処理に入る。
LF.value(0)
RB.value(0)
LF.value(0)
RF.value(0)
BL.value(0)
YL.value(0)
utime.sleep(0.1)
#動作終了