黒い線を進み空き缶を移動させるロボットの作成
Aをスタート
Bを直進
Cで一時停止の後、直進
Dで一時停止の後、Xの空き缶をキャッチしてD地点に戻る
DからEに向かい、Eを直進
Fを左折
Gで一時停止の後、左折
Hで一時停止の後、右折
Iで一時停止の後、右折
Lを直進
Kを直進
Jで一時停止の後、空き缶をYに置きてJに戻りBに向かう
Bで一時停止の後、左折
Aで停止
今回はこの課題を達成できなかった.
完成したロボットである.
このロボットは黒い線を認識するためにカラーセンサーが取り付けられている.
また,缶を掴むためにアームも取り付けられている.
黒い線をたどって移動するときは黒い線の境界線をジグザグに移動している.
また,ロボットが一定時間以上黒い線上にいると交差点と判断する.
このとき,カーブは交差点の時よりも黒い線上にいる時間が短くなるので,交差点とは判断せずにそのまま曲がる.
カラーセンサーを取り付ける位置を中心から少しずらすことでブレが大きくなることを利用して,細かい動きでも線上の黒い部分とそれ以外の白い部分との判別をできるようにした.
急なカーブでも曲がれるようにタイヤの回転の速さや時間を調整して,また,交差点と判断する時間をそれぞれのカーブごとで変えたり,同じプログラムを二回続けたりすることで全てのカーブに対応させようとした.しかしこのタイヤの回転の工夫が 欠点 に繋がってしまった.
部屋の場所によって照明の明るさが違い,ロボットの影を黒い線と判断してしまうなどの誤差が生じた.その誤差を減らすためにカラーセンサーが黒い線と判断する数値を高めに設定した.
急なカーブも曲がれるようにしたことでサークルから枝分かれしている道を交差点と判断せず,カーブと判断してそのまま曲がってしまった.この欠点が今回,時間内に課題を達成できなかった原因となった.
#!/usr/bin/env python3 from ev3dev.ev3 import * from time import sleep import time ml = LargeMotor('outA') #左のタイヤ mr = LargeMotor('outD') #右のタイヤ mm = MediumMotor('outB') #アーム cs = ColorSensor('in4') #カラーセンサー cs.mode = 'COL-REFLECT' #カラーセンサーのモード
ここまでがプログラムの準備
def line(x): #基本的なライントレースの関数 mr.reset() ml.reset() t0 = time.time() while time.time() -t0 < x: if cs.value() >= 75: #高めの数値を設定して誤差を減らした mr.run_timed(time_sp=300, speed_sp=80) ml.run_timed(time_sp=300, speed_sp=-40) t0 = time.time() else: mr.run_timed(time_sp=300, speed_sp=-40) ml.run_timed(time_sp=300, speed_sp=80)
def line_s(x): #急なカーブ用のライントレースの関数(しかし失敗) mr.reset() ml.reset() t0 = time.time() while time.time() -t0 < x: if cs.value() >= 75: #高めの数値を設定して誤差を減らした mr.run_timed(time_sp=300, speed_sp=80) ml.run_timed(time_sp=300, speed_sp=40) t0 = time.time() else: mr.run_timed(time_sp=300, speed_sp=40) ml.run_timed(time_sp=300, speed_sp=80)
def line_m(z): #逆側ライントレースの関数 mr.reset() ml.reset() t0 = time.time() while time.time() -t0 < z: if cs.value() >= 75: #高めの数値を設定して誤差を減らした mr.run_timed(time_sp=300, speed_sp=-40) ml.run_timed(time_sp=300, speed_sp=80) t0 = time.time() else: mr.run_timed(time_sp=300, speed_sp=80) ml.run_timed(time_sp=300, speed_sp=-40)
def straight(y): #交差点で直進する関数 mr.run_timed(time_sp=500*y, speed_sp=100) ml.run_timed(time_sp=500*y, speed_sp=50)
def can(a): #缶を掴む関数 mm.reset() mm.run_timed(time_sp=1500, speed_sp=75*a) sleep(2.5)
ここまでが定義した関数である.ただし急なカーブ用のライントレースの関数は成功しなかった.改善の余地があったが時間がなくやむなく断念した.
#1つ目の交差点まで line(0.5) straight(2.3) sleep(2)
#2つ目の交差点まで line(0.65) straight(2.8) sleep(2.5)
#3つ目の交差点まで(ここで空き缶を掴む) line(1.5) mr.run_timed(time_sp=800, speed_sp=75) ml.run_timed(time_sp=800, speed_sp=100) sleep(2) line_m(0.6) line_m(0.5) #1度交差点と判断するがもう1度ライントレースさせることで急なカーブに対応 mr.run_timed(time_sp=900, speed_sp=15) ml.run_timed(time_sp=900, speed_sp=100) sleep(2) can(-1)
#4つ目の交差点まで(空き缶をもって) mr.run_timed(time_sp=800, speed_sp=-15) ml.run_timed(time_sp=800, speed_sp=-100) sleep(2) line_m(0.8) line_m(0.6) line_m(1.2) #1度交差点と判断するがもう1度ライントレースさせることで急なカーブに対応
#5つ目の交差点まで(空き缶をもって) line(2.5) line(0.5) #1度交差点と判断するがもう1度ライントレースさせることで急なカーブに対応
#6つ目の交差点まで(空き缶をもって) mr.run_timed(time_sp=1000, speed_sp=15) ml.run_timed(time_sp=1000, speed_sp=80) sleep(2) line(0.6)
ここまでが成功したプログラムである.一番最初に添付したコースの画像で缶を持った状態でIまで到達する.
ここまで使っていた関数(line)では次の交差点を交差点と判断せず,そのまま曲がってしまったため,違う関数(line_s)を定義して次の交差点を判断できるように数値を調整したかったが時間が足りずうまくいく数値を見つけられなかった.
何度も記載したが今回は課題を達成できなかった.その主な原因として計画通りに進められなかったことがあげられる.今日はここまでやろうと計画しても思ったより時間がかかってしまいそこまで進まなかったということが何度もあり,結果的に最後まで行くことができなかった.
しかし今回の課題でも半分以上のプログラムは成功していたり,失敗してしまった原因が分析できたりしているので,課題を達成できていなくとも無駄ではなかったと思う.次回の課題では今回使ったのと同じコースを使用するので,プログラムの成功した部分をうまく生かし,さらに少し余裕をもって計画を立てていき,今度こそは課題をしっかり達成したい.