*目次 [#d65b5b80] #contents *課題 [#i59dc094] ~&ref(zumenn.png); ~&ref(zumenn.png); ~フィールドは、図のような課題1で使用した面を二枚つなぎ合わせたものを使います。 ~そして、START地点から始まり、缶を積み上げて行きGOAL地点に積み上げた缶を置くことをします。 ~途中でうまく動かなくなった場合、一回限りやり直しが出来、得点方法は、n段目の空き缶の点数を5n点として、すべての空き缶の点数を合計したものを点数とします。 ~使うロボットは、nqcのロボットを2台使うか、2台の材料を使って1台のロボットのどちらを使ってもよい。 ~自分たちは、1つの方がプログラミングが楽だという理由で、大きなロボットを作ることに決めました。 *メンバー [#e1bd5c6a] ~tomato 工学部電気電子工学科 自分です ~shinshi 工学部情報工学科 クロネコ ~nazan 理学部数学科 魔法使い ~satoT 農学部応用生命科学科 破壊神 *ロボット [#k044dfbe] ~まずは、ロボットの全体を見てください。 ~&ref(DSC_0057.jpg); ~ロボットは、新しく缶を掴むということと、もち上げるということを出来るようになれば、完成です。 ~まず、缶を掴む機構から説明させてください。 ~缶を掴むのは、ギアを三つ使って、回転の方向を変え、ひとつのギアを回転させると、その回転の向きによって、缶を掴む、缶を離すといったことができるような仕組みにしました。 ~アームはツルツルしていて、缶を掴んでも落ちてしまうので、そこは、輪ゴムを掛けて、摩擦係数を上げるという手を使いました。これは、他の班の人に教えてもらいました。ありがとうA上君。 ~&ref(DSC_0060.jpg); ~次に、缶をもち上げる機構です。 ~これはよく知らないのですが、ロボティクスの前期を受けていたy8さんという人が作ってくれたジャッキというものらしいです。自分はロボット担当ということでしたので、その仕組みは調べたのですが、菱形がいくつか繋がったような形をしている一番下のどちらかを固定して、もう一方を内側に移動させることで、菱形が伸び、その背が高くなるというものです。マジックハンドを想像してもらうといいかもしれません。 ~&ref(aaa.jpg); ~初めから動くようになっていたようなのですが、どうやら持ってくるまでに落として壊してしまったらしく、動かず、しかし、せっかく作ってもらったものだからと、直させられましたが、何も理解していなかった自分は、鼻血が出そうでした。 ~このロボットは前輪駆動。前の日まで私が作っていた車輪では、満足なされなかった破壊神が前輪だけ前半で作ったものと同じものを作って来ました。後輪は、それを哀れんだ他の班の人が作ってくれました。一番上の写真を見ていただけるとわかると思います。 ~どの方向にロボットを動かしても、それに倣うようにタイヤの向きが変わるものになっています。 *プログラミング [#x230dad6] ~手が痛くなってきたので、ここからは常態になりますが、ご了承ください。 *ライントレースをする方のプログラミング。2台分のロボットを使用しているので、1台目の方のロボットに入れるプログラミング。 [#n43fff7e] *謝罪 [#e9f9e150] ~プログラミングの説明に入る前に、誠に申し訳ありません。許してください。 ~初めに非常に言いにくいことですが、このプログラミングは本番でも練習でもろくに動きませんでした。許してください。ここからは、どういうプログラミングを書こうとしたかの説明になりますが、よろしくお願いいたします。 #define kurot 37 //黒線の中央を表す数字 #define kurok 42 //黒線の境界を表す数字 #define kurog 45 //ギリギリ黒線を認識する部分を表す数字 #define shiro 47 //白色の部分を表す数字 #define hi 5 //大きい力を出力を表す数字 #define low 2 //小さい力を出力を表す数字 #define sh SetPower(OUT_AC, hi); //ACに大きい力を出力 #define sl SetPower(OUT_AC,low); //ACに小さい力を出力 #define slh SetPower(OUT_A,low); SetPower(OUT_C,hi); //Aには小さい力、Cには大きい力を出力 #define shl SetPower(OUT_A,hi); SetPower(OUT_C,low); //Aには大きい力、Cには小さい力を出力 #define sss SetPower(OUT_A,1);SetPower(OUT_C,1); //ACに最も小さい力を出力する #define mae sh OnFwd(OUT_AC); //前へ進む #define ushiro OnRev(OUT_AC); //後ろへ進む #define migi0 sl; OnFwd(OUT_C); Off(OUT_A); //右へ曲がる #define migi1 sl; OnFwd(OUT_C); OnRev(OUT_A); //右旋回 #define hidari0 sl; Off(OUT_C); OnFwd(OUT_A); //左へ曲がる #define hidari1 sl; OnRev(OUT_C); OnFwd(OUT_A); //左旋回 #define STEP 1 //ここから下は任意の数字。その関数が何のために必要かを記す //whieの周期を1で回す #define nMAX 5 //hidar1を五回したら交差点と判断 #define yasumi Off(OUT_AC); Wait(100); //1秒間小休止 #define cross 25 //交差点を渡る時間 #define cross_line sl; OnFwd(OUT_AC); Wait(cross); yasumi; //交差点を渡るための定義付け #define kousin 5 //わずかに後ろに下がるためのメッセージ #define pdown 6 //完全にアームを下げるためのメッセージ #define zensin 7 //わずかに前進 #define kyatti 8 //缶をキャッチ #define anoraitore 10 //一つ目の交差点を通るためのメッセージ #define kankan 11 //上にあげた2段目の缶を一段目の缶までの高さまで下げるためのメッセー ジ #define bnoraitore 12 //二つ目の交差点を通るためのメッセージ #define cnoraitore 13 //出発点のT字路を通るためのメッセージ #define bniraitore 14 //2回目の二つの交差点を通るためのメッセージ #define kanhanasu 15 //缶を離すためのメッセージ #define tyoikousin 16 //少しだけ後進するためのメッセージ int p=0; //hidari1を通る回数でnMAX以上になると、交差点と判断する int n=0; //交差点を通った回数 sub hidarikan () { //一つ目の缶を通るまでライントレース SetSensor(SENSOR_1,SENSOR_LIGHT); //ポート1を光センサーにする SetSensor(SENSOR_3,SENSOR_LIGHT); //ポート3を光センサーにする while(SENSOR_1 > 55){ //缶用の光センサーが缶が感知するまでライントレース if (SENSOR_1 < kurot){ //光センサーが黒線の中央を感知 hidari1; //左旋回する p++; //左旋回した回数 } else { if(SENSOR_1 < kurok){ //光センサーが黒線の境界を感知 hidari0; //左に曲がる } else if (SENSOR_1 < kurog){ //光センサーが黒線のギリギリの場所を感知 mae; //前へ進む } else if (SENSOR_1 < shiro){ //光センサーが白を感知 migi0; 右へ曲がる } else { //それ以外の時 migi1; //右旋回する } p=0; //左旋回した回数のカウントを0にする } Wait(STEP); //STEP秒間で周期を回す } yasumi; //小休止 migi1; //右旋回 Wait(nMAX*STEP*2); //右旋回する時間を調整する cross_line; //交差点を渡る n++; //交差点を渡った回数をカウントする p=0; //左旋回した回数のカウントを0にする } sub hidaria () { //交差点を2回渡るまでのライントレースをする SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); while(n < 2){ //二回渡ったらの分岐のための条件を置く while(p < nMAX){ if (SENSOR_1 < kurot){ //上でも使用したライントレースを使う。上との違いは二回交差点を渡ったら終わるという点のみ hidari1; //全く同じなので省略 p++; } else { if(SENSOR_1 < kurok){ hidari0; } else if (SENSOR_1 < kurog){ mae; } else if (SENSOR_1 < shiro){ migi0; } else { migi1; } p=0; } Wait(STEP); } yasumi; migi1; Wait(nMAX*STEP*2); cross_line; n++; p=0; } } sub hidarib () { //交差点を3回渡るまでのライントレースをする SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); while(n < 3){ while(p < nMAX){ if (SENSOR_1 < kurot){ //これも上と同じ、なぜ同じようなものがたくさんあるのかというと、缶の位置まで行くのに、必要なライントレースを使用するからである hidari1; p++; } else { if(SENSOR_1 < kurok){ hidari0; } else if (SENSOR_1 < kurog){ mae; } else if (SENSOR_1 < shiro){ migi0; } else { migi1; } p=0; } Wait(STEP); } yasumi; migi1; Wait(nMAX*STEP*2); cross_line; n++; p=0; } } sub hidaric () { //交差点を4回渡るまでのライントレースをする SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); while(n < 4){ while(p < nMAX){ if (SENSOR_1 < kurot){ //全く同じ hidari1; p++; } else { if(SENSOR_1 < kurok){ hidari0; } else if (SENSOR_1 < kurog){ mae;} else if (SENSOR_1 < shiro){ migi0; } else { migi1; } p=0; } Wait(STEP); } yasumi; migi1; Wait(nMAX*STEP*2); cross_line; n++; p=0; } } sub hidarid () { //交差点を7回渡るまでライントレース SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); while(n < 7){ while(p < nMAX){ if (SENSOR_1 < kurot){ // hidari1; p++; } else { if(SENSOR_1 < kurok){ hidari0; } else if (SENSOR_1 < kurog){ mae; } else if (SENSOR_1 < shiro){ migi0; } else { migi1; } p=0; } Wait(STEP); } yasumi; migi1; Wait(nMAX*STEP*2); cross_line; n++; p=0; } } task main () { int p=0; //hidari1を通る回数でnMAX以上になると、交差点と判断 int n=0; //交差点を通った回数 int k=0; //メッセージを送った回数 migi0;until(SENSOR_1 < 45); Off(OUT_AC); 黒線に当たるまで、右に曲がる hidarikan(); //缶を感知するまで、ライントレース ClearMessage(); //余分に入っていたメッセージをリセット SendMessage(kyatti); //もう1台のロボットに信号を送る、あちら側ではロボットを掴むプログラムが発動する Wait(10); //0.1秒間待つ ClearMessage(); //メッセージをリセット while(k < 1){ //一つ目のメッセージを受信するまで待機 until(Message() == anoraitore); hidaria(); //一つ目の交差点を渡るまでライントレース k++; //メッセージ送った回数をカウントする } hidarikan(); //2個目の缶を感知するまでライントレース ClearMessage(); //メッセージをリセット SendMessage(kankan); //2段目の缶を一段目の缶の高さまで Wait(10); //0.1秒間待つ ClearMessage(); //メッセージをリセット while(k < 2){ //2つ目のメッセージを受信するまで待機 until(Message() == kousin); OnRev(OUT_AC); //わずかに後進する Wait(10); Off(OUT_AC); k++; //メッセージを送った回数をカウントする } ClearMessage(); SendMessage(pdown);//メッセージのリセット、そしてメッセージを送る Wait(10); ClearMessage(); while(k < 3){ //3つ目のメッセージを受信するまで待機 until(Message() == zensin); OnFwd(OUT_AC); Wait(10); Off(OUT_AC); k++; } ClearMessage(); SendMessage(kyatti);//缶を掴むプログラム Wait(10); ClearMessage(); while(k < 4){ //4つ目のメッセージを受信するまで待機 until(Message() == bnoraitore); hidarib(); hidari1; //ゴールの所に缶を置くためのプログラム Wait(50); OnFwd(OUT_AC); //ここでの時間がまだ不確実で、ちゃんと置けるかどうかは不明だが、円の中に入って缶を置く場所で止まる Wait(25); OnRev(OUT_AC); Wait(50); Off(OUT_AC); migi0; Wait(50); migi1;until(SENSOR_1 <45); Off(OUT_AC); hidarikan(); k++; } ClearMessage(); SendMessage(kyatti); //缶を掴む Wait(10); ClearMessage(); while(k < 5){ //5回目のメッセージを受信するまで待機 until(Message() == cnoraitore); メッセージをもらうと十字を進む hidaric(); hidarikan(); k++; } ClearMessage(); SendMessage(kankan); //缶を持ち上げるメッセージを送る Wait(10); ClearMessage(); while(k < 6){ //6回目のメッセージを受信するまで待機 until(Message() == kousin); //メッセージをもらうと後ろに進む OnRev(OUT_AC); Wait(10); Off(OUT_AC); k++; } ClearMessage(); SendMessage(pdown); //ここで缶を置くためにアームを下げさせる Wait(10); ClearMessage(); while(k < 7){ //7回目のメッセージを受信するまで待機 until(Message() == zensin); メッセージをもらうと前に進む OnFwd(OUT_AC); Wait(10); Off(OUT_AC); k++; } ClearMessage(); SendMessage(kyatti); 缶を掴む Wait(10); ClearMessage(); while(k < 8){ //8回目のメッセージを受信するまで待機 until(Message() == bniraitore); //交差点を曲がる hidarid(); hidari0; Wait(10); OnFwd(OUT_AC); Wait(15); k++; } ClearMessage(); SendMessage(kanhanasu); 缶を離す。ここで缶を移動させるためのプログラミングが終わり、最後に、少し後ろに下がって終了する Wait(10); ClearMessage(); while(k < 9){ //9回目のメッセージを受信するまで待機 until(Message() == tyoikousin); //少し後進する OnRev(OUT_AC); Wait(100); Off(OUT_AC); k++; } } *アームを動かすためのプログラミング(二つ目のロボットに入れる) [#e120378e] #define hi 1 //高い力を出力 #define low 1 //低い力を出力 #define lift_up OnFwd(OUT_AB); //ジャッキを上げる #define lift_down OnRev(OUT_AB); //ジャッキを下げる #define tukamu OnRev(OUT_C); //アームをつかむ #define release OnFwd(OUT_C); //アームを離す #define MOVE_TIMEA 280 //ジャッキを上げる時間 #define MOVE_TIMEB 140 //ジャッキを下げる時間 #define MOVE_TIMEC 30 //2段目の缶が1段目の缶の高さまで下げる時間 #define MOVE_TIMED 250 //一段分の缶の高さを下げる時間 #define kousin 5 //ここからは任意の数字である。重複するので、それが何のためにあるのかは省略する #define pdown 6 #define zensin 7 #define kyatti 8 #define anoraitore 10 #define kankan 11 #define bnoraitore 12 #define cnoraitore 13 #define bniraitore 14 #define kanhanasu 15 #define tyoikousin 16 int k=0; task main() { ClearMessage(); //メッセージをリセット while(k < 1){ //一つ目のメッセージを受信されるまで待機 until(Message() == kyatti); //缶をキャッチするメッセージを受信する tukamu; //缶をつかむ Wait(50); lift_up; //缶を上げる Wait(300); k++; //kの回数をカウント } ClearMessage(); //メッセージをリセット SendMessage(anoraitore); Wait(10); while(k < 2){ //二つ目のメッセージを受信されるまで待機 ClearMessage(); //メッセージをリセット until(Message() == kankan); lift_down; //アームを下げる Wait(MOVE_TIMEC); Off(OUT_AB); release; //缶を離す Wait(50); Off(OUT_C); k++; } ClearMessage(); SendMessage(kousin); Wait(10); ClearMessage(); while(k < 3){ //3つ目のメッセージを受信するまで待機 until(Message() == pdown); メッセージを受け取ると、アームを下げる lift_down; Wait(MOVE_TIMED); Off(OUT_AB); k++; } ClearMessage(); SendMessage(zensin); 前進するプログラミングを一つ目に送る Wait(10); ClearMessage(); while(k < 4){ //4つ目のメッセージを受信するまで待機 until(Message() == kyatti); tukamu; Wait(50); k++; } ClearMessage(); SendMessage(bnoraitore); 交差点判断のメッセージをもう一方に送る Wait(10); ClearMessage(); while(k < 5){ //5つ目のメッセージを受信するまで待機 until(Message() == kyatti); 受信したら缶を掴むプログラミング tukamu; Wait(50); lift_up; Wait(MOVE_TIMEA); k++; } ClearMessage(); SendMessage(cnoraitore); //出発地点にT字路まで、 Wait(10); ClearMessage(); while(k < 6){ //6つ目のメッセージを受信するまで待機 until(Message() == kankan); //アームを上げるプログラミング lift_down; Wait(MOVE_TIMEC); release; //缶を離す Wait(50); k++; } ClearMessage(); SendMessage(kousin); //わずかに後進 Wait(10); ClearMessage(); while(k < 7){ //7つ目のメッセージを受信するまで待機 until(Message() == pdown); //完全に下がる lift_down; Wait(MOVE_TIMED); Off(OUT_AB); k++; } ClearMessage(); SendMessage(zensin); //わずかに前進 Wait(10); ClearMessage(); while(k < 8){ //8つ目のメッセージを受信するまで待機 until(Message() == kyatti); //メッセージを受け取って缶を掴む tukamu; Wait(50); k++; } ClearMessage(); SendMessage(bniraitore); //ゴール地点までライントレース ClearMessage(); while(k < 9){ //9つ目のメッセージを受信するまで待機 until(Message() == kanhanasu); //缶を離す release; Wait(50); k++; } ClearMessage(); SendMessage(tyoikousin); //少し後進するというメッセージの送信をして終了 Wait(10); Off(OUT_ABC); } *反省 [#y095db3b] ~前回の反省を生かし、早めにロボットを完成させようとしたが、ロボットが運ぶ時に壊れてしまって、それを直すというところに、時間のロスが多かったのが本当に悔しかったです。 ~来年は全部紙に書くか、ロボットを持ち運ぶことを安全にすることができるような、何かを考えておこうと思います。 ~最後の発表の時、破壊神君にタイヤをむしり取られ、プログラミングが入らないと、癇癪を起こしてジャッキを破壊された時は、少し泣いた。来年は死ぬほど頑丈に作る。