[[2007a/MemberOnly/進行状況A]] #contents *メンバー紹介 [#p0fb3bd4] 今回のメンバーは「ZWEI」「クロ」「カズ」「チノ」「KY王子」の5人です。 *ロボコンのルール [#kf3e6928] **基本ルール [#zb371d97] ●所定の時間内に紙パックを所定の場所に運んで積み上げる。 ●競技時間は2分30秒、あるいはリタイアするまでとする。 ただし積み上げた紙パックからロボットが離れようとしている動作中に制限時間が来てしまった時には、その動作が終了するまで、とする。 2分経過した時点で10個以上入っていた場合には30秒延長する。 ●どこからスタートしてもよい。 ●スタート時のロボットは3個を越えないこと (スタート後はいくつに分裂してもかまわない)。 ●開始の合図から5秒以内にRCXのスタートボタンを押す作業を完了すること。 ●競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。 ●途中でうまく動かなくなった場合、1回限り再スタートすることができる。 ●積んだ紙パックの底面は水平でなければならない。 ●競技終了時点で、積み上げた紙パックにロボットの一部が触れていてはならない。 触れている場合は、その紙パックおよびその紙パックに触れている紙パック、さらにその紙パックに触れている紙パック、・・・、は加算しない。 ●半分以上枠はみ出した紙パックは得点に加算しない。 ●枠内からはみ出した部分が半分以下の場合には、本来の点数の 1/2 とする。1点未満は切捨て。 **フィールドの説明 [#fcbeb78b] http://yakushi.shinshu-u.ac.jp/robotics/?plugin=attach&refer=2007a%2F%A5%ED%A5%DC%A5%B3%A5%F3&openfile=robocon-2007a-field.gif ●フィールドは約160cm×110cm ●運搬する500mlの紙パック(以下単に紙パックと呼ぶ)は約7cm×7cm×10.3cm ●紙パックはすべての面に白あるいは緑色の画用紙がはられている ●紙パックは(目的地の円周上を除く)各交差点に立てて配置されている ●目的地の円を囲む正方形の4隅には緑の紙パックが配置されている ●1つの格子はの境界の黒線の芯々で20cm平方の正方形である ●黒い線の太さは約25mm ** 基本得点の計算方法 [#t805fffa] 紙パックを一個運んで積み上げると、白パックの場合 1層目で横置き:1点、1層目で縦置き:2点 2層目で横置き:2点、2層目で縦置き:4点 3層目で横置き:4点、3層目で縦置き:8点 4層目で横置き:8点、4層目で縦置き:16点 ..... 以下同様 緑パックの場合はすべて白パックの2倍 技術点の計算方法 以下の動作の精度・スピード・確実性などを含めた技術的な工夫や芸術性について他の全てのチーム(9チーム+TAor教員)が20点満点で採点し、その平均点を求める。 **得点の目安 [#ka930579] ●紙パックを集める動作 (4点) ●紙パックを積み上げる動作 (4点) ●2台以上のロボット、あるいは単体のロボットの場合は2台のRCXの連携の良さ(4点) ●自立型のロボットとしての形や動作の美しさ、斬新さ(4点) ●その他 (4点) *目標 [#n9c58888] 私たちのグループでは高く積み上げたものを一つ作り高得点をねらうことにした。 またできるだけ単純な動きですんだ方がいい。 そのためにはどうすればいいか。 **案1 [#sa93d98f] 一つの大きいロボットを作り、紙パックを集め、それを横向きにねかしておく。あるていど集めたら円の中に移動し、紙パックをたてる。 しかし、これだとロボットが大きくなりすぎてしまう。ロボットが大きいと、フィールドの外側を走るときライントレースをしながらのカーブができない。なぜならフィールドには外壁があるからだ。また、フィールドの内側をライントレースして紙パックを集めるのはプログラミングが複雑になってしまう。よってこの案は断念した。 **案2 [#u6d0809f] ロボットを二つに分け、役割を運ぶロボットと積むロボットに分担する。 また積み方を上に紙パックを乗せるのではなくて、下に入れていく方法にしたことによってよりシンプルな動きですむようにした。このような工夫によりロボットの軽量化ができるようになった。 しかし二つのロボットを使うということでロボット同士の通信機能を上手く使わなければいけない。 その点が課題となった。 *製作過程 [#b1a6d05f] **運ぶロボット [#t6ef73ba] 積むロボットまで合計4個の紙パックを運ぶ。 ***紙パックを運ぶ [#a9fcbc38] 紙パックをつかむ部分にはモーターを使わず軽量化、ロボットが後退したときには抜けるように工夫した。 そうしたことにより紙パックを運んで置いてくる作業がしやすくなった。 &ref(./SA350039.JPG);&ref(./SA350040.JPG); **ロボットの通信機能とバランス [#m93b242b] 運ぶロボットと積むロボットはうまく連携しなければいけない。よって、通信機能がもっとも大切である。当初、NQCの本体はバランスが安定するように、ロボットの中心においていた。しかし、試作のプログラムで通信機能のテストを行った結果、 一.ある程度近づかないと反応しない 二.障害物が目の前にあると、通信ができない(紙パックが1つでもあると通信できない) ということが判明したため、本体の位置を左横にずらした。バランスをとるためにロボットの右側におもりをつけた。 &ref(./SA350047.JPG); **積むロボット [#z9598072] 運ばれてきた紙パックをつかみ持ち上げる。4段まで積み上げたら円の中まで紙パックを運ぶ。 ***紙パックをつかむ[#yae90ec7] &ref(./SA350051.JPG); ***紙パックを持ち上げる [#e274c537] &ref(./SA350055.JPG); &ref(./SA350050.JPG); ***タッチセンサー [#yda57890] &ref(./SA350054.JPG); ***円の中に紙パックを運ぶ [#i8fbf67d] &ref(./SA350052.JPG); *プログラミング [#o63cb7c7] **ロボット1 [#hdf52324] #define danb 4 // #define sage 20 // #define time 80 // int dan_p; //変数と定数を用意 task main () { SetSensor(SENSOR_1, SENSOR_TOUCH);// SetSensor(SENSOR_2, SENSOR_TOUCH);// SetSensor(SENSOR_3, SENSOR_TOUCH);//センサ123をタッチセンサと定義 SetPower(OUT_A+OUT_C,7); //モーターの出力を最大に設定 dan_p=0; while(true) { while((dan_p >= 1)&&(dan_p <= 3)) { OnFwd(OUT_C);// Wait(120); // Off(OUT_C); //箱をつかむ while(SENSOR_1 == 0){OnFwd(OUT_B);} //箱を持ち上げる Off(OUT_B); while (SENSOR_2 ==0){SendMessage(1);}//箱を持ち上げたらメッセージを送る while(Timer(1)<=35){OnRev(OUT_B);} Off(OUT_B); Wait(30); OnRev(OUT_C);//箱を積み上げる Wait(116); Off(OUT_C); OnRev(OUT_B);//アームの位置を初期状態に戻す Wait(850); Off(OUT_B); Wait(50); dan_p=dan_p+1;//次の段の作業に移行する } while(dan_p == 4) //箱を4段積みあげたとき { OnFwd(OUT_C);//箱が崩れないように、固定する Wait(120); Off(OUT_C); OnFwd(OUT_A);//丸の中まで移動する Wait(2500); Float(OUT_A); OnRev(OUT_C);//箱の固定を解除する Wait(120); Off(OUT_C); OnRev(OUT_A);//ロボットが箱から離れる Wait(1800); dan_p=dan_p+1; }}} **箱を運ぶロボット [#b26651c9] #define LI 42 // #define GO OnRev // #define BACK OnFwd// int d_p; // int k_p; // int l_p; //変数と定数を用意 task main () { SetSensor(SENSOR_1, SENSOR_LIGHT);// SetSensor(SENSOR_2, SENSOR_LIGHT);//センサ12を光センサと定義 ClearMessage(); d_p=0; k_p=0; l_p=0;//すべての変数の中の数字をリセットする while(true) { while (k_p < 3) //ロボットが所定の位置に到達するまで { GO(OUT_A+OUT_C); //前進する if ((SENSOR_1 < LI)&&(SENSOR_2 < LI)) { if (d_p ==0){d_p = 1; k_p = k_p + 1;}//ラインの数を数える }else{ if (d_p ==1){d_p = 0;} } } while(k_p == 3) //所定の位置に到達したとき {Off(OUT_A+OUT_C); Wait(120); GO(OUT_A+OUT_C);//箱を積み上げるロボットに渡す Wait(135); OnRev(OUT_A+OUT_C);//少しさがる Wait(10); Off(OUT_A+OUT_C); k_p=k_p+1; } while ((k_p > 3)&&(k_p < 6)) {Off(OUT_A+OUT_C); if (Message() == 1) //メッセージ1を受け取ったとき { while (Message() ==1){GO(OUT_A+OUT_C);}//前進する if (Message() == 2) // {BACK(OUT_A+OUT_C); //メッセージ2を受け取ったとき少しさがる l_p=l_p+1; Wait(20); Off(OUT_A+OUT_C);} } if (l_p == 3) //すべてのブロックを渡し終えたとき {k_p ==7;} //次の動作に移行する } while (k_p == 7)//すべてのブロックを渡し終えたときの動作 {BACK(OUT_A+OUT_C); Wait(200); Off(OUT_A+OUT_C);} 積み上げロボットの邪魔にならないように、後進する } } **LongLongAgoの主旋律 [#y0fe799c] #define Do 523 #define Fa 698 #define So 784 #define Ra 880 #define Si 932 #define DO 1047 #define RE 1175 task play_music() // 音楽を演奏するタスク { while (true) { PlayTone(Fa,60); Wait(70); // Wait の時間の方を少し長くして PlayTone(Fa,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(So,30); Wait(35); // 一つの音にならないようにしている PlayTone(Ra,60); Wait(70); PlayTone(Ra,30); Wait(35); PlayTone(Si,30); Wait(35); PlayTone(DO,60); Wait(70); PlayTone(RE,30); Wait(35); PlayTone(DO,30); Wait(35); PlayTone(Ra,120); Wait(140); PlayTone(DO,60); Wait(70); PlayTone(Si,30); Wait(35); PlayTone(Ra,30); Wait(35); PlayTone(So,120); Wait(140); PlayTone(Si,60); Wait(70); PlayTone(Ra,30); Wait(35); PlayTone(So,30); Wait(35); PlayTone(Fa,120); Wait(140); PlayTone(Fa,60); Wait(70); // Wait の時間の方を少し長くして PlayTone(Fa,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(So,30); Wait(35); // 一つの音にならないようにしている PlayTone(Ra,60); Wait(70); PlayTone(Ra,30); Wait(35); PlayTone(Si,30); Wait(35); PlayTone(DO,60); Wait(70); PlayTone(RE,30); Wait(35); PlayTone(DO,30); Wait(35); PlayTone(Ra,120); Wait(140); PlayTone(DO,60); Wait(70); PlayTone(Si,30); Wait(35); PlayTone(Ra,30); Wait(35); PlayTone(So,60); Wait(70); PlayTone(Ra,30); Wait(35); PlayTone(So,30); Wait(35); PlayTone(Fa,120); Wait(140); PlayTone(Fa,120); Wait(140); PlayTone(DO,60); Wait(70); PlayTone(Si,30); Wait(35); PlayTone(Ra,30); Wait(35); PlayTone(So,60); Wait(70); PlayTone(Do,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(Si,60); Wait(70); PlayTone(Ra,30); Wait(35); PlayTone(So,30); Wait(35); PlayTone(Fa,120); Wait(140); PlayTone(DO,60); Wait(70); PlayTone(Si,30); Wait(35); PlayTone(Ra,30); Wait(35); PlayTone(So,60); Wait(70); PlayTone(Do,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(Si,60); Wait(70); PlayTone(Ra,30); Wait(35); PlayTone(So,30); Wait(35); PlayTone(Fa,120); Wait(140); PlayTone(Fa,60); Wait(70); // Wait の時間の方を少し長くして PlayTone(Fa,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(So,30); Wait(35); // 一つの音にならないようにしている PlayTone(Ra,60); Wait(70); PlayTone(Ra,30); Wait(35); PlayTone(Si,30); Wait(35); PlayTone(DO,60); Wait(70); PlayTone(RE,30); Wait(35); PlayTone(DO,30); Wait(35); PlayTone(Ra,120); Wait(140); PlayTone(DO,60); Wait(70); PlayTone(Si,30); Wait(35); PlayTone(Ra,30); Wait(35); PlayTone(So,60); Wait(70); PlayTone(Ra,30); Wait(35); PlayTone(So,30); Wait(35); PlayTone(Fa,120); Wait(140); PlayTone(Fa,120); Wait(140); Wait(20); } } task main() { SetSensor(SENSOR_1, SENSOR_TOUCH); start play_music ; // 演奏を開始 OnFwd(OUT_A+OUT_B); // 前進 until (SENSOR_1 == 1); stop play_music ; // 演奏を停止 Off(OUT_A+OUT_B); // 動きも停止 } **伴奏 [#j816dbef] #define Do 523 #define ra 440 #define fa 349 #define mi 330 #define doo 262 #define si 466 #define so 392 task play_music() // 音楽を演奏するタスク { while (true) { PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(mi,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(so,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(mi,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(so,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(mi,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(so,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(mi,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(so,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,120); Wait(140); PlayTone(doo,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(si,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(so,30); Wait(35); PlayTone(si,30); Wait(35); PlayTone(doo,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(si,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(so,30); Wait(35); PlayTone(si,30); Wait(35); PlayTone(doo,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(ra,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(fa,30); Wait(35); PlayTone(ra,30); Wait(35); PlayTone(doo,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(ra,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(fa,30); Wait(35); PlayTone(ra,30); Wait(35); PlayTone(doo,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(si,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(so,30); Wait(35); PlayTone(si,30); Wait(35); PlayTone(doo,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(si,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(so,30); Wait(35); PlayTone(si,30); Wait(35); PlayTone(doo,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(ra,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(fa,30); Wait(35); PlayTone(ra,30); Wait(35); PlayTone(doo,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(ra,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(fa,30); Wait(35); PlayTone(ra,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(mi,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(so,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(mi,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(so,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,30); Wait(35); // Wait の時間の方を少し長くして PlayTone(Do,30); Wait(35); // 同じ音を続けて鳴らす場合にも PlayTone(ra,30); Wait(35); PlayTone(Do,30); Wait(35); PlayTone(fa,120); Wait(140) Wait(20); } } task main() { SetSensor(SENSOR_1, SENSOR_TOUCH); start play_music ; // 演奏を開始 OnFwd(OUT_A+OUT_B); // 前進 until (SENSOR_1 == 1); stop play_music ; // 演奏を停止 Off(OUT_A+OUT_B); // 動きも停止 } *プログラミングのおおまかな解説 [#dfd10aa8] --------------------------------------------- 説明の便宜上、箱を積み上げるロボットを「ロボットA」、箱を運ぶロボットを「ロボットB」とします ----------------------------------------------- まず、ロボットAは、目の前にある箱を持ち上げます。 OnFwd(OUT_C);// Wait(120); // Off(OUT_C); //箱をつかむ while(SENSOR_1 == 0){OnFwd(OUT_B);}//箱を持ち上げる 上限まで箱を持ち上げると、タッチセンサが反応します。反応したら、ロボットBにメッセージを送り、準備が完了した事を伝えます。 while (SENSOR_2 ==0){SendMessage(1);}//箱を持ち上げたらメッセージを送る ロボットBは、そのメッセージを受信すると、ロボットAが持ち上げた箱の下に、箱を1つ置きます GO(OUT_A+OUT_C);//箱を積み上げるロボットに渡す ロボットAは、タッチセンサによって箱が置かれたことを確認すると、その箱の上に、持ち上げていた箱を重ねて置きます while(Timer(1)<=35){OnRev(OUT_B);} Off(OUT_B); Wait(30); OnRev(OUT_C);//箱を積み上げる Wait(116); Off(OUT_C); アーム等を初期位置に戻します OnRev(OUT_B);//アームの位置を初期状態に戻す Wait(850); 一番最初のプログラムに戻り、目の前にある箱を持ち上げます *試験走行と検証・修正 [#k6654329] 試験走行するなかで、気がついた事を検証した **完成したロボットのスペック [#j925849d] -------------------------------------------- 箱を持ち上げるロボットは、最高で5つ持ち上げる事ができた。すなわち6段まで箱を積み上げることが可能 4段積み上げて、所定の位置に運ぶ作業をするのに、およそ2分30秒かかった。 4段積み上げる作業は、動作は遅いがその分正確である。 ----------------------------------------------- 上の事を考察した結果、競技時間が2分30秒なので4段を積み上げて終了するロボットにすることに決めた。ただ、競技時間がもっとあれば、5,6段も可能である。 *感想 [#ybd808d6] *コメントをどうぞ [#c6af31ac] #comment