〜課題2(ライントレース)目次〜 #contents *課題 [#k9831262] 1.A地点からB地点へ (P三叉路およびQ交差点はともに直進) 2.B地点からA地点へ (Q交差点では直進、P三叉路では直進) 3.C地点からA地点へ (Q交差点では直進、P三叉路では右折) そして、途中(P地点とQ地点)の間においたボール(ピンポン玉またはNXT付属のボール)を 目的地まで運んで、ゴールに入れる。その途中、三叉路および交差点では2秒間停止すること。 可能であれば、A,B,Cのそれぞれにエリアに入る三叉路付近からボールをシュートする。 自分は、1のA地点からB地点へのルートを選択した。 #ref(./ロボ課題2.1ライン.png,50%) *製作する上で工夫した点 [#ned7e2fc] **ロボット本体 [#zee4c438] ・ロボット本体にパーツを付けやすくするために、モーターを地面に水平にした。 ・本体前部にクワ型状のアーム1を取り付けた。 ・本体上部前方に、モーターを1つ取り付けてショベル型状のアーム2作った。 ・本体下部前方に光センサーを取り付けた。 ・本体についている個々のパーツ(アーム1、アーム2)は接合部が複雑でないので簡単に取り外して、片づけることが可能。 #ref(./本体1.jpg,10%) #ref(./本体2.jpg,10%) **アーム1(クワ型) [#x371323d] ・本体前部に、タイヤも含めた横幅と同じ長さのアームを取り付けた。縦の長さはボール2個分の長さと同じにして、やや余裕を持たせた。 ・水平に取り付けるとボールが下から通り抜けることがあるので、やや下に傾くようにした。 ・タイヤが付いている二つのモーターの間に感覚をもたせ、光センサーがちょうど取り付けられるようにした。アームは二つのモーターに直接取り付けた。 #ref(./アーム1.jpg,10%) #ref(./アーム2.jpg,10%) **アーム2(ショベル型) [#odd4f12c] ・本体上部前方のクワ型に入ったボールが出ないようにするために、ショベル型のアームを設置した。 ・アームの幅はクワガタの横幅と同じにして、ボールが出ないようにした。 ・アームは、スタート地点では上にあげていてボールが入るタイミングで下がるようにしている。 ・アームが下がりすぎて地面と接触しないように、ストッパーを設置した。 #ref(./ショベル1.jpg,10%) #ref(./ショベル2.jpg,10%) *プログラム [#c9146c3d] **定義の説明 [#t841a54b] #define THRESHOLD 45・・・光センサーの閾値 #define THRESHOLD 39 #define SPEED_H 40・・・移動スピード(高速) #define SPEED_H 30 #define SPEED_L 25・・・移動スピード(低速) #define SPEED_L 20 #define downtime 13500・・・開始してからショベル型アームを降ろすまでの時間 #define downtime 1000 #define down OnFwd(OUT_A,50);Wait(300);Off(OUT_A);Wait(300);・・・ショベル型アームを降ろす #define down OnFwd(OUT_A,40);Wait(500);Off(OUT_A);Wait(300); #define up OnRev(OUT_A,60);Wait(300);Off(OUT_A);Wait(300);・・・ショベル型アームを上げる #define up OnRev(OUT_A,40);Wait(500);Off(OUT_A);Wait(300); #define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL);・・・カーブで前進 #define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); #define go_forward OnRL(SPEED_H, SPEED_H);・・・前進 #define go_forward OnRL(SPEED_H, SPEED_H); #define turn_left1 OnRL(SPEED_L, -SPEED_L);・・・左旋回 #define turn_left1 OnRL(SPEED_L, -SPEED_L); // 左旋回 #define turn_left0 OnRL(SPEED_L, 0);・・・左折 #define turn_left0 OnRL(SPEED_L, 0); // 左折 #define turn_right0 OnRL(0, SPEED_L);・・・右折 #define turn_right0 OnRL(0, SPEED_L); // 右折 #define turn_right1 OnRL(-SPEED_L, SPEED_L);・・・右旋回 #define turn_right1 OnRL(-SPEED_L, SPEED_L); // 右旋回 #define STEP 1・・・1回の判定で進む時間 #define STEP 1 #define nMAX 300・・・ 通常のカーブとして許容できる繰り返しの最大値 #define nMAX 300 #define short_break Off(OUT_BC); Wait(1000);・・・小休止 #define short_break Off(OUT_BC); Wait(1000); // 小休止 #define CROSS_TIME 200・・・交差点通過にかかる時間 #define CROSS_TIME 500 #define cross_line OnRL(SPEED_L,SPEED_L);Wait(CROSS_TIME);short_break;・・・交差点を渡る #define goal OnRev(OUT_BC,50);Wait(500);Off(OUT_BC);Wait(500);\ up;OnFwd(OUT_BC,80);Wait(200);Off(OUT_BC); #define cross_line OnRL(SPEED_L,SPEED_L);Wait(CROSS_TIME);short_break; **実際のプログラム [#zbefae11] #define THRESHOLD 39 #define SPEED_H 40 #define SPEED_L 25 #define downtime 13500 #define down OnFwd(OUT_A,50);Wait(300);Off(OUT_A);Wait(300); #define up OnRev(OUT_A,60);Wait(300);Off(OUT_A);Wait(300); #define SPEED_H 30 #define SPEED_L 20 #define downtime 1000 #define down OnFwd(OUT_A,40);Wait(500);Off(OUT_A);Wait(300); #define up OnRev(OUT_A,40);Wait(500);Off(OUT_A);Wait(300); #define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); #define go_forward OnRL(SPEED_H, SPEED_H); #define turn_right1 OnRL(SPEED_L, -SPEED_L); // 左旋回 #define turn_right0 OnRL(SPEED_L, 0); // 左折 #define turn_left0 OnRL(0, SPEED_L); // 右折 #define turn_left1 OnRL(-SPEED_L, SPEED_L); // 右旋回 #define STEP 1 // 1回の判断で動作させる時間 #define nMAX 300 // 通常のカーブとして許容できる繰り返しの最大値 (調整する) #define turn_left1 OnRL(SPEED_L, -SPEED_L); // 左旋回 #define turn_left0 OnRL(SPEED_L, 0); // 左折 #define turn_right0 OnRL(0, SPEED_L); // 右折 #define turn_right1 OnRL(-SPEED_L, SPEED_L); // 右旋回 #define STEP 1 #define nMAX 300 #define short_break Off(OUT_BC); Wait(1000); // 小休止 #define CROSS_TIME 200 // 交差点通過にかかる時間 /* 交差点を渡る */ #define cross_line OnRL(SPEED_L,SPEED_L);Wait(CROSS_TIME);short_break; #define CROSS_TIME 500 #define goal OnRev(OUT_BC,50);Wait(500);Off(OUT_BC);Wait(500);\ up;OnFwd(OUT_BC,80);Wait(200);Off(OUT_BC); #define cross_line OnRL(SPEED_L,SPEED_L);Wait(CROSS_TIME);short_break; task main() { SetSensorLight(S3); int nOnline=0; // 続けて黒になった回数 (カウンタ) long t0 = CurrentTick(); int g=0; while (CurrentTick()-t0<10000) { /* 黒を続けてnMAX回繰り返さない間、通常のライントレースをする */ while (nOnline < nMAX) { if (SENSOR_3 < THRESHOLD-10) { turn_left1; nOnline++; // カウンタを増やす }else { if (SENSOR_3 < THRESHOLD-5) { turn_left0; } else if (SENSOR_3 < THRESHOLD+2) { go_forward; } else if (SENSOR_3 < THRESHOLD+5) { turn_right0; } else { turn_right1; SetSensorLight(S3); int nOnline=0; // 続けて黒になった回数 (カウンタ) int cross_count=0; int goal_count=0; int nOnwhite=0; long t0=CurrentTick(); while (cross_count<2) { while (nOnline < nMAX) { if(CurrentTick()-t0<=downtime&&downtime-1<CurrentTick()-t0) { down; } if (SENSOR_3 < THRESHOLD-6) { turn_left1; nOnline++; // カウンタを増やす } else { if (SENSOR_3 < THRESHOLD-3) { turn_left0; } nOnline=0; // カウンタをリセット else if (SENSOR_3 < THRESHOLD+5) { go_forward; } Wait(STEP); else if (SENSOR_3 < THRESHOLD+8) { turn_right0; } else { turn_right1; } nOnline=0; // カウンタをリセット } Wait(STEP); } short_break; // 小休憩 turn_right1; Wait(nMAX*STEP); // 進行方向修正 cross_line; // 交差点を渡る nOnline=0; //カウンタをリセット } while(CurrentTick()-t0>10000.0) { /* 黒を続けてnMAX回繰り返さない間、通常のライントレースをする */ while (nOnline < nMAX) { if(CurrentTick()-t0==downtime) { down; cross_count++; } t0=CurrentTick(); while(goal_count<1) { while (nOnwhite<nMAX) { if(SENSOR_3 >= THRESHOLD+8) { turn_right1; if(CurrentTick()-t0>4000) { nOnwhite++; } if (SENSOR_3 < THRESHOLD-10) { } else { if (SENSOR_3 < THRESHOLD-6) { turn_left1; nOnline++; // カウンタを増やす g=0; } else if (SENSOR_3 >= THRESHOLD+5) { turn_right1; g++; nOnline=0; if(g==nMAX) { nOnline=nMAX; } }else { if (SENSOR_3 < THRESHOLD-5) { else if (SENSOR_3 < THRESHOLD-3) { turn_left0; } else if (SENSOR_3 < THRESHOLD+2) { else if (SENSOR_3 < THRESHOLD+5) { go_forward; } else if (SENSOR_3 < THRESHOLD+5) { else { turn_right0; } nOnline=0; // カウンタをリセット g=0; nOnwhite=0; } Wait(STEP); } if(g<nMAX) { short_break; // 小休憩 turn_right1; Wait(nMAX*STEP); // 進行方向修正 cross_line; // 交差点を渡る nOnline=0; //カウンタをリセット } short_break; // 小休憩 turn_left1; Wait(nMAX*STEP); // 進行方向修正 goal; goal_count++; } Off(OUT_BC); } *作成した上での残った課題 [#o3eb7df6] ・ショベル型のアームが重くなってしまい、モーターの力具合によっては上下動が出来ないことがあったので、制御が必要になってしまった。 ・全体的に、本体前部にパーツが集中しているのでロボット全体が前のめりになってしまった。 ・シュートするプログラムに挑戦したが、上手くできなかった。 *感想と反省 [#j97622f4] ・自分の班のロボットはボールが出ないように、上からボールをかぶせるアームを取り付けた。しかし理想はボールをアームでつかむことだったが時間が無くてその機構を作ることが出来なかった。もう少し時間があれば理想に近づけたかなと思う。 ・実際にプログラムを作ってロボットがその通りに動いてくれた時は素直に嬉しかった。 ・もう少しパーツを工夫して使って、スマートなロボットを作るようにすればよかった。