目次 #contents *課題2 [#gc17f0e3] 下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットの作成 ** コース [#xdefe08a] #ref(2017b/Mission2/2017b-mission2.png,50%,課題2のコース) 第1コース + Aをスタート + Bを直進 + Cを右折 + Fを直進 + Rを左折(一時停止) + Pを直進 + X地点の紙コップを取得してコースに戻る + Qを左折 + Sを直進(一時停止) + Y地点に紙コップを置いてコースに戻る + Sを直進(一時停止) + Fを左折(一時停止) + Cを右折(一時停止) + D地点へ(ゴール) ** ミッション [#k5f5fb77] いずれかのコースで黒い線に沿って動き、紙コップを移動させるロボットの製作 自分は第1コースを走行するロボットを作成した。 *ロボット [#d61248a3] &ref(2017b/Member/OGI/Mission2/本体上.JPG,50%); &ref(2017b/Member/OGI/Mission2/本体横.JPG,50%); &ref(2017b/Member/OGI/Mission2/アーム部分.JPG,50%); ロボット本体をなるべくコンパクトにし、小回りが利くようにした。2枚目の写真から分かるように後輪をタイヤではなくし、三輪にしたことも機動力を上げることに繋がった。また、アーム部分が重くなると本体の重心が前に偏り、ラインをトレースする際に後輪が浮いてしまい、スムーズに走ることが出来なかった。重心を後ろにずらすためにRIS本体を後方に設置し、3枚目の写真のように、アーム部分は片方のアームを固定しもう片方のアームだけを動かす簡単な構造にし軽量化を図った。 1枚目の写真のように、2つのタイヤの幅を狭めることでロボット本体をなるべくコンパクトにし、小回りが利くようにした。2枚目の写真から分かるように後輪をタイヤではなくし、三輪にしたことも機動力を上げることに繋がった。また、アーム部分が重くなると本体の重心が前に偏り、ラインをトレースする際に後輪が浮いてしまい、スムーズに走ることが出来なかった。重心を後ろにずらすためにRIS本体を後方に設置し、3枚目の写真のように、アーム部分は片方のアームを固定しもう片方のアームだけを動かす簡単な構造にし軽量化を図った。 &ref(2017b/Member/OGI/Mission2/光センサー部分.JPG,75%); センサーをなるべく下につけることで値を安定して測れるようにした。 *プログラム [#f3415e79] **定義付け [#g94a355f] #define THRESHOLD 46 //閾値 #define go(t) OnRev(OUT_AC);Wait(t);Off(OUT_AC); //t秒前進 #define back(t) OnFwd(OUT_AC);Wait(t);Off(OUT_AC); //t秒後進 #define roll_left OnFwd(OUT_C);OnRev(OUT_A); //左旋回 #define turn_left OnRev(OUT_A);Off(OUT_C); //左折 #define roll_right OnFwd(OUT_A);OnRev(OUT_C); //右旋回 #define turn_right OnRev(OUT_C);Off(OUT_A); //右折 #define roll_left2(t) OnFwd(OUT_C);OnRev(OUT_A);Wait(t); //t秒左旋回 #define turn_left2(t) OnRev(OUT_A);Off(OUT_C);Wait(t); //t秒左折 #define roll_right2(t) OnFwd(OUT_A);OnRev(OUT_C);Wait(t); //t秒右旋回 #define turn_right2(t) OnRev(OUT_C);Off(OUT_A);Wait(t); //t秒右折 #define roll_left3 OnRev(OUT_A);OnFwd(OUT_C);until(SENSOR_2<=43);Off(OUT_AC); //ラインを見つけるまで左旋回 #define roll_right3 OnRev(OUT_C);OnFwd(OUT_A);until(SENSOR_2<=43);Off(OUT_AC); //ラインを見つけるまで右旋回 #define close SetPower(OUT_B,1);OnFwd(OUT_B);Wait(50);Off(OUT_B);//アームを閉じる #define open SetPower(OUT_B,1);OnRev(OUT_B);Wait(70);Off(OUT_B);//アームを開ける #define cross_stop Off(OUT_AC);Wait(100); //交差点で1秒停止 #define STEP 2 // 一回の判定で進む時間 あらかじめ右左折やアームの動きを用意した。また、用途に合わせて3種類の右左折を用意した。 **ライントレース [#r9d37718] ***右側トレース [#p5e39a15] sub LINE_R() //線の右側をトレース { SetSensor(SENSOR_2,SENSOR_LIGHT); //端子2に光センサーをセット ClearTimer(0); while(FastTimer(0)<=23) //0.23秒以内の場合はループ 超えた場合は交差点として判断 { if (SENSOR_2 > THRESHOLD +5) { //センサーが閾値+5の値を超えたら左旋回 roll_left; ClearTimer(0); }else if (SENSOR_2 > THRESHOLD +3){ //センサーが閾値+3の値を超えたら左折 turn_left; ClearTimer(0); }else if (SENSOR_2 > THRESHOLD){ //センサーが閾値を超えたら直進 OnRev(OUT_AC); ClearTimer(0); }else if (SENSOR_2 > THRESHOLD -3){ //センサーが閾値−3の値を超えたら右折 turn_right; ClearTimer(0); }else{ //上記のどの条件にも当てはまらないときに右旋回 roll_right; } Wait(STEP); } Off(OUT_AC); } ***左側トレース [#r337b88d] sub LINE_L() //線の左側をトレース { SetSensor(SENSOR_2,SENSOR_LIGHT); //端子2に光センサーをセット ClearTimer(0); while(FastTimer(0)<=21) //0.21秒以内の場合はループ 超えた場合は交差点として判断 { if (SENSOR_2 > THRESHOLD +5) { //センサーが閾値+5の値を超えたら右旋回 roll_right; ClearTimer(0); }else if (SENSOR_2 > THRESHOLD +3){ //センサーが閾値+3の値を超えたら右折 turn_right; ClearTimer(0); }else if (SENSOR_2 > THRESHOLD){ //センサーが閾値を超えたら直進 OnRev(OUT_AC); ClearTimer(0); }else if (SENSOR_2 > THRESHOLD -3){ //センサーが閾値−3の値を超えたら左折 turn_left; ClearTimer(0); }else{ //上記のどの条件にも当てはまらないときに右旋回 roll_left; } Wait(STEP); } Off(OUT_AC); } 第1コースでは、ヘアピンカーブや円などは線の左側をトレースすることが上手く動かすために必要だったので、ライントレースのプログラムを左右で2種類用意した。交差点を判断するために用意したタイマーの値が左右同じだと、車体の進入角度からか上手くいかなかった。微調整を繰り返した結果、左側をトレースする際はタイマーの値を少し小さくすることで解決した。 **コップを取る・置く [#c013ec9a] ***取る [#g432d4d5] sub CATCH() //コップを取る { roll_right2(70); //進行方向調整 go(30); //コップに近づく close; //アームを閉じる roll_left2(80); //進行方向調整 go(30); //ラインに近づく roll_right3; //ラインを見つけるまで右旋回 } ***置く [#l4d86ad5] sub RELEASE() //コップを置く { roll_right2(90); //進行方向調整 open; //アームを開く turn_left2(30); //進行方向調整 back(100); //コップから離れる turn_right2(120); //ラインに近づく } **メインプログラム [#rec2eafb] task main() { LINE_R(); //A〜B go(20); //線から離れる roll_left3; //線を見つける LINE_R(); //B〜C roll_right2(20); //進行方向調整 LINE_R(); //C〜F go(25); //線から離れる roll_left3; //線を見つける LINE_R(); //F〜第2ヘアピンカーブ go(25); //トレースの左右を変更するために線から離れる LINE_L(); //第2ヘアピンカーブ〜R cross_stop; //Rで1秒停止 roll_left2(20); //進行方向調整 LINE_L(); //R〜P CATCH(); //コップを取る LINE_L(); //P〜Q go(30); //トレースの左右を変更するために線から離れる LINE_R(); //Q〜S cross_stop; //Sで1秒停止 go(15); //線から離れる LINE_R(); //S〜S cross_stop; //Sで1秒停止 go(20); //線から離れる roll_left3; //線を見つける LINE_R(); //S〜F cross_stop; //Fで1秒停止 RELEASE(); //コップを置く LINE_R(); //F〜C cross_stop; //Cで1秒停止 roll_right2(50); //進行方向調整 go(120); //Dへ } *反省点 [#p149de35] 発表では上手くいったが、3回に1回程度の成功率だったので、もっと改善出来る箇所があったと思う。また、進行方向の調整などでメインプログラムが予想以上に長くなってしまった事が心残りになった。