[[2019a/Member]] #contents *課題3:ボール運搬ロボット [#t0a921e9] **フィールドの説明 [#ga6480ef] &ref(課題3 フィールド説明2.png); +フィールドは課題2で使用した紙を使用する。 +生協のお弁当の四角いプラ容器2つをそれぞれ円内に置き、片方に玉を2個入れる。 +残りの2個の玉は課題2と同じ位置に置く。その際、ゴムタイヤやプレートの上に置いてもよい。 +プラ容器には色をつけたり文字や記号を書いてもよい。 +プラ容器は両面テープ等でフィールドに固定してもよい。 +2枚の紙の境界にはそれぞれ幅1cm、合計2cmの黒線を描いてもよい。 **ルール [#q54f8f20] +競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで。 +図のA地点または(および)A'地点からスタートする。ただし接地している部分はそれぞれの領域内に収まるものとする(線上はOK)。上空部分は領域からはみ出していてもよい。 +開始の合図から5秒以内にスタートボタンを押す作業を完了すること。 +競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。 +途中でうまく動かなくなった場合、1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい)。 +競技終了後、ロボットが、ゴールのプラ容器に触れていてはいけない。 +競技終了後、もともと玉が入っていたプラ容器が、ゴールのプラ容器に触れていてはいけない。 *ロボットの説明 [#va172a24] **アームの説明 [#af94082a] 今回はモーターを2つ使って,ボールをととる動作と,ボールを放す動作に分けて動くようにした. ***ボールを取る動作 [#e38c3a04] ボールを取る動作はゴムを使う機構にした.上からボールを押したときにゴムでとるような造りだ. &ref(bo-ru toru.jpg); ***ボールを箱に入れる動作 [#eb5bf674] ボールを箱に入れる動作は長い棒をうまく使ってできるようにした. &ref(bo-ru toru3.jpg);&ref(bo-ru hanasu2.jpg); 長い棒が閉じているときはボールが落ちないようになっているが,長い棒が開くとそこからボールが落ちるような仕組みだ. 両側から閉じたかったので歯車を2枚使った. &ref(bo-ru hanasu.jpg); **足まわりの説明 [#v589206f] 足まわりのところはアームが重くなってしまっているので本体を乗せる部分を強化したりタイヤの部分を中心に強くした. &ref(nxt support.jpg); 光センサーはタイヤの近くに設置しライントレースをしやすくした. &ref(hikari sensa.jpg); *経路の説明 [#v64c0bfb] **1つ目のピンポン玉を入れるまでの経路 [#e1780a00] &ref(課題3 一つ目のボール.png); **2つ目のピンポン玉を取るまでの経路 [#i121372b] &ref(課題3 二つ目のボール.png); *2台のNXTの連結 [#yc0e6f88] 前回と違うところはNXTが2つあるので2つを連結させて動かしたところだ.2台のNXTの連結はBluetoothと呼ばれる近距離の無線を使って2台で通信することによって作動させる. 2台のうちの片方がマスターとなりもう一台はスレーブという役割になる.プログラムについては次に説明する. *プログラムの説明 [#v99e6db1] 今回も課題2の時と同様に光センサーを使ってライントレースをするプログラムにした. **定義 [#c60a9e04] ***光センサーの定義 [#y71f15ed] #define BL 40 // 灰色 #define WH 47 // 灰白 #define HB 32 // 灰黒 #define HW 55 // 真っ白 &ref(kadai3.png); ***基本動作の定義 [#k2ff3d11] #define left OnFwd(OUT_B,45);OnRev(OUT_C,40); // より左折 #define right OnFwd(OUT_C,45);OnRev(OUT_B,40); // より右折 #define lefts OnFwd(OUT_B,38);OnFwd(OUT_C,25); // 少し左折 #define rights OnFwd(OUT_C,38);OnFwd(OUT_B,25); // 少し右折 ***グローバル変数 [#y55ab4d7] #define CONN 1 // スレーブの接続番号 **アームのサブルーチン&プログラム [#de49ff99] ***アームを上げ下げ [#f32b6fec] +アームを上げる ++マスター側 sub arm_up() //アームを上げる { int msg; // 受け取った値を格納する変数 until(BluetoothStatus(1)==NO_ERR); // 接続できるまで待つ RemoteStartProgram(1,"TAI(S1).rxe"); while(msg !=11){ ReceiveRemoteNumber(MAILBOX1,true,msg); // MAILBOX1の値を受け取りmsgに格納 } Wait(2000); } ++スレーブ側 sub arm_up_s() { OnRev(OUT_C,50); Wait(5000); Off(OUT_C); } task main() { arm_up_s(); SendResponseNumber(MAILBOX1,11); // MAILBOX1に11を送信 } +アームを下げる ++マスター側 sub arm_down() //アームを下げる { int msg; //受け取った値を格納する変数 until(BluetoothStatus(1)==NO_ERR); // 接続できるまで待つ RemoteStartProgram(1,"TAI(S2).rxe"); while(msg !=12){ ReceiveRemoteNumber(MAILBOX1,true,msg); // MAILBOX1の値を受け取りmsgに格納 } Wait(2000); } ++スレーブ側 sub arm_down_s() { OnFwd(OUT_C,30); Wait(3000); Off(OUT_C); } task main() { arm_down_s(); SendResponseNumber(MAILBOX1,12); // MAILBOX1に12を送信 } ***長い棒の開け閉め [#wf044be0] +棒を開ける ++マスター側 sub arm_open() //棒を開ける { int msg; //受け取った値を格納する変数 until(BluetoothStatus(1)==NO_ERR); //接続できるまで待つ RemoteStartProgram(1,"TAI(S3).rxe"); while(msg !=13){ ReceiveRemoteNumber(MAILBOX2,true,msg); // MAILBOX2の値を受け取りmsgに格納 } Wait(2000); } ++スレーブ側 sub open_s() { OnFwd(OUT_B,30); Wait(3000); Off(OUT_B); } task main() { open_s(); SendResponseNumber(MAILBOX2,13); // MAILBOX2に13を送信 } +棒を閉める ++マスター側 sub arm_close() //棒を閉める { int msg; //受け取った値を格納する変数 until(BluetoothStatus(1)==NO_ERR); //接続できるまで待つ RemoteStartProgram(1,"TAI(S4).rxe"); while(msg !=14){ ReceiveRemoteNumber(MAILBOX2,true,msg); //MAILBOX2の値を受け取りmsgに格納 } Wait(2000); } ++スレーブ側 sub close_s() { OnRev(OUT_B,50); Wait(5000); Off(OUT_B); } task main() { close_s(); SendResponseNumber(MAILBOX2,14); // MAILBOX2に14を送信 } **アーム以外のサブルーチン [#d144c74d] ***ライントレース [#ec318eaa] sub hidari() { SetSensorLight(S3); long t0=CurrentTick(); while(CurrentTick()-t0<=250){ if(SENSOR_3>HW){ // センサー3がHWより大きかったらより右に曲がる right; t0=CurrentTick(); }else if(SENSOR_3>WH){ // センサー3がWHより大きかったら少し右に曲がる rights; t0=CurrentTick(); }else if(SENSOR_3>BL){ // センサー3がBLより大きかったら直進する OnFwd(OUT_BC,30); t0=CurrentTick(); }else if(SENSOR_3>HB){ // センサー3がHBより大きかったら少し左に曲がる lefts; t0=CurrentTick(); }else{ left; // それ以外の値だったらより左に曲がる } } Off(OUT_BC); } ***交差点横断 [#g3421d67] 交差点の横断は前回と同じように連続して黒が一定の時間続いたらで止まるようにする. 交差点に来たら下記の通りに進んで横断する sub oudann() { right; //右折 Wait(300); Off(OUT_BC); OnFwd(OUT_BC,30); //直進 Wait(500); Off(OUT_BC); } 横断した後はラインに戻るために下記のようなプログラムにした. sub magari() { SetSensorLight(S3); int nOnline=0; while(nOnline<4600){ if(SENSOR_3>HW){ right; nOnline++; }else if(SENSOR_3>WH){ rights; }else if(SENSOR_3>BL){ OnFwd(OUT_BC,30); }else if(SENSOR_3>HB){ lefts; }else{ left; } } Off(OUT_BC); } *メインプログラム [#n85e20dd] task main() { hidari(); oudann(); magari(); arm_up(); OnFwd(OUT_BC,30); Wait(300); Off(OUT_BC); arm_down(); arm_close(); left; Wait(1500); Off(OUT_BC); OnFwd(OUT_BC,30); Wait(2000); Off(OUT_BC); arm_up(); arm_down(); left; Wait(2500); Off(OUT_BC); OnFwd(OUT_BC,40); Wait(5000); Off(OUT_BC); hidari(); oudann(); hidari(); oudann(); hidari(); arm_up(); arm_open(); } *結果 [#r23dc413] ロボコンの結果は一つもボールをとれなかった. *反省・感想 [#e703271c] 初めての4人作業でしっかりと協力できたので良かったと思う.しかし,機械の方ではアームの部分が重くなってしまったので重心が傾いたり,思うように動かない場面があったり,プログラミングの方では,本番で全然思い通りに動かなかったりした部分があったので課題の残るものとなってしまった.光センサーを2つ使っているところもあり学ぶ部分も多かった.人間ならボールを容器に入れるなんて簡単なのに、ロボットでやるとうまくいかなかった.。だから、人間や動物が目的を達成するためにする行動をプログラムによって、再現するのは難しいと思った。また、人間のような動きをさせることが共通の課題なんだろうと思った.。