#contents * 課題 [#b7427eda] 課題は[[こちら>2017a/Mission3]]を参照 * ロボット [#n580a019] 最初は缶を集めるロボットと缶を積むロボットを別々に作る予定だったが、1台にしてしまったほうが正確性が出ると判断し、缶を集める機構と缶を積む機構を1台にまとめて積むことにした。 以下でロボットについて詳しく説明をする。 ** ロボット本体 [#z706bc53] 缶を集める機構と缶を積む機構がついている。RIS同士の赤外線部分がくっついているため、RIS同士での通信ができないという心配をする必要がなくなる。 機構を2つ積んだため、ロボットがかなり重くなってしまった。このことが後々あだとなってしまったが、このことについてはプログラムのほうで説明をすることとする。 &ref(2017a/Member/kazubon/Mission3/IMG_0007.jpg,50%,ロボット全体); &ref(2017a/Member/kazubon/Mission3/IMG_0006.jpg,50%,ロボット土台); &ref(2017a/Member/kazubon/Mission3/IMG_0008.jpg,50%,ロボット後ろ); &ref(2017a/Member/kazubon/Mission3/IMG_0005.jpg,50%,RISの写真); 1枚目の写真はロボット全体を上から撮った写真である。長く伸びたブロックが缶を集める機構で、写真左側に付いているのが缶を積む機構である。ロボットの最終形態は、重心の調整のためRISに車輪を取り付けた。(4枚目参照) 2枚目の写真はRISを取り除いて撮影した写真である。ロボットが壊れにくくなるように土台を頑丈に作成した。 3枚目の写真は缶を積む機構の下に取り付けた車輪を撮影した写真である。この車輪を取り付けることで重心が安定し、ロボットを安定した動きにさせることができる。 ** 機構 [#ra92db54] *** 缶を集める機構 [#ie3edbfb] 缶を集めるために長いブロックを組み合わせ、モーターを使ってブロックを広げたり閉じたりできるようにすることで、必要最小限の動きで効率的に缶を集めることができる機構となった。また、ギアにウォームギアを用いることで、缶を倒すことのない速さかつ缶を運ぶことのできる力の強さを実現することができた。 &ref(2017a/Member/kazubon/Mission3/IMG_0001.jpg,50%,機構アップ写真); &ref(2017a/Member/kazubon/Mission3/IMG_0004.jpg,50%,機構全体); *** 缶を積む機構 [#b75da115] 缶をつかむ機構には一定の力以上がかかると空転するギアを用いることで、はさみすぎによる缶のズレ等の2次被害が起こらないようにした。また、光センサーを用いて、缶が最接近したことを認知してから、缶をつかむようにした。なお、光センサーはロボット本体にとりつけた。(4枚目の写真を参照) 缶を上げる機構にはウォームギアを用いることで、缶を多く持ちあげるときに、重力に負けずに持ち上げることのできるようにした。 &ref(2017a/Member/kazubon/Mission3/DSC_0002.jpg,50%,機構横); &ref(2017a/Member/kazubon/Mission3/IMG_0009.jpg,50%,機構の中); &ref(2017a/Member/kazubon/Mission3/DSC_0003.jpg,40%,缶をつかむ機構); &ref(2017a/Member/kazubon/Mission3/DSC_0010.jpg,130%,光センサー); * プログラム [#n2842d44] ロボットは1台であるが、RISは2台積んであるため、缶を集めるプログラムと缶を積むプログラムをそれぞれ1台ずつに入れた。 今回のプログラムはチームの他のメンバーに作ってもらった。そのため、詳しいプログラムの説明は[[こちら>2017a/Member/Kenty/Mission3]]を参照にしていただきたい。 以下に、プログラムを掲載する。 ** 缶を集めるプログラム [#p537dc0b] *** 定数・マクロの定義 [#t8bfa865] センサー値の定義 #define LINE_BLACK 35 // 黒線反応時の光センサ(ライン判定用)の値 #define CAN_SHORT 46 // 缶に接近したときの 光センサ(缶用)の値 動作に関する時間の定義 #define TURN_TIME 145 // 180°反転までの時間 #define APP_TIME 75 // 缶接近までの時間 #define ARM_TIME 200 // アームが真横を向くまでの時間(アームの駆動時間はこれを基準に使用) タイヤの動作の定義 #define FOWORD OnFwd(OUT_AC); // 直進 #define BACK OnRev(OUT_AC); // 後退 #define STOP Off(OUT_AC); // 停止 #define TURN_LEFT OnFwd(OUT_C); OnRev(OUT_A); // 左旋回 #define TURN_RIGHT OnFwd(OUT_A); OnRev(OUT_C); // 右旋回 アームの動作の定義 #define ARM_OPEN OnFwd(OUT_B); // アーム開 #define ARM_CLOSE OnRev(OUT_B); // アーム閉 #define ARM_STOP Off(OUT_B); // アーム停止 通信信号の定義 #define ROGER 1 // <受信・送信> 【了解】 #define GO_AHEAD 10 // <送信> 【行動開始】 #define MOTION_END 20 // <受信> 【動作完了】 *** グローバル変数の定義 [#b08d599a] int trans_sign = 0; // <通信> 送信信号 格納用 int can_cnt = 0; // 缶 積み上げ本数カウント用 *** 通信のサブルーチン [#c4ddc4e4] 受信 sub Reception() { ClearMessage(); // <通信> 初期化(最後に受信した値 → 0) until(Message() == MOTION_END); // <通信> 『20【動作完了】』を受信するまで待機 SendMessage(ROGER); // <通信> 『1【了解】』を送信 } 送信 sub Transmission() { ClearMessage(); // <通信> 初期化(最後に受信した値 → 0) SendMessage(trans_sign); // <通信> 『"trans_sign"の値』を送信 until(Message() == ROGER); // <通信> 『1【了解】』を受信するまで送信し続ける } *** メインタスク [#h9810300] task main() { /*---------- モータパワー・センサ 設定 ----------*/ SetPower(OUT_AC , 3); SetSensor(SENSOR_3 , SENSOR_LIGHT); // 黒線 認識用 SetSensor(SENSOR_1 , SENSOR_LIGHT); // 缶 認識用 /*---------- アームを全開 ----------*/ ARM_CLOSE; // アーム閉 Wait(ARM_TIME); // アームが真横を向くまで閉じる ARM_STOP; Wait(100); /*---------- 缶 回収 ----------*/ FOWORD; // アーム側を前方向として until(SENSOR_3 < LINE_BLACK); // 2つ目の黒線まで前進 until(SENSOR_3 > LINE_BLACK); // until(SENSOR_3 < LINE_BLACK); // STOP; // 停止 Wait(100); ARM_CLOSE; // アーム閉 Wait(ARM_TIME + 50); // アームが平行になるまで閉じる ARM_STOP; Wait(100); BACK; // 缶を揃えるために Wait(50); // 少し下がる STOP; ARM_CLOSE; // アーム閉 Wait(30); // 缶を一列にするためにさらに少し閉じる ARM_STOP; ARM_OPEN; // アームを開き、 Wait(ARM_TIME*2 + 80); // スタート時にあった場所まで戻す ARM_STOP; /*---------- 缶積み上げのための準備 ----------*/ BACK; // 後退して、 until(SENSOR_3 > LINE_BLACK); // 2つ目の黒線まで前進 until(SENSOR_3 < LINE_BLACK); // STOP; //------------------- 発表会ここまで ---------------------------// SetPower(OUT_AC , 7); TURN_LEFT; // 右方向へ Wait(TURN_TIME); // 180°旋回 STOP; SetPower(OUT_AC , 3); BACK; // ハンド側を前方向として until(SENSOR_1 > CAN_SHORT); // 缶の手前まで前進 Wait(20); // (ここから下は、ハンド方向を前方向とする) STOP; /*---------- 缶を積み上げ開始 (3回繰り返し、4段にする) ----------*/ while(pile_up_cnt < 3){ trans_sign = GO_AHEAD; // <通信> 『10【行動開始】』 Transmission(); // 送信 /* - - - - - - - - - - - - - - - - -*/ /* ハンド側が缶の持ち上げを実行 */ /* - - - - - - - - - - - - - - - - -*/ Reception(); // <通信> 『20【動作完了】』が送られてくるまで待機 BACK; // 缶一つ分だけ(次の缶の手前まで) until(SENSOR_1 > CAN_SHORT); // 前進する Wait(20); STOP; trans_sign = GO_AHEAD; // <通信> 『10【行動開始】』 Transmission(); // 送信 /* - - - - - - - - - - - - - - - - - -*/ /* ハンドが缶を置き、初期位置に戻る */ /* - - - - - - - - - - - - - - - - - -*/ Reception(); // <通信> 『20【動作完了】』が送られてくるまで待機 can_cnt++; // 缶の本数 +1 } } 発表会で途中のプログラムで打ち切らざるを得なかったのは、ロボットの重さが原因である。 ロボットが重いため、旋回する際に車輪部分に多大な負荷がかかってしまうために、ギアがかみ合わなくなってしまったり、遠心力によって重心が移ってしまい、車輪が浮いてしまったりしてしまった。そのため、うまく旋回しきらないうちに次のプログラムに進んでしまう。 これによってせっかく並べた缶を散らかしてしまい、結果得点につながらなくなってしまう恐れがあるため、途中のプログラムで打ち切った。 ** 缶を積むプログラム [#o1de0021] *** 定数・マクロの定義 [#fba280d7] ハンド開閉時間の定義 #define HAND_TIME 50 // ハンド開閉 時間 ハンド・上下機構の動作の定義 #define ELEVATE_UP OnFwd(OUT_C); // <ハンド昇降>上昇 #define ELEVATE_DOWN OnRev(OUT_C); // <ハンド昇降>降下 #define ELEVATE_STOP Off(OUT_C); // <ハンド昇降>停止 #define HAND_OPEN OnRev(OUT_B); // <ハンド開閉>開 #define HAND_CLOSE OnFwd(OUT_B); // <ハンド開閉>閉 #define HAND_STOP Off(OUT_B); // <ハンド開閉>停止 通信信号の定義 #define ROGER 1 // <受信・送信> 【了解】 #define GO_AHEAD 10 // <受信> 【行動開始】 #define MOTION_END 20 // <送信> 【動作完了】 *** グローバル変数の定義 [#g1f3d186] int trans_sign = 0; // 送信用 信号 格納変数 int hand_flag = 0; // <ハンド>開閉 判断用 int elevate_flag = 0; // <ハンド>昇降 判断用 int can_cnt = 0; // 積み上げた缶の本数 *** ハンドを昇降させるサブルーチン [#v23e415c] sub Hand_Elevate() { if(elevate_flag == 0){ // ハンド上昇 ELEVATE_UP; until(SENSOR_1 > 385); ELEVATE_STOP; elevate_flag = 1; // ハンド上昇終了 次:降下を実行 } else if(elevate_flag == 1){ // ハンド降下(缶をのせる) ELEVATE_DOWN; until(SENSOR_1 < 360); ELEVATE_STOP; elevate_flag = 2; // ハンド降下終了 次:下降を実行 } else if(elevate_flag == 2){ // ハンド初期位置(一番下)へ移動 ELEVATE_DOWN; until(SENSOR_1 < 3); ELEVATE_STOP; elevate_flag = 0; // ハンド下降終了 次:上昇を実行 } } *** ハンド開閉のサブルーチン [#he539dcd] sub Hand_OC() { if(hand_flag == 0){ SetPower(OUT_C , 3); HAND_CLOSE; Wait(100); SetPower(OUT_C , 6); hand_flag = 1; // ハンド閉 次:ハンドを開く } else{ HAND_OPEN; Wait(HAND_TIME); HAND_STOP; hand_flag = 0; // ハンド開 次:ハンドを閉じる } } *** 通信のサブルーチン [#c32258ca] 受信 sub Reception() { ClearMessage(); // <通信> 初期化(最後に受信した値 → 0) until(Message() == GO_AHEAD); // <通信> 『10【行動開始】』を受信するまで待機 SendMessage(ROGER); // <通信> 『1【了解】』を送信 } 送信 sub Transmission() { ClearMessage(); // <通信> 初期化 (最後に受信した値 → 0) SendMessage(trans_sign); // <通信> 『"trans_sign"の値』を送信 until(Message() == ROGER); // <通信> 『1【了解】』を受信するまで送信し続ける } *** メインタスク [#mf9918b9] task main() { /*---------- モータパワー・センサ 設定 ----------*/ SetSensor(SENSOR_1 , SENSOR_ROTATION); // 回転センサ設定 ClearSensor(SENSOR_1); // 回転センサ初期化 /*---------- 缶 積み上げ(3回繰り返し、4段にする)----------*/ while(can_cnt < 3){ Reception(); // <通信> 『10【行動開始】』を受信するまで待機 Hand_OC(); // 缶をつかむ Hand_Elevate(); // ハンド上昇 trans_sign = MOTION_END; // <通信> 『20【動作完了】』 Transmission(); // 送信 /* - - - - - - - - - - - - - - - - - - -*/ /* 駆動側が缶の手前まで移動 */ /* - - - - - - - - - - - - - - - - - - -*/ Reception(); // <通信> 『10【行動開始】』を受信するまで待機 Hand_Elevate(); // ハンド下降 Hand_OC(); // 缶を放す Hand_Elevate(); // 一番下までハンドを下ろす trans_sign = MOTION_END; // <信号>『20【動作完了】』 Transmission(); // 送信 can_cnt++; // 缶の本数 +1 } Reception(); } * 感想 [#n402b706] この課題をやるにあたり、ロボットでどのように缶を集めて積むか全く想像がつかなかった。しかし、 この課題をやるにあたり、ロボットでどのように缶を集めて積むか全く想像がつかなかった。しかし、時間を重ねるうちにアイデアがおもいついていき、何とか形にすることができた。発表会に至るまでに何度も困難にぶち当たったが、チームのメンバーで協力し合うことで乗り越えることができ、仲も深め合うことができたと思う。なんだかんだで発表会の結果は9点で5位と、まずまずの結果を残すことができてうれしく思った。この講義で学んだことを糧に、これから様々なことに挑戦をしていきたい。