- 追加された行はこの色です。
- 削除された行はこの色です。
[[2018a/Member]]
*目次 [#e0879845]
#contents
*課題2:空き缶運搬ロボット [#w7748c4f]
黒い線を進み空き缶を移動させるロボットの作成
#ref(./2018a-mission2.png,コース)
~Aをスタート
~Bを直進
~Cで一時停止の後、直進
~Dで一時停止の後、Xの空き缶をキャッチしてD地点に戻る
~DからEに向かい、Eを直進
~Fを左折
~Gで一時停止の後、左折
~Hで一時停止の後、右折
~Iで一時停止の後、右折
~Lを直進
~Kを直進
~Jで一時停止の後、空き缶をYに置きてJに戻りBに向かう
~Bで一時停止の後、左折
~Aで停止
#br
~ 今回はこの課題を達成できなかった.
*ロボット [#pd591458]
**空き缶運搬ロボット [#a59aa36d]
完成したロボットである.
#ref(./1531736088095.jpg,ロボット)
このロボットは黒い線を認識するためにカラーセンサーが取り付けられている.
#ref(./1531736091508.jpg,センサー)
また,缶を掴むためにアームも取り付けられている.
#ref(./1531736093243.jpg,)
**ロボットの仕組み [#d52ad2ec]
~ 黒い線をたどって移動するときは黒い線の境界線をジグザグに移動している.
#ref(./sketch-1533534493720.png,ライントレース)
~ また,ロボットが一定時間以上黒い線上にいると交差点と判断する.
#ref(./sketch-1533534494394.png,交差点判断)
~ このとき,カーブは交差点の時よりも黒い線上にいる時間が短くなるので,交差点とは判断せずにそのまま曲がる.
#ref(./sketch-1533534495056.png,カーブの曲がり方)
**工夫した点 [#h1bb9b19]
カラーセンサーを取り付ける位置を中心から少しずらすことでブレが大きくなることを利用して,細かい動きでも線上の黒い部分とそれ以外の白い部分との判別をできるようにした.
*プログラミング [#bd6a4040]
**工夫した点 [#j24a2afc]
~ 急なカーブでも曲がれるようにタイヤの回転の速さや時間を調整して,また,交差点と判断する時間をそれぞれのカーブごとで変えたり,同じプログラムを二回続けたりすることで全てのカーブに対応させようとした.しかしこのタイヤの回転の工夫が 欠点 に繋がってしまった.
~ 部屋の場所によって照明の明るさが違い,ロボットの影を黒い線と判断してしまうなどの誤差が生じた.その誤差を減らすためにカラーセンサーが黒い線と判断する数値を高めに設定した.
**欠点 [#w451e60b]
急なカーブも曲がれるようにしたことでサークルから枝分かれしている道を交差点と判断せず,カーブと判断してそのまま曲がってしまった.この欠点が今回,時間内に課題を達成できなかった原因となった.
**プログラム [#n9035754]
#!/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)を定義して次の交差点を判断できるように数値を調整したかったが時間が足りずうまくいく数値を見つけられなかった.
*反省点など [#fd64fb4f]
~ 何度も記載したが今回は課題を達成できなかった.その主な原因として計画通りに進められなかったことがあげられる.今日はここまでやろうと計画しても思ったより時間がかかってしまいそこまで進まなかったということが何度もあり,結果的に最後まで行くことができなかった.
~ しかし今回の課題でも半分以上のプログラムは成功していたり,失敗してしまった原因が分析できたりしているので,課題を達成できていなくとも無駄ではなかったと思う.次回の課題では今回使ったのと同じコースを使用するので,プログラムの成功した部分をうまく生かし,さらに少し余裕をもって計画を立てていき,今度こそは課題をしっかり達成したい.