課題の内容

経路1

フィールドの説明 フィールドは課題2で使用した紙を使用する。 〇350ml缶(中が入っていても空でよい)は逆さまにして使い、ロボットのスタート直後にサイコロを〇振って出た目の番号の位置に置く。 〇その番号の次の番号のところにもダミーの缶を置くことができる。ただし6の目が出た場合は6の〇位置と25cm以上離れていない場所ならどこに置いてもよいものとする。距離は缶と缶のもっとも近い部分で測る。 空き缶には色をつけたり文字や記号を書いてもよい。あるいは周囲に紙を張ってもよい。 赤と青のボールは、図のように所定の場所に置いておく。その際、キットに含まれない小さな輪ゴムを使用するものとする。

ルール

基本ルール

競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで。 図のX地点または(および)Y地点からスタートする。ただし接地している部分はそれぞれの領域内に収まるものとする(線上はOK)。上空部分は領域からはみ出していてもよい。

赤いボールを図のピンクのいずれかに置いた缶に、青いボールを図の水色のいずれかに置いた缶に、それぞれ乗せる。

開始の合図から5秒以内にスタートボタンを押す作業を完了すること。

競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。

途中でうまく動かなくなった場合、1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい)。

基本得点の計算方法

ボールを一つ乗せればそれぞれ10点、二つとも乗せればボーナス点としてさらに10点。

ダミーの缶を設置した上で、正しい缶に乗せれば、それぞれさらに6点加点する。

ボールを目的の缶に当てることができれば、それぞれ4点。

ボールを同じ領域内の間違った缶に乗せた場合は、それぞれ6点。

ボールを同じ領域内の間違った缶に当てた場合は、それぞれ2点。

ボールを違う領域内の缶に乗せた場合は、それぞれ2点。

ボールを違う領域内の缶に当てた場合は、0点。

目的の缶をもとの位置(直径7cmの円)から少し出してしまった場合は1点減点、半分以上出してしまった場合は2点または取得した得点の半分のいずれか少ないほうを減点、その缶を完全にだしてしまったときは点数を半分にする。

ダミーの缶がもとの位置から移動しても減点はしない。

技術点の計算方法

以下の動作の精度・スピード・確実性などを含めた技術的な工夫や芸術性について他の全てのチーム(5チーム)が20点満点で採点し、その平均点を求める。

得点の目安:

ボール探し取りにいくまでの動作 (3点)

ボール掴む動作 (3点)

ボールを運ぶ動作 (2点)

ボールを缶に置く動作 (2点)

2台のNXT、EV3の連携の良さ(2点)

自立型のロボットとしての形や動作の美しさ、斬新さ(2点)

その他 (3点)

ロボット

ロボットの全体図

経路1
経路1
ボールの動き

ロボットを作る過程

今回の課題を進めるうえでまず作ろうとしたのはベルトコンベアを使ってフォークリフトのようにボールを上げるものだった。

経路1

しかしこの機構は大きくかさばったり重くてロボットのバランスが悪くなってしまったりと様々な問題が起こったのでこの機構は使わなかった。 そのあとに考えたのがコンベアを使ってボールをすくい上げ、それを転がして間の中に入れるというものである。

この見た目からもわかるように超音波センサがある方を前とするとボールを放つ機構が車体の前方に、ボールを持ち上げるコンベアが車体の後方にあるので車体にかかる重心のバランスが良いという利点がある。よってこの方法ならうまくいきそうだと考え、今回のロボットの制作に取り掛かった。

車体

車体については全体図からもわかるように説明書でみられるような比較的スタンダードな形のものにしてある。

今回はボールを取るときと、前に進むとききっちりと180度車体の向きを変える必要があるためジャイロセンサーを使用した。

ジャイロセンサー

↑ジャイロセンサー

これを使うと車体を回転させたときの角度を測れるようになりセンサーが正確なら毎回同じだけ回転してくれる

工夫した点としては、車体の前頭部に付けた2つの角を作ったことである。この役割は缶とロボットが少し左右にずれてしまったときこの角の部分にあてることで、減点しない程度に缶を動かしロボットとの距離を修正するというものである。

経路1

ボールを投げるとき...↓

経路1

このようになる。

ボールを扱う機構

ボールの動き

↑図のようにボールが上がっていき転がって缶の上に置かれる

この機構を使う上でまず気を付けなければならないのはどのようにボールを上げるかということである。解決法としてはコンベアにかきづめのようなものを付け、車体とコンベアでボールを挟んで持ち上げることにした。コンベアと壁で挟まれているうちはボールを持ったまま保管でき、放つときにはボールを車体の上まで上げれば自然に転がっていく。

経路1

図の黄色く囲まれた場所がかきづめの役割を果たす。

またかきづめは二つ付けてあるので1度に赤いボール、青いボールどちらも保持することができる。 これで一回球を置いてからもう一つの球を取りに行く手間を省くことができる。

ボールを乗せる

コンベアの図 2つかきづめがある

ボールを乗せる

↑ボールが二つのる。コンベアを途中で止めれば、どちらか片方だけのボールを放出することも可能

また後ろにコンベアを付けることで超音波センサーがボールを持つ機構の動きにとらわれずいつでも缶の位置を把握できるようになった。

続いてボールを転がす機構について説明する。基本的には滑り台のようにボールを転がした。この際ただ転がすだけだとボールの勢いが強く缶を大きくはみ出し落ちてしまうので、勢いを相殺するための壁のようなものを取り付けた。

あまり硬い防護壁のようなものを作ってしまうと、ロボットが缶に近づいたときに壁に当たって缶が動いてしまったり、ロボットと缶の距離が少しでも離れると缶の上に落ちてくれなくなるので割と簡単な力で動くように作った。そうすることで缶のような重いものに当たっいても間違えて動かしてしまうことはなく、ボールのような軽いものに対しては効果を発揮してくれる。

ボールの動き

プログラミング

#!/usr/bin/env python3
from ev3dev.ev3 import *
import time
ml=LargeMotor('outA') *
mr=LargeMotor('outD')
ma=LargeMotor('outB')
cs=ColorSensor('in3')
us=UltrasonicSensor('in4')
gs=GyroSensor('in1')
def stop(): #ロボットを停止させる
       ml.stop()
       mr.stop()
def linetrace_rin(): #線の左側のライントレース 交差点で止まる
       c1=cs.value()
       while c1>13:
               c1=cs.value()
               x=(abs(c1-10)/70)*100
               if x>100:
                       x=100
               l=(x/100)*210-30
               r=150-l
               ml.run_forever(speed_sp=l,stop_action='brake')
               mr.run_forever(speed_sp=r,stop_action='brake')
       stop()
def linetrace_lin(): #線の右側のライントレース 交差点で止まる
       c1=cs.value()
       while c1>13: 
               c1=cs.value()
               x=abs((c1-10)/70)*100
               if x>100:
                       x=100
               r=(x/100)*210-30
               l=150-r
               ml.run_forever(speed_sp=l,stop_action='brake')
               mr.run_forever(speed_sp=r,stop_action='brake')
       stop()
def linetrace_ltime(j): #ある程度時間がたってから実行するプログラム。これは缶の位置が5か6の時に缶にある程度近づいたらライントレースをやめさせるためのものである。
       c1=cs.value()
       t1=time.time()
       t2=time.time()
       while t2-t1<j:
               c1=cs.value()
               t2=time.time()
               x=abs((c1-10)/70)*100
               if x>100:
                       x=100
               r=(x/100)*210-30
               l=150-r
               ml.run_forever(speed_sp=l,stop_action='brake')
               mr.run_forever(speed_sp=r,stop_action='brake')
       stop()
def linetrace_lout(): #左側のライントレース 交差点で止まらない
       c1=cs.value()
       while c1<40:
               c1=cs.value()
               x=(abs(c1-10)/70)*100
               if x>100:
                       x=100
               r=(x/100)*120-40
               l=40-r
               ml.run_forever(speed_sp=l,stop_action='brake')
               mr.run_forever(speed_sp=r,stop_action='brake')
       stop()

今回の課題のライントレースでは定義を4つ利用した。

def runtime(l,r): #ロボットの動きを左右で別に動かす
       ml.run_timed(time_sp=l*1000,speed_sp=70,stop_action='brake')
       mr.run_timed(time_sp=r*1000,speed_sp=70,stop_action='brake')
       time.sleep((l+r)/2)
def angle(l,r,t): #指定した角度だけタイヤを動かす。lは左タイヤの角度、rは右タイヤの角度、tはスリープする時間
       ml.run_to_rel_pos(position_sp=l,speed_sp=115,stop_action='hold')
       mr.run_to_rel_pos(position_sp=r,speed_sp=115,stop_action='hold')
       time.sleep(t)
def kaiten_r(s,t): #ジャイロセンサーのとる値を使って右回転させる
       g1=gs.value()
       g2=gs.value()
       while g2-g1<s: #ボールを探す範囲を指定する
               ml.run_forever(speed_sp=t,stop_action='hold')
               mr.run_forever(speed_sp=-t,stop_action='hold')
               g2=gs.value()
       stop()
def kaiten_l(s,t):  #ジャイロセンサーのとる値を使って左回転させる
       g1=gs.value()
       g2=gs.value()
       while g1-g2<s:
               ml.run_forever(speed_sp=-t,stop_action='hold')
               mr.run_forever(speed_sp=t,stop_action='hold')
               g2=gs.value()
       stop()
def g(): #g1の値をプリントする
       g1=gs.value()
       while g1<10000:
               g1=gs.value()
               print(g1)
def roll(s): #ベルトコンベアを動かす際に使われる。
       ma.run_to_rel_pos(position_sp=s,speed_sp=80,stop_action='hold')
       time.sleep(3)
def discover_l(s,t): #缶を探す際に使われる。この場合は右回りで探す。
       u1=us.value()
       g1=gs.value()
       g2=gs.value() 
       while g1-g2<s: ジャイロセンサーが缶を探す範囲を向くときのみ動かす
               u2=us.value()
               ml.run_forever(speed_sp=-70,stop_action='hold')
               mr.run_forever(speed_sp=70,stop_action='hold')
               g2=gs.value()
               if u2<u1: #超音波センサーを更新した時、その値が最小値だった場合はその値をu1に保存しておく。後の値は無視
                       u1=u2
                       g3=gs.value()
       ml.run_forever(speed_sp=70,stop_action='hold')
       mr.run_forever(speed_sp=-70,stop_action='hold')
       g4=gs.value()
       g5=gs.value()
       if u1<=t:#測定した時に缶が見つかった場合
               while g5-g4<g3-g2-6: #測り始めた位置まで戻るプログラム
                       mr.run_forever(speed_sp=-70,stop_action='hold')
                       ml.run_forever(speed_sp=70,stop_action='hold')
                       g5=gs.value()
               stop()
               u3=us.value()
               t1=time.time()
               while u3<2550: #超音波センサーが観測できる限界に近づいたときループから抜ける
                       ml.run_forever(speed_sp=100,stop_action='hold')
                       mr.run_forever(speed_sp=100,stop_action='hold')
                       u3=us.value()
                       t2=time.time()
               stop()
               roll(220) #ボールを発射する
               ml.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold')
               mr.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold')
               time.sleep(t2-t1)
               g6=gs.value()
               g7=gs.value()
               while g7-g6<=g1-g3-6: #缶の位置に到達するまで右回りする -6でジャイロセンサーの誤差を埋めた
                       mr.run_forever(speed_sp=-70,stop_action='hold')
                       ml.run_forever(speed_sp=70,stop_action='hold')
                       g7=gs.value()
               stop()
       else: #測定した時に缶が見つからなかった場合
               while g5-g4<90:
                       mr.run_forever(speed_sp=-70,stop_action='hold')
                       ml.run_forever(speed_sp=70,stop_action='hold')
                       g5=gs.value()
               stop()
def discover_r(s,t): #右回りで缶を探すとき。基本は前述したとおり。
       u1=us.value()
       g1=gs.value()
       g2=gs.value()
       while g2-g1<s:
               u2=us.value()
               ml.run_forever(speed_sp=70,stop_action='hold')
               mr.run_forever(speed_sp=-70,stop_action='hold')
               g2=gs.value()
               if u2<u1: 
                      u1=u2
                       u1=u2
                       g3=gs.value()
       ml.run_forever(speed_sp=-70,stop_action='hold')
       mr.run_forever(speed_sp=70,stop_action='hold')
       g4=gs.value()
       g5=gs.value()
       if u1<=t: 
               while g4-g5<g2-g3-6:
                       mr.run_forever(speed_sp=70,stop_action='hold')
                       ml.run_forever(speed_sp=-70,stop_action='hold')
                       g5=gs.value()
               stop()
               u3=us.value()
               t1=time.time()
               while u3<2550:
                       ml.run_forever(speed_sp=100,stop_action='hold')
                       mr.run_forever(speed_sp=100,stop_action='hold')
                       u3=us.value()
                       t2=time.time()
               stop()
               roll(220)
               ml.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold')
               mr.run_timed(speed_sp=-100,time_sp=(t2-t1)*1000,stop_action='hold')
               time.sleep(t2-t1)
               g6=gs.value()
               g7=gs.value()
               while g6-g7<=g3-g1-6:
                       mr.run_forever(speed_sp=70,stop_action='hold')
                       ml.run_forever(speed_sp=-70,stop_action='hold')
                       g7=gs.value()
               stop()
       else: 
               while g4-g5<90:
                       mr.run_forever(speed_sp=70,stop_action='hold')
                       ml.run_forever(speed_sp=-70,stop_action='hold')
                       g5=gs.value()
def Redball(): #スタートから赤いボールを取るまでの指令の定義
       angle(250,250,3)
       kaiten_r(180,110)
       roll(220)
       kaiten_r(195,110)
       linetrace_lin()
def Blueball(): #スタートから青いボールを取るまでの指令の定義
       angle(-20,160,2)
       linetrace_lin()
       angle(-35,-35,1.5)
       kaiten_r(175,110)
       roll(220)
def move(): #青ボールを拾った後、Eに行くまでのロボットの動き
       kaiten_r(190,110)
       angle(-50,-50,1)
       linetrace_lin()
       linetrace_lout()
       linetrace_lin()
       linetrace_lout()
       linetrace_lin()
def BlueZone(): #赤いボールを乗せてから青いボールを探すまでのプログラム
       linetrace_rin()
       linetrace_rout()
       linetrace_rin()
       angle(0,70,1)
       linetrace_rin()
       angle(70,0,1)
       linetrace_rin()
def discover2(): #青ボールを探してから青ボールを投げるまでのプログラム
       kaiten_l(60,100)
       discover_r(90,500)
def start(): #今回の課題でさせる命令の定義。この命令一つですべての作業が完了するようになっている。
       r=int(input("insert numbera")) #缶がどの位置にあるのかを入れる
       Redball() 
       Blueball()
       move()
       if r<=2: #缶が1か2にある場合缶を探すプログラム
               kaiten_l(90,110)
               discover_l(90,250)
               kaiten_l(95,100)
       if r==3: #缶が3にある場合缶を探すプログラム
               angle(-40,180,2)
               linetrace_lin()
               discover_r(60,250)
               angle(-150,-150,2)
               kaiten_l(195,110)
               linetrace_rin()
               angle(230,-40,2)
       if r==4: #缶が4にある場合缶を探すプログラム
               angle(-40,180,2)
               linetrace_lin()
               discover_l(60,250)
               kaiten_l(195,110)
               linetrace_rin()
               angle(230,-40,2)
       if 5<=r: #缶が5か6にある場合缶を探すプログラム
               angle(-40,180,2)
               linetrace_lin()
               linetrace_lout()
               linetrace_ltime(3)
               discover_l(60,190)
               angle(-130,-130,3)
               kaiten_l(180,110)
               linetrace_rin()
               linetrace_rout()
               linetrace_rin()
               angle(230,-40,2)
       BlueZone()
       discover2()
start() #実際に動作をさせるプログラム

反省

今回はテスト期間に制作をしたのでほとんど時間が取れなかった。そのため完成にこぎ付けるかどうか不安要素は大きかったが時間に余裕をもって完成させることができた。

最後の調整の段階では失敗することはほとんどなかったが、本番は一個目のボールを缶に乗せた後にライントレースにたどり着けずそのまま失敗してしまった。

おそらく失敗の原因は、2つ配られていたジャイロセンサーの感度があまりよくなく、動作させるたびに少しずれてしまったことであった。もしもう一度作る機会があるとするならば、今度はジャイロセンサーの値が少しずれても、ある程度ロボットの構造や動きで修正できるものにしたい。

閲覧回数

総計:84 今日:1 昨日:0


添付ファイル: files_bear.jpg 7件 [詳細] files_cancan.jpg 11件 [詳細] files_tuno.jpg 10件 [詳細] files_double.jpg 9件 [詳細] files_can.jpg 8件 [詳細] files_yoko.jpg 11件 [詳細] file2018b-mission3.png 8件 [詳細] filejailo.jpg 10件 [詳細] files_korokoro.1.jpg 7件 [詳細] files_belt.jpg 9件 [詳細] files_usiro.jpg 7件 [詳細] files_mae.jpg 10件 [詳細] files_syatai3.jpg 3件 [詳細] files_folk.jpg 7件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-02-13 (水) 13:30:48 (193d)