2019a/Member

目次

課題2

課題内容

黒線に沿い、コースを進み途中の地点でピンポン球を掴みゴールにシュートする課題

コース 

大まかなコースの説明をする。
A→B→C→D(一時停止あり)→E→F→G(一時停止あり)→H→I→J→K→L(ピンポン玉)→K→M(一時停止あり)→シュート→Aである。

ko-su3.png

制作したロボット 

機体は動かしやすいようにシンプルな機構

aa.jpg

ボールを捉えやすいようにアームを真ん中へ

aaa.jpg

差が減るようにセンサーも真ん中へ

aaaa.jpg

プログラム

始めの定義

ev3devのpythonライブラリ、sleep関数諸々を導入するところから始める。カラーセンサーmode = 'COL-REFLECT'では明るいほど高い値を出す。0〜100までの値である。mLは左のラージモーター、mRは右のラージモーターに対応する。mmはミディアムモーターで今回はボールを回収、放出の役割を果たす。

#!/usr/bin/env python3
from ev3dev.ev3 import *
from time import sleep
mL = LargeMotor('outA')
mR = LargeMotor('outB')
mm = MediumMotor('outC')
cs = ColorSensor('in2')
cs.mode = 'COL-REFLECT'

ロボットを動かす定義をしていく、l()は左前に進み、r()は右前に進む。time_spを小さくすることでなるべく脱線しないように配慮。f(a)は前進、b()は後退。こちらはtime_spを少し大きくしspeed_spを小さくすることでラインの値を変に読まないように配慮。

def r():
    mL.run_timed(time_sp=1,speed_sp=550,stop_action='brake')
    mR.run_timed(time_sp=1,speed_sp=60,stop_action='brake')
def l():
    mL.run_timed(time_sp=1,speed_sp=60,stop_action='brake')
    mR.run_timed(time_sp=1,speed_sp=550,stop_action='brake')
def f(a):
    mL.run_timed(time_sp=10+a,speed_sp=150,stop_action='brake')
    mR.run_timed(time_sp=10+a,speed_sp=150,stop_action='brake')
def b():
    mL.run_timed(time_sp=20,speed_sp=-50,stop_action='brake')
    mR.run_timed(time_sp=20,speed_sp=-50,stop_action='brake')

magaru(m,n,o,p)は90度回転して元の位置に戻る、というものである。magaru(1,0,0,1)で右回転、magaru(0,1,1,0)で左回転する。ziyuu(x,y,X,Y)を定義しとくことにより後々のプログラムを簡潔にする。armage()はアームをあげてボールを回収、armsage()ではアームをさげてボールを射出。

def magaru(m,n,o,p):
    mL.run_timed(time_sp=400,speed_sp=1000*m,stop_action='brake')
    mR.run_timed(time_sp=400,speed_sp=1000*n,stop_action='brake')
    sleep(1)
    mL.run_timed(time_sp=350+o*100,speed_sp=-350,stop_action='brake')
    mR.run_timed(time_sp=350+p*100,speed_sp=-350,stop_action='brake')
    sleep(1)
def ziyuu(x,y,X,Y):
    mL.run_timed(time_sp=x,speed_sp=y,stop_action='brake')
    mR.run_timed(time_sp=X,speed_sp=Y,stop_action='brake')
def armage():
    mm.run_to_abs_pos(position_sp=80,speed_sp=100,stop_action="hold")
    sleep(0.1)
def armsage():
    mm.run_to_abs_pos(position_sp=-80,speed_sp=100,stop_action="hold")
    sleep(0.1)

ライントレース

ライントレースに使ったプログラムを説明する。
図 1.png 図 2.png

print (cs.value())でカラーセンサーの値を調べたところ赤丸1では70以上、赤丸2では50ほど、赤丸3では10以下であることが分かった。図1ではcs.value()の値が50ほどで前進させ、図2はcs.value()の値が20以下の時右前に進ませて、図3では60以上の時左前に進ませる。図4ではcs.value()の値が70以上で後退させる。なおこの基準ではかなりの範囲でかぶっているので、elifを使うことでその問題を解決した。これによりおおまかな値で定義し、より正確にラインをたどれるようにした。

なお最初にst=cs.value()と書き、whileの中にne=cs.value()を入れ、whileの最後にst=neと書くことで前回計測したcs.value()を保持することが出来た。これにより図5では連続的、つまり2回黒を計測するとL字や十字路と判断するようにした。この2回計測させる、ということが1番の工夫である、1度ではカーブ時などに勘違いしてL字や十字路だと思い誤作動を起こすが二回黒のかなり低い値、st<10 and ne<10にしておくことで誤作動が激減した。

ganbaru()関数は最初にs=0を置き、黒二回計測、つまり交差点or”「 ” この形の時にsに1を加える、if,elif,elseを使い、ライントレースを制御、sが2以上になればwhileから抜けだし動作終了。細かいライントレースに用いる。(主にゴール前)

ganbare()関数は基本的にはganbaru()関数と同じで、BからIに移動させるためtの限界値はaと設定し、長めにライントレース、つまり交差点or”「 ” の形を何度も計測し動作し続けるものとなっている。これを実現するために siraberu()関数を定義し組み込んである、これは後述する。

def ganbaru():
        s=0
        st=cs.value()
        while s <= 1:
            ne=cs.value()
            if st>70 or ne>70:
                b()
            elif st<10 and ne<10:
                s=s+1
                sleep(1)
            elif ne>60:
                l()
            elif ne<20:
                r()
            else:
                f(0)
            st=ne


def ganbare(a):
        t=0
        st=cs.value()
        while t <= a:
            ne=cs.value()
            if st>70 or ne>70:
                b()
            elif st<10 and ne<10:
                siraberu()
                sleep(3)
                t=t+1
            elif ne>60:
                l()
            elif ne<20:
                r()
            else:
                f(0)
            st=ne

siraberu()関数を説明する。

図111.png

図のように黒を二度観測、つまり交差点or”「 ” の形、Tにあたれば、まず右前に移動し左右に首を揺らし、二つ目の赤の地点と矢印の地点、左、右のcs.value()を観測する、それぞれ順番にss0、ss1、ss2と定義する。そして一旦元の位置に戻り、ss0、ss1、ss2の値によって行動を分岐させる。

図のように交差点であれば左は黒を観測し右は何も観測しない、この場合はD地点でおこる、すなわち前進させる必要がある。elseで対応させ、 f(300)前進。簡単に説明したのが下図である。

図あうあう.png ううう図.png

なお出っ張りがない部分は円のところもあり、誤作動がないようこまかく調整した。if ss0 > 65 and ss1 > 70 and ss2 > 65;においてmagaru(1,0,0,1)、つまり90度旋回する様になっている。

これらによって交差点or”「 ” の形、Tに完全に対応させた。

def siraberu():
     mR.run_timed(time_sp=400,speed_sp=200,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=100,stop_action='brake')
     sleep(0.4)
     ss0=cs.value()
     sleep(0.5)
     mR.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
     sleep(0.4)
     ss1=cs.value()
     sleep(0.5)
     mR.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
     sleep(0.4)
     mR.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
     sleep(0.4)
     ss2=cs.value()
     sleep(0.5)
     mR.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
     sleep(0.4)
     mR.run_timed(time_sp=400,speed_sp=-200,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=-100,stop_action='brake')
     sleep(1)
     while True:
         if ss0 > 65 and ss1 > 70 and ss2 > 65:
             sleep(1)
             magaru(1,0,0,1)
             break

         else:
             f(300)
             break

実装プログラム

プログラム全文は以下に記載する。

#!/usr/bin/env python3
from ev3dev.ev3 import *
from time import sleep
mL = LargeMotor('outA')
mR = LargeMotor('outB')
mm = MediumMotor('outC')
cs = ColorSensor('in2')
cs.mode = 'COL-REFLECT'


def r():
    mL.run_timed(time_sp=1,speed_sp=550,stop_action='brake')
    mR.run_timed(time_sp=1,speed_sp=60,stop_action='brake')
def l():
    mL.run_timed(time_sp=1,speed_sp=60,stop_action='brake')
    mR.run_timed(time_sp=1,speed_sp=550,stop_action='brake')
def f(a):
    mL.run_timed(time_sp=10+a,speed_sp=150,stop_action='brake')
    mR.run_timed(time_sp=10+a,speed_sp=150,stop_action='brake')
def b():
    mL.run_timed(time_sp=20,speed_sp=-50,stop_action='brake')
    mR.run_timed(time_sp=20,speed_sp=-50,stop_action='brake')
def magaru(m,n,o,p):
    mL.run_timed(time_sp=400,speed_sp=1000*m,stop_action='brake')
    mR.run_timed(time_sp=400,speed_sp=1000*n,stop_action='brake')
    sleep(1)
    mL.run_timed(time_sp=350+o*100,speed_sp=-350,stop_action='brake')
    mR.run_timed(time_sp=350+p*100,speed_sp=-350,stop_action='brake')
    sleep(1)
def ziyuu(x,y,X,Y):
    mL.run_timed(time_sp=x,speed_sp=y,stop_action='brake')
    mR.run_timed(time_sp=X,speed_sp=Y,stop_action='brake')
def armage():
    mm.run_to_abs_pos(position_sp=80,speed_sp=100,stop_action="hold")
    sleep(0.1)
def armsage():
    mm.run_to_abs_pos(position_sp=-80,speed_sp=100,stop_action="hold")
    sleep(0.1)


def siraberu():
     mR.run_timed(time_sp=400,speed_sp=200,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=100,stop_action='brake')
     sleep(0.4)
     ss0=cs.value()
     sleep(0.5)
     mR.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
     sleep(0.4)
     ss1=cs.value()
     sleep(0.5)
     mR.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
     sleep(0.4)
     mR.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
     sleep(0.4)
     ss2=cs.value()
     sleep(0.5)
     mR.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
     sleep(0.4)
     mR.run_timed(time_sp=400,speed_sp=-200,stop_action='brake')
     mL.run_timed(time_sp=400,speed_sp=-100,stop_action='brake')
     sleep(1)
     while True:
         if ss0 > 65 and ss1 > 70 and ss2 > 65:
             sleep(1)
             magaru(1,0,0,1)
             break

         else:
             f(300)
             break

def ganbaru():
        s=0
        st=cs.value()
        while s <= 1:
            ne=cs.value()
            if st>70 or ne>70:
                b()
            elif st<10 and ne<10:
                s=s+1
                sleep(1)
            elif ne>60:
                l()
            elif ne<20:
                r()
            else:
                f(0)
            st=ne


def ganbare(a):
        t=0
        st=cs.value()
        while t <= a:
            ne=cs.value()
            if st>70 or ne>70:
                b()
            elif st<10 and ne<10:
                siraberu()
                sleep(3)
                t=t+1
            elif ne>60:
                l()
            elif ne<20:
                r()
            else:
                f(0)
            st=ne

導入と先ほど説明した定義である。

ganbare(6)
sleep(1)

BからHに移動、ここが最も難所で成功率は高くない。

ganbaru()
sleep(1)

HからJに移動

magaru(1,0,0,1)
sleep(1)

90度回転

ganbaru()
sleep(1)

JからKに移動

magaru(0,1,1,0)
sleep(1)

90度回転

f(50)
sleep(1)

armage()

玉を回収する、この部分も誤差が大きい時は回収出来ない。

ganbare(1)
sleep(1)

armsage()

ゴールまで行き、アームを下ろした。

反省

課題達成に必死、自己流の工夫が余りできていない。ロボットの形は機構だったが、プログラムが全く機能しないなどの苦労が多かった。ライントレースが正確になるまでの調整が特に大変。難所の円部分で誤作動する可能性が高いことを解決出来なかった


添付ファイル: fileううう図.png 98件 [詳細] file図あうあう.png 106件 [詳細] file図111.png 92件 [詳細] file図 2.png 103件 [詳細] file図 1.png 91件 [詳細] fileaaaa.jpg 102件 [詳細] fileaaa.jpg 98件 [詳細] fileaa.jpg 127件 [詳細] filerobo1.jpg 58件 [詳細] fileS__70647823.jpg 87件 [詳細] fileko-su3.png 99件 [詳細] fileko-su2.png 54件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-08-15 (木) 00:38:43