#author("2019-12-26T10:52:11+09:00","kurisuke","kurisuke") [[2019b/Member]] 目次 #contents *課題2 [#e4a51b43] 下の図のようなコースを各チームで作成し,A地点を出発し,黒い線に沿って進み,Iに置かれたボールをキャッチして出発点に戻るロボットを作成せよ. 私は,コース1を選択した.コース1は下図の赤線の通りで,A-B-D-E-F-G-H-I-J-Aの順番で進む.交差点では1秒間停止し,T字路では直角方向に進入する時のみ一時停止する. &ref(2019b/Member/kurisuke/Mission2/Inked2019b-mission2_LI.jpg,100%,コース図); **今回のポイント [#r93b0d77] 黒線を正確にトレースして進むことができるか,交差点を認識して止まることができるかが大きなポイントであった.また,ロボットのスピードなどもあった. *ロボットの説明 [#p4b74d62] **掴む機構 [#af220d59] 掴む機構は,しっかりつかみたかったので両側からアームでボールををつかむ機構にした.歯車でモーターによる縦回転を横回転にしてアームが動くようにした. &ref(2019b/Member/kurisuke/Mission2/S__5455883_LI.jpg,30%,掴む機構); **車体の構造 [#u8debd6b] 基本的な構造は,NXTの設計例に載っているものとほとんど変わらないが,光センサーの取り付ける位置をなるべく床に近づけたいことや,タイヤとの位置を近くしたいということをで下の図のように位置を変えた.これにより,設計例に載っていた車体よりも正確にライントレースすることが可能になっ.また,急カーブや曲がり角の時のロボットと黒線のズレを小さくすることができた. &ref(2019b/Member/kurisuke/Mission2/ロボットの車体.jpg,30%,ロボットの車体); &ref(2019b/Member/kurisuke/Mission2/光センサーの位置.jpg,30%,光センサーの位置); *プログラムの説明 [#k2e277be] **定義 [#tde25d57] プログラムを簡潔にするため,値の変更を簡単にするために以下のように定義した.右左折や旋回は曲がりたい方向のモータを進行方向と逆向きに回転させることで黒線とのずれを少なくし,スムーズにロボットが動くようにした.値に関しては,一般化しようと試みたが時間が足りず何度も実験を重ねる(力技)で導き出した. #define turn_right OnFwd(OUT_C,28); OnFwd(OUT_B,-18); //右折 #define turn_left OnFwd(OUT_B,25); OnFwd(OUT_C,-15); //左折 #define around_right OnFwd(OUT_C,20); OnFwd(OUT_B,-25); //右旋回 #define around_left OnFwd(OUT_B,20); OnFwd(OUT_C,-25); //左旋回 #define go_straight OnFwd(OUT_BC,35); //直進 #define black 35 //黒の値は35 #define black_gray 43 //黒灰の値は43 #define white_gray 57 //白灰色の値は57 #define white 65 //白の値は65 #define catch OnFwd(OUT_A,-15);Wait(250); //ボールキャッチ ライントレースで重要となる閾値は4つに分けて考え,下図のようにした.これをどのように使用したかは次の項目で説明する. &ref(2019b/Member/kurisuke/Mission2/ライントレース.jpg,30%,ライントレースの設定); **左のライントレース [#f3879664] 私の選んだ課題1はうまくやれば左のライントレースだけで行けると気づき,右のライントレースのプログラムは用いなかった.左ライントレースのプログラムは以下のようである. void follow_line(long tmin,long tmax) //左トレース { SetSensorLight(S1); long t = CurrentTick(); long t_start = CurrentTick(); while((CurrentTick()-t<100 || CurrentTick()-t_start<tmin)&& (CurrentTick()- t_start<tmax)){ if(SENSOR_1<black){ around_left;} else if(SENSOR_1<black_gray){turn_left; t = CurrentTick();} else if(SENSOR_1<white_gray){ go_straight; t = CurrentTick();} else if(SENSOR_1<white){turn_right; t = CurrentTick();} else if(SENSOR_1>=white){around_right; t = CurrentTick();} } Off(OUT_BC); Wait(1000); } ロボットをスムーズに真っ直ぐ進めるために,黒灰と白灰の閾値の間は直進,白灰と白の閾値の間は右折,黒と黒灰の閾値の間は左折するようにプログラムを組んだ. **ボールをつかむ動き [#n57d5846] void fetch_ball(long t1)//ボールキャッチ { go_straight; Wait(400); Float(OUT_BC); around_left; //ボールの前まで旋回 Wait(1560); Off(OUT_BC); Wait(500); catch; //ボールをつかむ Off(OUT_BC); Wait(4000); around_left; //旋回して方向転換 Wait(t1); Off(OUT_BC); Wait(1000); } **交差点を渡る [#h7445faa] void intersection_straight() { turn_right; Wait(100); go_straight; Wait(300); Off(OUT_BC); } **メインプログラム [#w2083b3d] task main() { follow_line(0,50000);//AからD intersection_straight();//交差点 follow_line(900,50000);//DからG follow_line(2500,5000);//GからH fetch_ball(3550);//H~I follow_line(10000,500000);//IからA go_straight; Wait(1500); Off(OUT_BC);//終了 } *課題2の反省と感想 [#f0f14ef7] 今回は,課題1の時よりもプログラミングに慣れ大まかなプログラムの作成には手間取ることがなかった.ロボット本体の作成に関しても,過去の受講生の考えやチームメイトの考えを参考にして,授業時間内に作り終えることができた.しかし,ボールをとる動作時に,ロボット全体を大きく作りすぎたため,超音波センサーを取り付けることができなかった.後から,他の受講生のロボットを見た時,超音波センサーをロボットの車体の上に付け,横からではなく上からボールの位置を特定しているチームが多数あり,私たちのチームも同じ方法を採用していたらうまくいっていたかもしれないと思った.また,正確さを優先しすぎたため,速度が落ちてしまった. 次の課題3では,今までの課題の反省を生かして,さらに良いロボットをつくり成功させたいと思う.