#contents *メンバー [#j6101771] ・saborijini ~・bosoo ~・hodaka ~・snowdrop *課題について [#sf79c1d2] **課題:紙コップ収集分別ロボット [#jb006a0e] 2台のロボットで紙コップを収集し、同じ番号の書かれている紙コップに重ねる #ref(http://yakushi.shinshu-u.ac.jp/robotics/?plugin=ref&page=2014a%2FMission2&src=2014a-mission2.png) **フィールドの説明 [#l0983e23] フィールドは課題1で使用した紙を2枚つなぎ合わせる (詳細な図面は課題1を参照)。 ~図の右半分の黄色い地点には、その数字と同じ数字が書いてある紙コップが置かれている。 また左半分のA,B,Cの地点にも1から3までの数字が書かれている紙コップが置かれているが、 どのコップをどの地点に置くかは直前にサイコロを振って次のように決める。 ~ |サイコロの目|A|B|C| |LEFT:1|1|2|3| |LEFT:2|1|3|2| |LEFT:3|2|1|3| |LEFT:4|2|3|1| |LEFT:5|3|1|2| |LEFT:6|3|2|1| その他ルールなど詳細は[[課題2:http://yakushi.shinshu-u.ac.jp/robotics/?2014a%2FMission2#p66feff7]] *本体について [#h2cafae9] #ref(IMG_0388.jpg) 全体の写真。NXTを縦に重ねることで、横幅の軽減に努めた。アームは上部に取り付けた。 #ref(IMG_0385 .jpg) 超音波センサーを前につけた。これにより、紙コップの位置を正確に測ることが出来る。縦につけたほうがより精度が増したと考えられる。またラインとセンサーを下向きにつけ、フィールドのラインを識別した。これにより、ロボット自身が今どこにいるのか確認できる。 #ref(IMG_0386.jpg) 前からの写真。 #ref(IMG_0387.jpg) アームの写真。ラインセンサーを横につけることで、紙コップの色の識別を可能にした。アームを持ち上げる部分、紙コップを持ち上げる部分の二つのモーターを分けた。モーター一つの重さが予想以上にあったため、アシストにを輪ゴムを使うことで、アームを上げる動作をスムーズにした。 #ref(IMG_0389.jpg) アームの横からの写真。 #ref(IMG_0390.jpg) 紙コップを挟む動作。 *プログラムについて [#rdc34368] ここでは、同じようなプログラム[PlaySound(SOUND_CLICK);やOff(OUT_BC);Wait(500);]が使われている。これはある動作が完了したことを示すために音を鳴らし、各動作をはっきりさせるために一時停止をしている。また今回の課題は余り時間をかけられなかったので1個のコップの運搬までしかプログラミングが出来ていない。コップは茶色のコップを使用し、白黒の着色で区別した。 **紙コップの運搬ルート [#s8a1e5a6] #ref(2014a-mission2.png) まず、スタート位置から、赤色のルートを通り、紙コップAまで移動する。紙コップAをアームでつかみ、アームについているライントセンサーで紙コップの側面の色を判別(白・茶・黒)それに対応する1〜3の紙コップへ移動(青・緑・ピンクのルート)。後、B、Cも同様にして運ぶ予定であった。基本的に、曲がるタイミングはフィールド上のラインに依存した。 **マスター(親機)のプログラム [#rd63967e] #define black 36 #define speed 35 #define A 38 #define B 65 task main() { SetSensorLight(S1); SetSensorLight(S4); SetSensorLowspeed(S3); int msg; until(BluetoothStatus(1) == NO_ERR); RemotePlayTone(1,440,1000); Off(OUT_BC); Wait(1200); OnFwdSync(OUT_BC,speed,0); until(SENSOR_1 < black); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnFwdSync(OUT_BC,speed,0); Wait(400); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnFwdSync(OUT_BC,speed,0); until(SENSOR_1 < black); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnFwdSync(OUT_BC,speed,0); Wait(500); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnFwd(OUT_B,speed); OnRev(OUT_C,speed); until(SENSOR_1 < black); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(700); OnFwd(OUT_B,speed); OnRev(OUT_C,speed); Wait(180); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnFwdSync(OUT_BC,speed,0); Wait(1100); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnFwdSync(OUT_BC,speed,0); until(SENSOR_1 < black); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnFwdSync(OUT_BC,speed,0); Wait(500); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnFwdSync(OUT_BC,speed,0); until(SENSOR_1 < black); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnFwdSync(OUT_BC,speed,0); Wait(600); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnFwd(OUT_B,speed); OnRev(OUT_C,speed); until(SENSOR_1 < black); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnRevSync(OUT_BC,speed,0); Wait(2000); OnFwdSync(OUT_BC,speed,0); until(SensorUS(S3) <= 12); Off(OUT_BC); Wait(100); RemoteStartProgram(1,"z_slave.rxe"); while(msg != 11){ ReceiveRemoteNumber(MAILBOX1,true,msg); } PlaySound(SOUND_CLICK); if(SENSOR_4 < A){ OnFwdSync(OUT_BC,speed,0); until(SensorUS(S3) <= 18); Off(OUT_BC); Wait(100); RemoteStartProgram(1,"z_slave-2.rxe"); while(msg != 12){ ReceiveRemoteNumber(MAILBOX1,true,msg); } PlaySound(SOUND_CLICK); }else if(SENSOR_4 < B){ OnFwdSync(OUT_BC,speed,0); Wait(2000); PlaySound(SOUND_CLICK); Off(OUT_BC);Wait(500); OnFwd(OUT_B,speed); OnRev(OUT_C,speed); until(SensorUS(S3) < 18); PlaySound(SOUND_CLICK); Off(OUT_BC); Wait(100); RemoteStartProgram(1,"z_slave-2.rxe"); while(msg != 12){ ReceiveRemoteNumber(MAILBOX1,true,msg); } PlaySound(SOUND_CLICK); }else{ OnFwdSync(OUT_BC,speed,0); Wait(6000); OnFwd(OUT_B,speed); OnRev(OUT_C,speed); until(SensorUS(S3) < 30); PlaySound(SOUND_CLICK); Off(OUT_BC); Wait(100); OnFwdSync(OUT_BC,speed,0); until(SensorUS(S3) <= 18); Off(OUT_BC); Wait(100); RemoteStartProgram(1,"z_slave-2.rxe"); Off(OUT_BC); Wait(100); RemoteStartProgram(1,"z_slave-2.rxe"); while(msg != 12){ ReceiveRemoteNumber(MAILBOX1,true,msg); } PlaySound(SOUND_CLICK); } } **スラーブ(子機)のプログラム [#aec6a496] task main() { PlaySound(SOUND_CLICK); OnFwd(OUT_A,70);Wait(2800);Off(OUT_A); OnRev(OUT_C,20);Wait(800);Off(OUT_C); OnRev(OUT_A,60);Wait(2800);Off(OUT_A); SendResponseNumber(MAILBOX1,11); Wait(1000); PlaySound(SOUND_CLICK); } task main() { PlaySound(SOUND_CLICK); OnFwd(OUT_A,60);Wait(900);Off(OUT_A); OnFwd(OUT_C,20);Wait(700);Off(OUT_C); OnRev(OUT_A,80);Wait(1800);Off(OUT_A); SendResponseNumber(MAILBOX1,12); Wait(1000); PlaySound(SOUND_CLICK); } *感想 [#t682257e] 今回私は、プログラムについてより一層、考えが深まった。今回の課題は、ただ単純に一連の動作をプログラムにするのではなく、ロボット自身にその状況を理解させる必要があった。そのためには、何通りもの動作を前もってプログラムする必要がある。センサーによる知覚をどうすればより正確に、安定してプログラムとかみ合わせることが出来るのか。それはロボット本体、ハードを変えるよりも、プログラムを変えることに重点を置くべきなのだと改めて感じた。