[[2016a/Member]] *目次 [#z30aa09c] #contents *課題 [#b54224a4] 課題2で用いたコースを使い、紙コップを運ぶタイムレースを行う C地点D地点に置いた紙コップを交互に重ねて中央付近の円の中に置く その数によってポイントが決まり、さらに、ほかのグループからの評価の平均もポイントとして加算される *方針 [#m9e752f2] 私たちのグループでは、一つずつ紙コップを円の中に運び、重ねていく方法をとった そのために、「紙コップを運ぶロボット」と、紙コップを重ねる際、下の紙コップに少しでもズレがあると重ねられないため「置いた紙コップを固定するロボット」を作った 固定するロボットが最初に予定された位置まで移動する そして運ぶロボットが1個目を運んできたときに2体が通信し、固定するロボットが、それを固定する 固定するロボットは以後動かず、運ぶロボットが重ねていく *紙コップを運ぶロボット [#v1c2132c] **本体 [#lbe74c98] &ref(attachment00.jpg ); まず紙コップを持ち上げる仕組みだが 画像のように歯車を組み合わせた モーターを動かすとまずは右側の挟み込む部分が動く そして何かを挟み込みその部分が動かなくなると 今度はモータの動きが紙コップを持ち上げる動作に使われる(連結部分が自由に動くようになっているため) 次は紙コップを識別する方法と、移動方法である &ref(attachment01.jpg ); 二つの光センサーを用いた 一つ目でライントレースをし、もう一つは紙コップにを識別する **プログラム [#tf1505ce] プログラミングの知識のあるメンバーが作ったため、私には理解できない部分もあるが、分かる範囲で説明し、プログラムを書いておく ***定義 [#e2fc0ce4] #define SIGNALON 121 //通信用 #define MIDDLE 50 //ライントレース用の中間値 #define WHITE 50 //紙コップ認識用の値 #define turn_left1 SetPower(OUT_AC,2); Off(OUT_A); OnFwd(OUT_C); //左折 #define turn_left2 SetPower(OUT_A,1); OnRev(OUT_A); OnFwd(OUT_C); //左旋回 #define turn_right1 SetPower(OUT_AC,2); OnFwd(OUT_A); Off(OUT_C); //右折 #define turn_right2 SetPower(OUT_C,1); OnFwd(OUT_A); OnRev(OUT_C); //右旋回 #define go_forward SetPower(OUT_AC,7); OnFwd(OUT_AC); //前進 #define SIGNALON 121 //通信用 #define MIDDLE 50 //ライントレース用の中間値 #define WHITE 50 //紙コップ認識用の値 #define turn_left1 SetPower(OUT_AC,2); Off(OUT_A); OnFwd(OUT_C); //左折 #define turn_left2 SetPower(OUT_A,1); OnRev(OUT_A); OnFwd(OUT_C); //左旋回 #define turn_right1 SetPower(OUT_AC,2); OnFwd(OUT_A); Off(OUT_C); //右折 #define turn_right2 SetPower(OUT_C,1); OnFwd(OUT_A); OnRev(OUT_C); //右旋回 #define go_forward SetPower(OUT_AC,7); OnFwd(OUT_AC); //前進 int cup_count=0; //コップのカウント(これによって動作が変化する) ***サブルーチン [#x565f4cb] sub trace() //ライントレース { while(FastTimer(0) < 26) //左旋回が一定時間続くまでループ { if(SENSOR_2 < MIDDLE-5) //黒 { turn_left2; //左旋回 } else { if(SENSOR_2 < MIDDLE-2) //中間に近い黒 { turn_left1; //左曲がり } else if(SENSOR_2 < MIDDLE+3) //中間 { go_forward; //直進 } else if(SENSOR_2 < MIDDLE+6) //中間に近い白 { turn_right1; //右曲がり } else //白 { turn_right2; //右旋回 } ClearTimer(0); } } } sub i_forward() //直進 { turn_right2; Wait(30); go_forward; Wait(50); Off(OUT_AC); } sub i_left() //左折 { turn_left2; Wait(45); Off(OUT_AC); } sub i_right() //右折 { turn_right2; Wait(30); go_forward; Wait(30); turn_right2; Wait(80); Off(OUT_AC); } sub cup1() //CとDのそれぞれの1つ目のコップ { turn_right2; //紙コップまで方向調整 Wait(25); SetPower(OUT_AC,1); //紙コップまで移動 OnFwd(OUT_AC); while(SENSOR_3 <= WHITE); Off(OUT_AC); OnRev(OUT_B); //紙コップをつかむ Wait(150); Off(OUT_B); turn_right2; //ラインまで移動 Wait(180); go_forward; Wait(20); } sub cup2() //2つ目のコップ { SetPower(OUT_AC,1); //紙コップまで移動 OnFwd(OUT_AC); while(SENSOR_3 <= WHITE); Off(OUT_AC); OnRev(OUT_B); //紙コップをつかむ Wait(150); Off(OUT_B); turn_right2; //ラインまで移動 Wait(180); go_forward; Wait(120); } sub cup3() //3つ目のコップ { turn_right2; //紙コップまで方向調整 Wait(45); SetPower(OUT_AC,1); //紙コップまで移動 OnFwd(OUT_AC); while(SENSOR_3 <= WHITE); Off(OUT_AC); OnRev(OUT_B); //紙コップをつかむ Wait(150); Off(OUT_B); turn_right2; //ラインまで移動 Wait(170); go_forward; Wait(100); } sub cup_down() //コップを下すときの動作 { turn_left2; //コップを下す位置まで移動 Wait(5); OnRev(OUT_AC); Wait(5); Off(OUT_AC); if(cup_count == 1) //最初のコップを置くとき { SendMessage(SIGNALON); //もう一台の動作を再開する } OnFwd(OUT_B); Wait(50); Off(OUT_B); if(cup_count == 1) //最初のコップを置いたとき { OnFwd(OUT_AC); //コップを少し前に押す Wait(10); } OnRev(OUT_AC); //ラインまで移動 Wait(60); turn_left2; Wait(120); go_forward; Wait(50); } C地点D地点において、コップの置き場所に工夫した、道の目の前に置いたコップを「1」、左奥に置いたコップを「2」、右奥に置いたコップを「3」として説明している また同じ番号のコップは、地点が違っていても同じ動作でつかむことができる ***main [#b0cb4a05] task main() { SetSensor(SENSOR_2, SENSOR_LIGHT); SetSensor(SENSOR_3, SENSOR_LIGHT); int c=1; //交差点の確認 int d=0; //1になったら動作停止 int course_check=0; //0ならC地点へ、1ならD地点へ SetPower(OUT_B,1); //コップをつかむときのモータをできるだけ弱くする go_forward; //ラインまで直進 Wait(80); while(d == 0) { ClearTimer(0); trace(); //ライントレース Off(OUT_AC); //交差点確認 PlaySound(SOUND_UP); Wait(100); switch(c) { case 1: //最初の交差点 i_left(); //S地点へ break; case 2: //S地点の交差点 if(course_check == 0) { i_right(); //C地点へ } else { i_left(); //D地点へ } break; case 3: //C地点かD地点 if(cup_count < 2) //集めたコップが2つより少ないなら { cup1(); } else if(cup_count < 4) //集めたコップが4つより少ないなら { cup2(); } else //集めたコップが4つ以上なら { cup3(); } cup_count++; break; case 4: if(course_check == 0) //C地点から戻ってきたら { i_left(); //P地点へ course_check = 1; //次はD地点へ } else //D地点から戻ってきたら { i_right(); //P地点へ course_check = 0; //次はC地点へ } break; case 5: //P地点の交差点 i_left(); //Q地点へ break; case 6: //Q地点の交差点 cup_down(); if(cup_count == 6) //コップを集め終わったら { d = 1; //動作停止 } break; case 7: //P地点の交差点 i_right(); //S地点へ c = 1; //case 2に戻る break; } c++; } Off(OUT_ABC); } コップのカウントによって、コップをつかむまでの動作を変化させている switch文を使い、交差点を判別したらcの値を増やしている 長くならないようにCをリセットし、case2に戻っている *紙コップを固定するロボット [#ka4b73df] **本体 [#g841c561] &ref(attachment01 (1).jpg ); 光センサーをもう一方のロボットで使っているため、ライントレースができない 直進とコップを挟むためにモーターを時間指定で移動させる 最後にコップから離れる 前述の通りコップを挟む際のタイミングを計るため通信を行う **プログラム [#f451f095] #define SIGNALON 121 //通信用 task main() { ClearMessage(); ClearTimer(0); OnRev(OUT_AC); //Q地点まで移動 Wait(450); Off(OUT_AC); OnRev(OUT_A); //向き調整 OnFwd(OUT_C); Wait(5); Off(OUT_AC); while(Message() != SIGNALON); //通信するまで動作停止 Wait(150); //紙コップが置かれたらアームで調整 OnFwd(OUT_B); Wait(10); Off(OUT_B); Wait(30000); //紙コップが確実に集め終わるまで動作停止(あまりよくない) OnRev(OUT_B); //アームを広げる Wait(20); Off(OUT_B); OnRev(OUT_AC); //紙コップから離れる Wait(30); Off(OUT_AC); } *結果と感想 [#zcbfaa13] 作業過程だが、協力できることは協力していたつもりだが、知識のあるメンバーに頼りきりになってしまった。プログラムの意味が分からず、意見を持てなかったことが原因だ。もう少し時間があれば、プログラムの意味を解説してもらいながら、自分の考えを持つことができたのかなと思う。時間が無かったため、わざわざ解説してもらうのは迷惑になるのではないかと思ってしまった。プログラムを読んでみて、私にはよく分からない部分もあったが、しっかり考えて作られていることが読み取れ、とても感謝している。 さて、ロボコンの結果であるが 一回目の挑戦では固定するロボットが前に行きすぎてコップを置くスペースが無くなってしまったため0ポイント(しかし後ろ過ぎると移動の妨げになるため、加減がとても難しい。電池の減り具合や、少しの角度の変化で失敗してしまう) 2回目は重ねることは諦めて、固定するロボットを解雇した これが功を奏し、一つ紙コップを置くことができて二位になれた