目次 #contents *はじめに [#y39db0e1] Mission: ピンポン玉と紙コップを別々に回収して所定の場所に運べ。 #ref(2017b/Member/tetsuya/Mission3/2017b-mission3.png,60%) 黄色:障害物 ピンク:ピンポン玉(2つ)入りの紙コップ 茶色:割り箸 つまり、障害物に触れず、x地点にピンポン玉、y地点に紙コップを運ぶ。時間制限は無し。 *ロボットの説明 [#f7915437] **完成型 [#fffd4457] #ref(2017b/Member/tetsuya/Mission3/zentaizu.jpeg,10%) ↑全体図 手前の装置で紙コップをつかみ、垂直に持ち上げることができる。この動作を組み合わせることで、Missionを遂行する。 **光センサー [#rdca1faa] #ref(2017b/Member/tetsuya/Mission3/sensor.jpeg,10%) ↑2つの光センサー ライントレースをするためのもの(右)と、紙コップを探知するためのもの(左)だ。 **RIS本体の置き方 [#s3a28adf] #ref(2017b/Member/tetsuya/Mission3/ris.jpeg,10%) ↑RIS本体 今回のMissionでは、通信することが必要不可欠だ。RISの場合RIS上部の黒い部分で、赤外線通信をするので、この配置が望ましい。 **紙コップをつかむ装置 [#d4efb8da] #ref(2017b/Member/tetsuya/Mission3/hasamu.jpeg,10%) ↑紙コップをつかむ装置 白い部品が空回りすることで、一定の力でつかみ続けることができる。摩擦を強くするために、ゴムのタイヤを取り付けた。 **紙コップを持ち上げる装置 [#n0ae9ac3] #ref(2017b/Member/tetsuya/Mission3/bure.jpeg,10%) ↑紙コップを持ち上げる装置 32歯のギアを2つ使用した。 紙コップを被せるために、かなり上げなければならない。それゆえ、ロボットが大きくなったが、安定していた。 **紙コップの位置を調整する装置 [#w1bbae19] #ref(2017b/Member/tetsuya/Mission3/bou.jpeg,10%) ↑一見、ただの棒に見えるが… この簡易装置が、大きな役割を果たす。 光センサーで紙コップを見つけた後、この直角の棒の角に紙コップが来るように、車体を動かす。これにより、毎回、同じ位置で、紙コップを掴むことができる。 *プログラミングの説明 (車体) [#n865940d] 空白、空行のみ見やすいように変更。 空白、空行のみ、見やすいように改善した。 **define [#p3ba7937] #define GO_AHEAD 10 #define MOTION_END 20 #define OWARI 30 #define CYOI 40 通信に用いるための数字を定義する。 #define mae(w) ;OnRev(OUT_AC);Wait(w);Off(OUT_AC); #define zennsinn OnRev(OUT_AC); #define usiro(g) OnFwd(OUT_AC);Wait(g);Off(OUT_AC); #define SHIKIICHI 870 #define migisennkai(s) set_power_L;OnFwd(OUT_A);OnRev(OUT_C);Wait(s);Off(OUT_AC); #define hidarisennkai(n) set_power_L;OnFwd(OUT_C);OnRev(OUT_A);Wait(n);Off(OUT_AC); 初期値を定義しておくと便利だ。時間を指定できるように、定義する。 #define shikiichi 48 #define turn_left1 set_power_L;OnFwd(OUT_A);OnRev(OUT_C); #define turn_right1 set_power_L;OnRev(OUT_A);OnFwd(OUT_C); #define turn_left2 set_power_L;Off(OUT_A);OnRev(OUT_C); #define turn_right2 set_power_L;Off(OUT_C);OnRev(OUT_A); ライントレースのために、曲折と旋回を定義する。 #define LOWPOWER 1 #define HIGHPOWER 4 #define set_power_H SetPower(OUT_AC,HIGHPOWER); #define set_power_L SetPower(OUT_AC,LOWPOWER); 紙コップの位置を調整する際、動きが速いと紙コップを飛ばしてしまう恐れがあるため、"set_power"で、力の制御をする。 **sub routine (search) [#ada3c9bd] sub search3() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensorMode(SENSOR_1,SENSOR_MODE_RAW); while(SENSOR_1 < SHIKIICHI -40){ mae(10); } Off(OUT_AC); Wait(100); hidarisennkai(20); Wait(100); mae(30); Wait(300); ClearMessage(); SendMessage(OWARI); } 紙コップを探知するための関数。センサーが条件を満たさなくなるまで、前進する。 左旋回と前進をすることで、紙コップの位置を調整している。 sub search4() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensorMode(SENSOR_1,SENSOR_MODE_RAW); while(SENSOR_1 < SHIKIICHI -40){ mae(020); migisennkai(010); } Off(OUT_AC); Wait(100); hidarisennkai(20); Wait(100); mae(30); Wait(300); ClearMessage(); SendMessage(OWARI); } search3の"while"の中に、右旋回を入れた関数。search3より広範囲を探すことができる。 sub shougaibutsu() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensorMode(SENSOR_1,SENSOR_MODE_RAW); while(SENSOR_1 < SHIKIICHI -130){ mae(10); } Off(OUT_AC); Wait(100); usiro(200); Wait(300); ClearMessage(); SendMessage(OWARI); } 障害物を探知したら、後進する。 **sub routine(line_trace) [#dd066498] sub line_l() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<=550){ if(SENSOR_2 < shikiichi -7){ turn_right2; } else if (SENSOR_2 < shikiichi -4 ){ turn_right2; } else if (SENSOR_2 < shikiichi -1){ zennsinn; } else if (SENSOR_2 < shikiichi ){ turn_left2; } else { turn_left2; } } PlaySound(SOUND_CLICK); Off(OUT_AC); } ラインの左側の境界線を辿っていく。5.5秒でライントレースが終了する。 sub line_ll() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<=300){ if(SENSOR_2 < shikiichi -7){ turn_right1; } else if (SENSOR_2 < shikiichi -4 ){ turn_right2; } else if (SENSOR_2 < shikiichi -1){ zennsinn; } else if (SENSOR_2 < shikiichi ){ turn_left2; } else { turn_left1; } } PlaySound(SOUND_CLICK); Off(OUT_AC); } 3秒間ライントレースをする。時間を文字に置きかえ、task mainで時間を変えていけば、この関数は省略することができそうだ。 sub line_lll() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(SENSOR_1 < SHIKIICHI -40){ if(SENSOR_2 < shikiichi -7){ turn_right1; } else if (SENSOR_2 < shikiichi -4 ){ turn_right2; } else if (SENSOR_2 < shikiichi -1){ zennsinn; } else if (SENSOR_2 < shikiichi ){ turn_left2; } else { turn_left2; } } PlaySound(SOUND_CLICK); Off(OUT_AC); } 紙コップを探知するまで、ライントレースを続ける。こちらもまた、省略することができそうだ。 sub line_k() { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while(FastTimer(0)<=25){ if(SENSOR_2 < shikiichi-6){ turn_right1; } else if (SENSOR_2 < shikiichi -4){ turn_right2; ClearTimer(0); } else if (SENSOR_2 < shikiichi -1){ zennsinn; ClearTimer(0); } else if (SENSOR_2 < shikiichi ){ turn_left2; ClearTimer(0); } else { turn_left2; ClearTimer(0); } } PlaySound(SOUND_CLICK); Off(OUT_AC); } 0.25秒ライントレースを続ける。こちらも同様。 **task main [#a373894e] task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensorMode(SENSOR_1,SENSOR_MODE_RAW); mae(050);line_l();Wait(100);mae(40); SendMessage(CYOI); //1 Wait(50);mae(30);migisennkai(250); line_ll(); line_k();hidarisennkai(140); "SendMessage(変数名)"で変数を送信。"Message(変数名)"で変数を受信。 SendMessage(CYOI); //2 ClearMessage(); "ClearMessage()"で、Messageを0にする。 until(Message() == CYOI); //3 mae(160);Wait(100);ClearMessage(); "until"を使うことで、受信するまで、プログラムを進行させない仕組みになっている。 SendMessage(CYOI); //4 until(Message() == CYOI);//4.5 usiro(180);ClearMessage();hidarisennkai(100); line_lll();shougaibutsu();migisennkai(60); search3();mae(030);Wait(100); SendMessage(CYOI);//5 until(Message() == CYOI); //6 SendMessage(CYOI); //7 migisennkai(150);mae(050); SendMessage(CYOI);//8 ClearMessage(); until(Message() == CYOI);//9 usiro(060);Wait(50);ClearMessage(); hidarisennkai(120);mae(300); migisennkai(050);mae(060); search4();Wait(50); mae(020);migisennkai(040);mae(020); SendMessage(CYOI);//10 until(Message() == CYOI); //11 ClearMessage(); usiro(100); migisennkai(100);mae(080); SendMessage(CYOI); //12 until(Message() == CYOI); //13 ClearMessage(); mae(130); SendMessage(CYOI); //14 until(Message() == CYOI); //15 ClearMessage(); usiro(100);migisennkai(280);mae(030); SendMessage(CYOI); //16 until(Message() == CYOI); //17 usiro(070); } MIssionを遂行するために、繰り返し調整しながら、プログラムした。 *プログラミングの説明(アーム) [#u7d0d8ef] **define [#pb59631b] #define GO_AHEAD 10 #define MOTION_END 20 #define OWARI 30 #define CYOI 40 #define tsukamu OnFwd(OUT_C); #define hanasu Off(OUT_C); #define ageru OnFwd(OUT_B); Wait(230); Off(OUT_B); #define sageru OnRev(OUT_B); Wait(160); Off(OUT_B); #define up(z) OnFwd(OUT_B); Wait(z); Off(OUT_B); #define down(y) OnRev(OUT_B); Wait(y); Off(OUT_B); #define hiraku OnRev(OUT_C); Wait(008);Off(OUT_C); まずは、マクロで定義する。車体と同様の変数も定義する。 **task main [#k5996446] task main() { task main() { until(Message() == CYOI);//1 tsukamu; ClearMessage(); [CYOI]と受信したら、掴む動作を行う。 until(Message() == CYOI);//2 ClearMessage(); up(30);Wait(100); 「ちょい上げ」といい、紙コップを少し上げることで、割りばしを通過することができる。 SendMessage(CYOI);//3 until(Message() == CYOI);//4 up(180); ClearMessage(); x地点で、ピンポン球を排出。 SendMessage(CYOI);//4.5 until(Message() == CYOI);//5 down(180); ClearMessage(); 紙コップを重ねる。 SendMessage(CYOI);//6 ClearMessage(); until(Message() == CYOI);//7 up(50); ClearMessage(); until(Message() == CYOI);//8 Wait(100); down(50);Wait(100); hanasu;Wait(100); tsukamu;Wait(50); up(200); ClearMessage(); SendMessage(CYOI);//9 ClearMessage(); until(Message() == CYOI);//10 ClearMessage(); Wait(100); sageru; SendMessage(CYOI);//11 until(Message() == CYOI);//12 down(040); up(050); ClearMessage(); SendMessage(CYOI);//13 until(Message() == CYOI);//14 down(030); up(100); ClearMessage(); SendMessage(CYOI);//15 until(Message() == CYOI);//16 down(050); hiraku; SendMessage(CYOI);//17 } } 無駄な部分もあり、もっと整理されたプログラムにすることが課題だ。 *おわりに [#ye5e5590] **感想 [#j459c7fc] 今回の課題では、通信について学ぶことができた。最初は、難題だと感じたが、試行錯誤することで、より理解が深くなり、Missionを遂行することができた。ロボコンでは、1位になり、嬉しかった。共に制作した仲間に感謝したい。 **結果 [#od530594] 基本点30点 芸術点19.7点 合計49.7点