目次
#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点

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS