*課題3について [#y8510c02] 青と赤のボールを運搬して、それぞれ所定の350ml缶の上に乗せる #ref(2018b-mission3.png,,100%) **フィールドの説明 [#f22ab02a] フィールドは課題2で使用した紙を使用する。 350ml缶(中が入っていても空でもよい)は逆さまにして使い、ロボットのスタート直後にさいころを振って出た目の番号のところに置く。 その番号と次の番号のところにもダミーの感を置くことができる。ただし6の目が出た場合は6の位置と25�儖幣緡イ譴討い覆ぞ貊蠅覆蕕匹海砲�いてもよいものとする。距離は缶と缶の間の最も近い部分で測る。 空き缶には色を付けたり文字や記号を書いてもよい。あるいは周囲に紙を貼ってもよい。 赤と青のボールは、図のように所定の場所に置いておく。その際、キットに含まれない小さな輪ゴムを使用するものとする。 ** ルール [#s886e49e] ***基本ルール [#sea53814] 競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで 図のX地点またはY地点からスタートする。ただし設置している部分アhそれぞれの領域内に収まるものとする(線上はOK)。上空部分は領域からはみ出していてもよい。 赤いボールを図のピンクのいずれかに置いた缶に、青いボールを図の水入れのいずれかに置いた感に、それぞれ乗せる。 開始の合図から5秒以内にスタートボタンを押す作業を完了すること。 競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。 途中でうまく動かなくなった場合、1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい)。 ***基本得点の計算方法 [#t7f960b5] ボールを1つ乗せれば10点、2つとも乗せればボーナス点としてさらに10点。 ダミーの感を設置したうえで正しい缶に乗せれば、それぞれさらに6点加点する。 ボールを目的の缶に当てることができれば、それぞれ4点。 ボールを同じ領域内の間違った缶に乗せら場合は。それぞれ6点 ボールを同じ領域内の間違った缶に当てた場合は、それぞれ2点 ボールを違う領域内の缶に乗せた場合は、それぞれ2点 ボールを違う領域内の缶に当てた場合は0点 目的の缶をもとの位置(直径7cmの円)から少し出してしまった場合は1点減点、半分以上出してしまった場合は2点または取得した特典の半分のいずれか少ない方減点、その間を完全にだしてしまったときは 点数を半分にする。 ダミーの感が元の位置から移動しても減点はしない。 *ロボット [#x1f83962] #ref(s_IMAG0782.jpg,,100%) 全体図、アームにモーターがついていてかなり重くなり前に傾くことがあったのでEV3を付けてバランスを取っている #ref(s_IMAG0778.jpg,,100%) ボールを探せるように超音波センサーの位置をかなり低いところに付けた *プログラム [#i950f240] **定義 [#p34dbda8] まずはモーターとセンサーの定義をする mL=LargeMotor('outA') #進行方向に対して左側のモーター mR=LargeMotor('outD') #進行方向に対して右側のモーター mA=MediumMotor('outC') #アーム部分のモーター mC=MediumMotor('outB') #ハンド部分のモーター csR=ColorSensor('in1') #ライントレース用のカラーセンサー #csL=ColorSensor('in2') #使わなかったもう一つのライントレース用のカラーセンサー us=UltrasonicSensor('in3') #超音波センサー **ライントレース [#c78216fa] def traceR(): t0=time.time() while time.time()-t0<0.35: if cs.value()<35: turnR2() if 35<=cs.value()<40: turnR1() t0=time.time() if 40<=cs.value()<=50: run1() t0=time.time() if 50<cs.value()<=60: turnL1() t0=time.time() if cs.value()>60: turnL2() t0=time.time() mR.stop() mL.stop() def traceRa(t): t1=time.time() while time.time()-t1<t: if cs.value()<35: turnR2() if 35<=cs.value()<40: turnR1() if 40<=cs.value()<=50: run1() if 50<cs.value()<=60: turnL1() if cs.value()>60: turnL2() mR.stop() mL.stop() これらは課題2でのライントレースのプログラムを流用した 次はライントレースの中身の関数である def turnR1(): mL.run_forever(speed_sp=100,stop_action='brake') mR.stop() def turnL1(): mR.run_forever(speed_sp=100,stop_action='brake') mL.stop() def run1(): mR.run_forever(speed_sp=100,stop_action='brake') mL.run_forever(speed_sp=100,stop_action='brake') def turnR2(): mL.run_forever(speed_sp=100,stop_action='brake') mR.run_forever(speed_sp=-70,stop_action='brake') def turnL2(): mR.run_forever(speed_sp=100,stop_action='brake') mL.run_forever(speed_sp=-70,stop_action='brake') これらも前回のライントレースのプログラムを流用した **それ以外のプログラム [#u544220a] def run2(): #前にゆっくり進む mL.run_forever(speed_sp=50, stop_action='brake') mR.run_forever(speed_sp=50, stop_action='brake') def forword(): #前に少し進む mL.run_to_rel_pos(position_sp=360, speed_sp=500, stop_action='brake') mR.run_to_rel_pos(position_sp=360, speed_sp=500, stop_action='brake') def forword_bit(): #前に一定距離進む mL.run_to_rel_pos(position_sp=20, speed_sp=500, stop_action='brake') mR.run_to_rel_pos(position_sp=200, speed_sp=500, stop_action='brake') def catchup(): while us.value()>=50: #ボールに近づく run2() mR.stop() mL.stop() mC.reset() mC.run_to_abs_pos(position_sp=60 ,speed_sp=20, stop_action='brake') #ハンドを開く time.sleep(3) mA.run_to_abs_pos(position_sp=100, speed_sp=30, stop_action='brake') #腕を下げる time.sleep(4) mC.run_to_abs_pos(position_sp=0, speed_sp=20, stop_action='brake') #ハンドを閉じてボールをつかむ time.sleep(6) mA.run_to_abs_pos(position_sp=0, speed_sp=100, stop_action='hold') #腕を上げる time.sleep(3) def puton_red(): time4=time.time() while us.value>=40: #赤の缶に近づく run2() time_kan=time.time() mC.run_to_rel_abs(position_sp=30, speed_sp=20, stop_action='brake') #ボールを離す time.sleep(1) timenow=time.time() while time.time()-timenow<=time_kan-time4: #缶に近づいた分の距離戻る mL.run_forever(speed_sp=-50, stop_action='brake') mR.run_forever(speed_sp=-50, stop_action='brake') def puton_blue(): while us.value>=40: #青の缶に近づく run() mC.run_to_rel_abs(position_sp=30, speed_sp=20, stop_action='brake') #ボールを離す def direct_one(): time1=time.time() while time.time()-time1<=20: mL.run_forever(speed_sp=-50, stop_action='brake') mR.run_forever(speed_sp=50, stop_action='brake') 今回は赤の1の缶を基準に缶を探すのでその方向を向くためのプログラム def Round_red(): #赤の缶の周りを回転する time1=time.time() while time.time()-time1<=fuga: mL.run_forever(speed_sp=50, stop_action='brake') mR.run_forever(speed_sp=-50, stop_action='brake') def direct_redkan(): #正しい赤の缶を見分けるためにその周りを回転する time1=time() while time.time()-time1<=fuga-(think_red()-time_start): mL.run_forever(speed_sp=-50, stop_action='brake') mR.run_forever(speed_sp=50, stop_action='brake') def direct_I(): #I地点を向く time1=time.time() while time.time()-time1<=think_red()-time_start+いくらか: mL.run_forever(speed_sp=-50, stop_action='brake') mR.run_forever(speed_sp=50, stop_action='brake') def direct_B(): #B地点を向く time1=time.time() while time.time()-time1<=20: mL.run_forever(speed_sp=-50, stop_action='brake') mR.run_forever(speed_sp=50, stop_action='brake') def Round_blue(): #青の缶の周りを回転する time1=time.time() while time.time()-time1<=fuga2: mL.run_forever(speed_sp=50, stop_action='brake') mR.run_forever(speed_sp=-50, stop_action='brake') def direct_bluekan(): #正しい青の缶を見分けるためにその周りを回転する time1=time() while time.time()-time1<=fuga2-(think_blue()-time_start): mL.run_forever(speed_sp=-50, stop_action='brake') mR.run_forever(speed_sp=50, stop_action='brake') time_start=0 time_a=0 time_b=0 def search(fuga,hoge): #fugaはこのマクロを動かす時間 hogeは最短距離にある缶を探すための適当な距離の値 global time_start global time_a global time_b #globalを用いて他のマクロからtime_bをとってくる 上二つも同様 a=1250 #適当な大きい距離を代入する b=1250 #同上 time0=time_start=time.time() while us.value()>=hoge: #超音波センサの値がhoge以上なら何もしない continue while time.time()-time0<=fuga: #fuga以下の時間実行 if us.value()<=hoge: #超音波センサの値がhoge以下ならば実行 if us.value()<=a: #超音波センサの値がa以下ならば実行 a=us.value() #aに超音波センサの値を代入して更新する time_a=time.time() #time_aにその時の時間を代入 else: #hogeより超音波センサの値が大きいときループを抜ける break while time.time()-time0<=fuga and us.value()>=hoge: #fuga以下の時間かつ超音波センサの値がhoge以上ならば何もしない continue while time.time()-time0<=fuga: #fuga以下の時間実行 if us.value()<=hoge: #超音波センサの値がhoge以上のとき実行 if us.value()<=b: #超音波センサの値がb以下のとき実行 b=us.value() #bに超音波センサの値を代入して更新する time_b=time.time() #time_bにその時の時間を代入 else: #hogeより超音波センサの値が大きいときループを抜ける break def think_red(): if a<b: return time_a else: return time_b 上のプログラムはaとbの大小関係を比べて、それによって戻り値を変え正しい赤の缶を見分けるようにした。 def think_blue(): #青の正しい缶を決める関数を定義 if a<150 and b<150: #1の缶だと決定 return time_b #time_bを戻りとして返す if a<150 and 150<=b<300: #2の缶だと決定 return time_a #time_aを戻り値として返す if 150<=a<300 and 150<=b<300: #3の缶だと決定 return time_a #time_aを戻り値として返す if a<300 and b=1250: #4の缶どと決定 return time_a #time_aを戻り値として返す if a>=300 and b=1250: #5の缶だと決定 return time_b #time_bを戻り値として返す if 450<b<550: #6の缶だと決定 return time_b #time_bを戻り値として返す 上のプログラムはセンサで測ったaとbの値を二つ参照して正しい缶を決定するプログラムである。また決定した後にそこに行くまでの時間でtime_aとtime_bのどちらを採用するかも、このときに決定する。 *問題点 [#pf58304a] ロボットの問題点としてアームが重すぎたという点があった。これによりモーター一つだけではパワーが足りずボールを持ち上げられないという問題が発生した。今回はその問題を解決することができなかったが対策としては、ギア比を変えて力が出るようにする、ボールの持ち上げ方の組み方を変えるなど、いろいろな考え方があったと思う *感想 [#p9fd30cf] 結果としては準備不足により、ミッションを遂行することができ無かった。 本体プログラムともにもっと準備をすれば課題のクリアもできていたと考えるととても悔しい。