今回は二つのロボットをつかい紙コップを運び重ねるというものでした。
基本ルール
・紙コップはC地点、D地点にそれぞれ3個ずつおき、これを交互に重ねること
・ロボット2台はそれぞれA地点、B地点からスタートし、一体型の場合はA地点からスタートする
他にも様々ありますがこの2点を守ればだいたい良いでしょう。
得点の計算方法は
・1段目の紙コップ3点、2段目の紙コップ6点、・・、n段目のコップ3n点、6段目のコップ18点
・奇数段目にあるDのコップと偶数段目にあるCのコップは0点
です。
この他にもすべての班(自分の班を含む)がつける技術点があります。細かく言うと長くなるので割愛しますが、満点で20点です。
私たちはロボットを2台作り、紙コップを運ぶロボット、紙コップを重ねるロボットに分けました。
まずは紙コップを運ぶロボットから見ていこうと思います。
このロボットでは少し切れていますがむらさきの円を描いているところで紙コップを確保し、はこびます。紙コップが倒れないように、少し紫の円の位置を低くしたりと、微調整しています。このロボは一番最初に作ったドライブベースを元に作りましたので意外と簡単な作りになっています。
次に紙コップを重ねるロボットを見ていこうと思います。
このロボットは前についている光センサーで紙コップの白を感知するようになっています。
そして赤で囲った部分で紙コップを持ち上げ、重ねます。
このロボットの工夫したところは様々ありますが、この赤い部分で囲まれたところは特に考えました。なぜならこのロボットは紙コップが光センサーにくっついたときに反応するようにプログラミングをかいたため、そのまま下に紙コップを取りに行ってしまうと紙コップの位置が手間いすぎてつかむことができませんでした。しかしこの斜めになっているパーツを使うことにより、紙コップをある程度前に出すことができ、アームでつかめるようになりました。
私たちはロボットを二つ作ったためドライブベース用とアーム用の2つのプログラミグを書きました。
まずは定義したプログラムから
#define THRESHOLD 42 //閾値 #define gofw OnFwd(OUT_AC);Wait(5); //前へ5秒すすむ #define turn_left Off(OUT_A); OnFwd(OUT_C); //左へ曲がる #define senkai_left OnFwd(OUT_C);OnRev(OUT_A);Wait(63); //左旋回6.3秒 #define turn_right OnFwd(OUT_A); Off(OUT_C); //右へ曲がる #define senkai_right OnFwd(OUT_A);OnRev(OUT_C);Wait(60); //右旋回6秒 #define senkai OnFwd(OUT_A);OnRev(OUT_C);Wait(90); //右旋回90秒 #define STEP 1 //0.1秒ごとに色を認識 #define B_up OnFwd(OUT_B);Wait(80);Off(OUT_B); //囲いを8秒あげる #define B_down OnRev(OUT_B);Wait(80);Off(OUT_B); //囲いを8秒あげる #define back OnRev(OUT_AC);Wait(move_time);Off(OUT_AC); //後退 #define tyousei_l(t) OnFwd(OUT_C);OnRev(OUT_A);Wait(t); //左旋回 #define tyousei_r(t) OnFwd(OUT_A);OnRev(OUT_C);Wait(t); //右旋回 #define watasu OnFwd(OUT_AC);Wait(120);Off(OUT_AC);OnRev(OUT_AC);Wait(50);Off(OUT_AC);Wait(2000); intint move_time; //もう一つのロボへ紙コップを渡す
なぜ左旋回や右旋回が多いかというと、交差点や紙コップを渡した後にライントレースに戻るめに様々な旋回が存在します。少しの調整のためにtyousei_l などが存在します。
ここからはサブルーチンを紹介していきます。
内容に関しては1回課題、2回課題の内容とかぶる部分については説明を省略していきたいとおもいます。
・直進するサブルーチン
void line_follow(int t) //t秒で動く { SetSensor(SENSOR_2, SENSOR_LIGHT); ClearTimer(0); while (Timer(0)<t) { //タイマーがt以下の場合下の操作を行う if (SENSOR_2 < THRESHOLD){ turn_left; } else { turn_right; } Wait(STEP); }Off(OUT_AC); }
簡単に説明しますと。普通のライントレースです。タイマーをセットしたのは急カーブを交差点と勘違いしないように、急カーブでは普通の旋回をするためにタイマーでライントレースを切ったりできるようにしました。
・交差点を直進するサブルーチン
sub crossing_fwd() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; //カウンターをセット while(n<10){ //nが10以下の時この操作を繰り返す if (SENSOR_2 < THRESHOLD){ turn_left;n++; //左へ曲がったとき、カウンターを増やす } else { turn_right;n=0; //右へ曲がった時は増やさない } Wait(STEP); }Off(OUT_AC);Wait(100);gofw; //カウンターが10を超えたときこの操作を行う }
・交差点を止まるサブルーチン
sub crossing_stop() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; while(n<10){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; } else { turn_right;n=0; } Wait(STEP); }Off(OUT_AC);Wait(100); }
これは途中まで交差点を直進するサブルーチンと同じで、最後にnが10を超えた後に止まるだけです。
・交差点を右へ曲がるサブルーチン
sub crossing_right() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; while(n<10){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; } else { turn_right;n=0; } Wait(STEP); }Off(OUT_AC);Wait(100);senkai_right;OnFwd(OUT_AC);Wait(30); }
これも同じく、最後に右へ曲がるだけです
しかしこのライントレースは左側なので右へ曲がるときは直進を入れ線の左に行くようにしています。
sub crossing_left() { SetSensor(SENSOR_2, SENSOR_LIGHT); int n=0; while(n<10){ if (SENSOR_2 < THRESHOLD){ turn_left;n++; } else { turn_right;n=0; } Wait(STEP); }Off(OUT_AC);Wait(100);senkai_left; }
これも同じく、違うのは最後に左へ曲がるだけです。
最後は実際のプログラムですがとても長くなってしまったので文章で説明させていただきます。
まずはA地点からP交差点へ行くのですが、その間の半径5センチの半円で交差点と誤認してしまうのでライントレースの秒数を決めその後は右に旋回させ、乗り越えます。、その後順調にライントレースをしていき、最初はライントレースをして行き、コップをつかみ反転し、B地点へ行き、アームにコップをセットし20秒まちます。そのあとrepeatなどを用いながらC地点、D地点を交互に行きコップを取ってアームにセットします。最後には
だいたいはこのような動きをします
アームのプログラムについては腕の上げ下げと手の開け閉めだけなので短くすみました。
最初に定義したプログラムから見ていきましょう。
#define nigiru OnFwd(OUT_A);Wait(move_timeA);Off(OUT_A); //握ります #define hanasu OnRev(OUT_A);Wait(350);Off(OUT_A); //話します #define arm_up OnFwd(OUT_C);Wait(move_timeB);Off(OUT_C); //アーム上げます #define arm_down OnRev(OUT_C);Wait(500);Off(OUT_C); //長い間アームを下げます #define s_arm_down OnRev(OUT_C);Wait(200);Off(OUT_C); //少しだけアームを下げます int move_timeA; //上記にあるムーブタイムを設置 int move_timeB; // 上に同じく
次に実際に動いたプログラムを見ていきましょう。
task main() { SetSensor(SENSOR_1, SENSOR_LIGHT); int n=0; //カウンターを設置 while(n<=2) //nが2以下の時下の動作を繰り替えす {if(SENSOR_1>50) {move_timeA=400; //move_timeAを4秒に設定 move_timeB=800; //move_timeBを8秒に設定 s_arm_down;hanasu;arm_down; //少しアームを下げ、手を開き、アームを下げる nigiru;move_timeB=move_timeB+80; //8,8秒握ります arm_up;move_timeA=move_timeA+1; //4,01秒握ります n++; //カウンターが増えます } } s_arm_down;hanasu;arm_up;Off(OUT_A); //最後には、コップをはなし、終わります }
私たちの班は、紙コップを一つも円の中に入れることができなかったので、その点では0点です。 しかし、技術点では10.6点となかなかの評価をもらいました。 ロボットのアームの完成度がかなり良かったからだと思います。
今回の課題の二つのロボを使ってコップを重ねるという作業はとても難しく、私たちの考えたロボットでは運の要素が強すぎてとても毎回成功できるようなものではありませんでした。もっと時間を使い班員全員で考えるべきでした。最後に重ねていた班の発想は意外で、とても驚かされました。私にもあのような発想力がほしい。最後に、今回の課題はとても長い時間のかかるものでした。しかしなかなか班員が集まらずロボットを製作するにしても、プログラムを作るにしても一人の人に大きな負担をかけてしまいました。またグループ課題があったときにはしっかり連絡が取れる環境を整えた。い