空き缶を分別して所定の場所に運ぶ.
・フィールドの説明
フィールドは課題2で使用した紙を使用する.
2種類の空き缶(Aタイプ,Bタイプ)をそれぞれ3個づつ用意し,円XにABA,円YにBABとなるように3段づつ積み上げる.
空き缶には色をつけたり文字や記号を書いてもよい.あるいは周囲に紙を張ってもよい.
・基本ルール
競技時間は審判が続行不能と判断するまで,あるいはリタイアするまで.
図のA地点からスタートする.ただし接地している部分はそれぞれの領域内に収まるものとする(線上はOK).上空部分は領域からはみ出していてもよい.
Aタイプの空き缶を円Y内に,Bタイプの空き缶を円X内に運ぶ.
開始の合図から5秒以内にスタートボタンを押す作業を完了すること.
競技が終了するまで,ロボットに触ったり人間が遠隔で操作してはならない.
途中でうまく動かなくなった場合,1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい).
・基本得点の計算方法
運んだ空き缶の数×3点
空き缶を積み重ねて置くことができば場合,2段目の空き缶一つにつき2点加算,3段目の空き缶一つにつき3点加算する.
円内からはみ出している場合,半分以下なら1点減点,半分以上なら2点減点.
間違った円内に空き缶を置いた場合は,1個につき1点減点.
間違った円内の2段目に空き缶を置いた場合は1個につき3点減点,その上にある空き缶は0点.
・技術点の計算方法
以下の動作の精度・スピード・確実性などを含めた技術的な工夫や芸術性について他の全てのチームが20点満点で採点し,その平均点を求める. 得点の目安:
空き缶を探し取りにいくまでの動作 (3点)
空き缶を掴む動作 (3点)
空き缶を運ぶ動作 (2点)
空き缶を置く動作 (2点)
空き缶を積む動作 (3点)
2台のRCXまたはNXT、EV3の連携の良さ(2点)
自立型のロボットとしての形や動作の美しさ、斬新さ(2点)
その他 (3点)
移動させる缶は左右対称である.それを利用して左右にアームをつけて左右の缶を同時につかんで移動させられるようにした.
また,つかんだ缶はキャタピラーを動かすことで持ち上げることが可能である.
このロボットはスタートしたら,最初に添付したコースのGの交差点まで移動して,後は本体を回転させる動作のみでGの交差点から離れずに缶を運ぶ.そのため,Gの交差点でストップする必要があった.そこでカラーセンサーを使用してGの交差点で止まるプログラムを作った.これにより,止まる位置の誤差が少なくなった.ここでは前回の課題が生きた.
EV3本体が後輪の上のあたりについているため,EV3の重さで少し後ろに傾いてバランスが悪くなってしまった.改善策として,車体の前方にモーターとタイヤを取り付けた.特に動いたりするわけではないが,多少バランスはよくなり,支障が無くなった..
当初は缶をできるだけ多く積み上げるようなプログラムを作ろうとしたが,左右のアームの両方で缶をつかむ構造のため微調整がかなり大変だったということ(例えば,超音波センサーを使って左右どちらかの一段目の缶の正確な位置を把握してその上に缶を積むようにしても,車体の傾き具合をかなり正確に制御しないともう片方の一段目の缶の上に缶を積めない)に気づいた.
また,キットのキャタピラーのパーツが少なく,アームの上下運動が制限されて三段目の缶に届きはするが,安定して積んだり置いたりできないということが試行錯誤を繰り返すうちにわかった.
ロボットを作り替える時間がすでになかったこととこれらのことを踏まえて,頑張って左右片方の円で缶を二段積み,もう片方の円で1個の缶を置くというプログラムを作っても,缶を積むときに缶を倒して円から出してしまい,0点になるというリスクを負いながらも最高で11点しか取れない.しかし両方の円に2個ずつ缶を置くと,缶を倒してしまうリスクも減り,最高で12点も取ることができるのでそのようにした.
このような作戦変更のおかげで,練習では10〜12点を安定してとれるようになり,本番でも12点という全チーム最高の基本点を取ることができたので良かった.
充電の状態に左右されないようにモーターの動きは全て時間ではなく角度で制御した.
また,これより前にも述べているが,カラーセンサーを使って缶をつかめる位置で止まるようなプログラムを作った.
#!/usr/bin/env python3 from ev3dev.ev3 import * from time import sleep
ここまでがプログラムの準備
mA = MediumMotor('outA') mH = LargeMotor('outB') mR = LargeMotor('outC') mL = LargeMotor('outD') cs = ColorSensor('in1') #それぞれのモーターとセンサーの名前を定義した cs.mode = 'COL-REFLECT'
mA.reset() mH.reset() mR.reset() mL.reset() #全てのモーターをリセットする
def move_position(R,L,s): #タイヤを動かす関数(変数をいじることで前進したり回転したりする) mR.run_to_rel_pos(position_sp=R, speed_sp=50, stop_action='brake') mL.run_to_rel_pos(position_sp=L, speed_sp=50, stop_action='brake') sleep(s)
def move_arm(x,s): アームを閉じたり開いたりする関数(この時一緒にアームが伸び縮みする) mA.run_to_rel_pos(position_sp=x, speed_sp=100, stop_action='brake') sleep(s)
def move_high(x,s): #キャタピラーを動かしてアームの高さを変える関数 mH.run_to_rel_pos(position_sp=x, speed_sp=130, stop_action='brake') sleep(s)
def move_straight(): #真っ直ぐ進んで交差点Gで止まる関数 t0 = time.time() while time.time() - t0 < 0.3: mR.run_to_rel_pos(position_sp=20, speed_sp=50, stop_action='brake') mL.run_to_rel_pos(position_sp=20, speed_sp=50, stop_action='brake') if cs.value() >= 75: t0 = time.time()
ここまでが定義した関数
move_position(920,920,18) #まっすぐ進んで交差点Gの真下までくる move_position(180,-180,8) #90度車体を回転 move_position(360,360,10) #少しまっすぐ進む move_straight() #交差点Gまで進む
move_arm(700,6) #アームを閉じて一番下の缶をつかむ(乗っている2個の缶が落ちないように) move_position(380,-380,11) #180度車体を回転(乗っている2個の缶が落ちないように一番下の缶を持ちながら) move_arm(-300,6) #缶を離す(一番下の缶が指定された円に入る)
move_high(1500,15) #二段目の缶までアームを上げる move_arm(300,6) #二段目の缶をつかむ move_high(800,10) #少しアームを上げる(2,3段目の缶を持ち上げる)
move_position(-200,200,8) #約90度車体を回転 move_high(-2300,16) #アームを一番下まで下す move_position(-150,135,8) #缶が円に収まるように微調整しながら車体を回転 move_arm(-300,6) #缶を離す(もともと2段目にあった缶を離す反動で積まれている缶が落ちる)
落ちた缶が近くの円の中に入ってしまうと減点になってしまう.練習ではそれで何回か減点されたので運要素も少しあるが安定して10〜12点が取れる.
mA.reset() mH.reset() mR.reset() mL.reset() #最後に全てのモーターをリセット
ロボティクス入門ゼミの集大成としてのロボコンが終わってしまったが,優勝することができたのでとても嬉しかった.途中,方針を変えながらもいい成績を残すことができたので,今後新しい他の何かに挑戦するときの自信に繋がったと思う.
今回の課題では一人一人がプログラムを書くというわけではなく,チームメイトで協力して1つのプログラムを作り上げるというものだった.そのためみんなで意見を出し合って,時には意見の食い違いからお互い強く当たってしまうこともあったが最終的に1つのプログラムを完成させたときにはこれまでの課題とはまた違った達成感を味わうことができた.
今までこのゼミで様々な課題に取り組んできて,試行錯誤を繰り返してプログラムを考えることの大変さを身をもって体験できたと思う.この世の中にはたくさんのプログラムやシステムが存在するが,それらがすべて時間をかけて試行錯誤されてきたものだと考えると先人たちの偉大さを感じることができると思った.