[[2019a/Member]]目次 #contents *課題2 [#ee8817df] 下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成せよ。 #ref(./2019a-mission2.png,90%,ラインコース) **選択したコース [#ma838ca3] A地点から出発 → M → K(直進) → L(ピンポン玉をつかむ) → K(右折) → J(一時停止の後、左折) → I(直進) → H(直進) → G(左折) → F → E → D(一時停止の後、直進) → C(直進) → B(一時停止) → シュート→ A地点に入る(ゴール) #ref(./corse.jpg,90%,順番) *ロボットの説明 [#defc7733] **ロボットの全体像 [#va9a5665] 急なカーブでも曲がれるように左右の車輪の幅を狭くた。 #ref(./tukamu.jpg,30%,全体) **つかむ機構 [#bc7b09a5] 写真のように1本のアームを使って、引っ掛ける感じにした。 #ref(./tukamu1.jpg,40%,つかむ1) 別のモーターを使ってアームを動かすことにした。 #ref(./tukamu2.jpg,40%,つかむ2) **光センサー [#obf992dd] 光センサーを地上から5�个砲垢襪海箸膿Г糧淑未�しやすくなった。 #ref(./mae.jpg,40%,ラインコース) ***交差点の判断 [#oa38b9a1] 交差点では黒が連続する時間が通常のライントレースに比べて長い。そのため、通常のライントレースで光センサーが黒の上にいるより長く、光センサーが交差点で黒の上にいる時間より短い時間として0.3秒を設定し、交差点上でロボットが止まるようにした。 *プログラムについて [#s7843b79] **defineのプログラム [#a74845ee] #define RUN_TIME1 30 #define RUN_TIME_JIH 170 #define RUN_TIME_HGF 380 #define RUN_TIME_FE 180 #define RUN_TIME_DB 1000 #define turn_right OnFwd(OUT_A);OnRev(OUT_C); #define turn_left90 OnRev(OUT_A);OnFwd(OUT_C);Wait(100); #define turn_left OnRev(OUT_A);OnFwd(OUT_C);Wait(30); #define go_straight OnFwd(OUT_AC); #define turn180 OnRev(OUT_A);OnFwd(OUT_C);Wait(130); #define go_back OnRev(OUT_AC); #define THRESHOLD 42 #define turn_left Off(OUT_A); OnFwd(OUT_C); #define turn_right OnFwd(OUT_A); Off(OUT_C); #define turn180 OnFwd(OUT_C);OnRev(OUT_A);Wait(190);Off(OUT_AC);//180度回転 #define runtime 1450 #define runtime1 50 #define turn90 OnFwd(OUT_A);OnRev(OUT_C);Wait(100);Off(OUT_AC);//90度回転 #define power(s) SetPower(OUT_B,s); //モータのパワーをsにする #define STEP 1 // 一回の判定で進む時間 **サブルーチンプログラム [#h8048afa] ライントレースをそれぞれの区間ごとに時間内で繰り返すように設定し、細かく分けてあります。 ***出発点Aからボールを掴むLまでのプログラム [#a205abbc] sub across_turn() { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while (FastTimer(0) <= runtime) { if (SENSOR_2 < THRESHOLD){ // 線上なら turn_left; // 左へ } else { // 線上でなければ turn_right; // 右へ } Wait(STEP); // STEPの値 } } ***ボールを掴み終わりLからKまで進むプログラム [#g3f248b1] sub across_turn1() { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while (FastTimer(0) <= runtime1) { if (SENSOR_2 < THRESHOLD){ // 線上なら turn_left; // 左へ } else { // 線上でなければ turn_right; // 右へ } Wait(STEP); // STEPの値 } } ***交差点で止まるまで動き続けるプログラム [#gab04cab] sub line_trace1() //交差点で止まるまで動き続けるプログラム { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while ( FastTimer(0) <= RUN_TIME1 ) { if ( 48 < SENSOR_2 ){ OnFwd(OUT_A); Off(OUT_C);ClearTimer(0); //白なら右へ } else if (45 <SENSOR_2 < 49) { Off(OUT_A); OnFwd(OUT_C); //灰色なら左へ } else { OnRev(OUT_A);OnFwd(OUT_C); //黒なら右へ旋回 } } Off(OUT_AC);Wait(100); } ***JからI、IからHまでのライントレース一定時間内でライントレースし続ける [#r844b152] sub line_trace_JIH() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while ( FastTimer(0) <= RUN_TIME_JIH ) { if ( 48 < SENSOR_2 ){ OnFwd(OUT_A); Off(OUT_C); //白なら右へ } else if (45 <SENSOR_2 < 49) { Off(OUT_A); OnFwd(OUT_C); //灰色なら左へ } else { OnRev(OUT_A);OnFwd(OUT_C); //黒なら右へ旋回 } } turn_right;Wait(22);OnFwd(OUT_AC);Wait(15); } ***HからFまで一定時間内ライントレースし続ける [#ad14dcb9] sub line_trace_HGF() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while ( FastTimer(0) <= RUN_TIME_HGF ) { if ( 48 < SENSOR_2 ){ OnFwd(OUT_A); Off(OUT_C); //白なら右へ } else if (45 <SENSOR_2 < 49) { Off(OUT_A); OnFwd(OUT_C); //灰色なら左へ } else { OnRev(OUT_A);OnFwd(OUT_C); //黒なら右へ旋回 } } } ***FからEまで一定時間内ライントレースし続ける [#sd63a8eb] sub line_trace_FE() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while ( FastTimer(0) <= RUN_TIME_FE ) { if ( 48 < SENSOR_2 ){ OnFwd(OUT_A); Off(OUT_C); //白なら右へ } else if (45 <SENSOR_2 < 49) { Off(OUT_A); OnFwd(OUT_C); //灰色なら左へ } else { OnRev(OUT_A);OnFwd(OUT_C); //黒なら右へ旋回 } } } ***DからBまでのライントレース一定時間内ライントレースし続ける [#o92004ea] sub line_trace_DB() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while ( FastTimer(0) <= RUN_TIME_DB ) { if ( 48 < SENSOR_2 ){ OnFwd(OUT_A); Off(OUT_C); //白なら右へ } else if (45 <SENSOR_2 < 49) { Off(OUT_A); OnFwd(OUT_C); //灰色なら左へ } else { OnRev(OUT_A);OnFwd(OUT_C); //黒なら右へ旋回 } } } **メインプログラム [#x0a4eba2] task main(){ across_turn(); turn180; OnFwd(OUT_B); power(0);//ゆっくりボールを掴む Wait(25); Off(OUT_B); across_turn1(); turn90; Off(OUT_AC); line_trace1(); //kから出発 line_trace_JIH(); //JからI line_trace_JIH(); //IからH line_trace_HGF(); //HからF turn_left90; //Fで左90度旋回 line_trace_FE(); //FからE turn_left; //Eで左旋回(90度以下) line_trace1(); //EからDまでのライントレース後、一時停止 turn_right;Wait(25); //Dで左へ傾いた分、右に曲がって位置調整 line_trace_DB(); //DからB turn180; //180度旋回 OnRev(OUT_B); //アーム展開 power(0); Wait(25); Off(OUT_B); go_straight; //ボールから離れる Wait(100); OnFwd(OUT_B); //アームを閉じる power(0); Wait(25); go_back; //後ろに下がって位置調整 Wait(55); OnFwd(OUT_B); Wait(10); //ボールをアームで弾いてAにシュート } *結果 [#b0968d59] ライントレースの動きは正確かつスムーズに動いた。シュートでは、ピンポン玉が上手に静止することが難しくシュートが出来ないことがただあった。 *まとめ [#m9f10804] 前回に比べてプログラムを書く量が多かったため、サブルーチンの利点を知ることが出来た。今回のロボットは曲がりやすくするためにタイヤを二輪もしくは三輪にするべきだった。しかし、私たちはタイヤとの幅を小さくすることで急なカーブをうまく通過するための問題を解決すことが出来た。