2012b/Member

メンバー

Konbu・・・・繊維学部機械ロボット学系 ロボ作り初心者。

ARomeo・・・理学部応用生物学科         社長。

課題

・図のようなコースを各自で作成した上で、次のような動作をするロボットを作成せよ。

・1人目 i.スタート地点から出発し、スタート地点外のすぐ近くに置かれたピンポン玉をつかむ。
ii.ピンポン玉をつかんだら速やかにスタート地点の境界の黒線に戻り、そこから黒線に沿って動いてゴール地点を目指す。ただしT字路では、直進、右折、左折を正しく判断させること。また、曲線部中央の障害物に接触しないようにすること。
iii.ゴール地点に到達したら、ゴールエリア外からピンポン玉をゴールにシュートする。 ただし、どうしてもエリア外からのシュートが難しい場合は、エリア内からシュートした後、エリアから出てもよい。

・2人目 i.上の動作でスタートとゴールを逆にして同様の動きをするプログラムを作成せよ。ロボット本体は共通のものを使うとする。 

2012b-mission1.png

ロボットの紹介

・説明

高さと長さが目立つ構造で、ヘラクレスオオカブトに似た形になりました。

アーム部分を、ボールを取る動作と蹴る動作をなるべく簡略するための構造としました。

201212172028000.jpg

・写真の真ん中の黄色のアーム部分でボールを捉え、左の黒のアームでボールが横から転がるのを抑えています。

右のアームはアーム全体を持ち上げるのと同時にボールが発射するためのアーム。

201212171955000.jpg

・このように三つのアームから成り立つ機構であり、モーターBを上げる動作と下げる動作の二つだけでボールの捕獲とキックができます。

201212172037000.jpg

プログラム

戦略 1

交差点を曲がらないようにするため黒い線を捉えると直進するようにしましたが、

しかしそれでは二個目の交差点を越えられないので、タイマーで時間を計測しプログラム

を切り替えることにしました。

大きく分けて四つのプログラムから成り立ってをり、

なるべく時間の誤差が少なくするためにプログラムの切り替え場所を増やしました。

#define BLACK 35 //しきい値
#define u_turn  OnRev(OUT_A); OnFwd(OUT_C);  //モーターAを後退、Cを前進
#define go_forward OnFwd(OUT_AC);      // 前進
#define turn_left OnRev(OUT_A); OnFwd(OUT_C);   // モーターAを後退、Cを前進
#define turn_right OnFwd(OUT_A); OnRev(OUT_C);  // モーターAを前進、Cを後退
#define n_turn OnFwd(OUT_A); OnRev(OUT_C);   //  モーターAを前進、Cを後退
#define STEP 1 

 task main()
{
   SetSensor(SENSOR_3, SENSOR_LIGHT);
   ClearTimer(3);
   OnFwd(OUT_B);   //   ―蠶蠱呂らボールを取るためのプログラム。
   Wait(20);
   OnFwd(OUT_AC);
   Wait(90);
   Off(OUT_B);
   Off(OUT_AC);
   Wait(70);
   OnFwd(OUT_AC);
   Wait(30);
   ClearTimer(3);
   while (FastTimer(3) <=100){   //   ▲棔璽襪鮗茲辰晋紂黒い線に戻るための
   if (SENSOR_3 <= BLACK){        プログラム。
              Off(OUT_AC);                  
              Wait(50);
         } else if(SENSOR_3 > BLACK && FastTimer(3) <=40){
                 OnFwd(OUT_AC);
                 Wait(5);
         } else if(SENSOR_3 > BLACK && FastTimer(3) >40){
                 OnRev(OUT_AC);
                 Wait(5);
           }
          }
    ClearTimer(3);
    while (FastTimer(3) <=650){   // 
       if (SENSOR_3 <= BLACK){
            go_forward;
            Wait(10);
           turn_right;
            Wait(10);
            ClearTimer(0);
      }else if(FastTimer(0) >=100){
             u_turn;
            ClearTimer(0);
      }else if(FastTimer(0) >40){
             turn_right;              
      }else if(SENSOR_3 > BLACK){                
             turn_left;       
    }
   }  
   Off(OUT_AC);
   Wait(5);
   u_turn;
   Wait(40);
   ClearTimer(3);
    while (FastTimer(3) <=100){
        if (SENSOR_3 <= BLACK){
              Off(OUT_AC);
              Wait(50);
         } else if(SENSOR_3 > BLACK){
               u_turn;
               Wait(10);
 }
}
   Off(OUT_AC);
   Wait(10);
   ClearTimer(3);
    while (FastTimer(3) <=2400){   // 
       if (SENSOR_3 < BLACK ){
             go_forward;  
                       
           ClearTimer(1);
           ClearTimer(0);
      }else if(SENSOR_3 > BLACK && FastTimer(1) >=60){
             n_turn
      }else if(SENSOR_3 > BLACK && FastTimer(0) >=20){
             turn_left;        
      }else if(SENSOR_3 > BLACK ){
             turn_right;
    }  
  }
 Off(OUT_AC);
 Wait(5);
     
 ClearTimer(3);
    while (FastTimer(3) <=1000){  // 
       if (SENSOR_3 < BLACK ){
             go_forward;           
           
          ClearTimer(1);
          ClearTimer(0);
    }else if( FastTimer(1) >=10){
            u_turn;
    }else if( FastTimer(0) >=70){
            turn_right;  
    }else if(SENSOR_3 > BLACK ){                  
            turn_left;
    }   
   }
   Off(OUT_AC);
   Wait(5);

   ClearTimer(3);
    
    while (FastTimer(3) <= 800){  // 
       if (SENSOR_3 < BLACK){
             go_forward;
           Wait(10);
           ClearTimer(0);
      }else if(SENSOR_3 > BLACK && FastTimer(0) >=40){
             n_turn;
      }else if(SENSOR_3 > BLACK && FastTimer(0) >=10){
             turn_left;  
      }else if(SENSOR_3 > BLACK){
             turn_right;

    }  
}
    Off(OUT_AC);  // 
    Wait(100);
    OnRev(OUT_AC);
    Wait(60);
    Off(OUT_AC);
    turn_left;
    Wait(40);
    OnFwd(OUT_B);
    Wait(20);
    Off(OUT_B);
    Off(OUT_AC);

 }

戦略 2

ここでは上記の,らГ離廛蹈哀薀爐寮睫世鬚靴燭い隼廚い泙后

無題.png

まずこのプログラムは上の図でいう右からのスタート専用のプログラムです。赤い丸はその地点の近くでプログラムが切り替わることを表しています。では,ら(o・・o)/

  SetSensor(SENSOR_3, SENSOR_LIGHT); 
   ClearTimer(3); //タイマー3をゼロにリセット
   OnFwd(OUT_B);  //モーターBを前進(アーム上昇)
   Wait(20);   
   OnFwd(OUT_AC);  //前進
   Wait(90);
   Off(OUT_B);   //モーターBを後退(アーム下降)
   Off(OUT_AC);
   Wait(70);
   OnFwd(OUT_AC); //前進
   Wait(30);
  ClearTimer(3); 

ご覧の通りシンプルなプログラムでモータBをOnFwdすることによりアームを持ち上げ、

進み、Offにすることによりアームが自然と落ちるのでボールを掴める所まで行くとアー

ムが下げるという作戦です。

  while (FastTimer(3) <=100){
  if (SENSOR_3 <= BLACK){
             Off(OUT_AC);  //モーターABを停止
             Wait(50);
        } else if(SENSOR_3 > BLACK && FastTimer(3) <=40){ //しきい値より高いか
             OnFwd(OUT_AC);                 0.4秒たったら前進
             Wait(5);
        } else if(SENSOR_3 > BLACK && FastTimer(3) >40){ //しきい値より高いか
             OnRev(OUT_AC);                0.4秒以上で後退 
             Wait(5);                    
         }
        }

このプログラムはボールを取ったあと光センサーが白を感知すると前進し、それでもレイ

ルを感知できなければバックするプログラム。ロボの最初の位置は固定しましたが、ボー

ルを取ったあと白を感知すると、うまく動いてくれなかったのでこのように修正が自動で

できるようにしました。

 while (FastTimer(3) <=650){ //6.5秒間続ける
      if (SENSOR_3 <= BLACK){ //しきい値より小さければ0.1秒前進した後
           go_forward;      0.1秒右折する。
           Wait(10);      
          turn_right;
           Wait(10);
           ClearTimer(0);
     }else if(FastTimer(0) >=100){  //左折が1秒以上でuturn
            u_turn;
           ClearTimer(0);
     }else if(FastTimer(0) >40){  //左折が0.4秒以上で右折
            turn_right;              
     }else if(SENSOR_3 > BLACK){       //しきい値よりも大きければ左折   
            turn_left;       
   }
  }  
  Off(OUT_AC);       //モーターAC停止
  Wait(5);
  u_turn;
  Wait(40);
  ClearTimer(3);
   while (FastTimer(3) <=100){  //1秒間続ける
       if (SENSOR_3 <= BLACK){ //しきい値より小さければ
             Off(OUT_AC);     停止
             Wait(50); 
        } else if(SENSOR_3 > BLACK){  //しきい値より大きければ
              u_turn;            uturn
              Wait(10);

はボールを取ってから最初の交差点までのプログラムで、図の一番右の赤丸付近で終了

するようにしてあります。このプログラムだけ右、左、右、左とジグザグ歩行にプログラ

ムしてあり、直角を超えるためにこのようにしました。While以降のプログラムは図の青

丸付近で停止した後、uturnした時に黒い線上にセンサーを持ってくるためのプログラム

です。ここで白のままだとスタート地点まで戻ってしまいます。

 while (FastTimer(3) <=2400){ //24秒間続ける
      if (SENSOR_3 < BLACK ){ //しきい値以下だと前進
            go_forward;    
                      
          ClearTimer(1);   //タイマー1をゼロにリセット
          ClearTimer(0);   //タイマー0をゼロにリセット
     }else if(SENSOR_3 > BLACK && FastTimer(1) >=60){ //しきい値以上か0.6秒
            n_turn                   でnturn
     }else if(SENSOR_3 > BLACK && FastTimer(0) >=20){  //しきい値以上か0.2秒
            turn_left;                      で左折
     }else if(SENSOR_3 > BLACK ){        //しきい値以上で右折
            turn_right;
   }  
 }
Off(OUT_AC);      //停止
Wait(5);

い録泙留Δら二番めの赤丸まで作動するためのプログラムで、交差点を渡らないための

プログラムでもあります。交差点を渡らない方法としては、上記のプログラムどうり、機

体が線上に真っ直ぐになり、そのまま前進してくれるようにしました。図の右から二番目

の青丸付近で停止、プログラム終了です。

   while (FastTimer(3) <=1000){  //10秒間続ける
      if (SENSOR_3 < BLACK ){
            go_forward;           //前進
          
         ClearTimer(1);     //タイマー1をリセット
         ClearTimer(0);      //タイマー0をリセット
   }else if( FastTimer(1) >=10){  //右折から0.1秒後uturn
           u_turn;
   }else if( FastTimer(0) >=70){ //左折から0.7秒後右折
           turn_right;  
   }else if(SENSOR_3 > BLACK ){   //しきい値以上で左折              
           turn_left;
   }   
  }
  Off(OUT_AC);    //停止
  Wait(5);

図でいうと右から三番目の赤丸までのプログラム。センサーが右によって交差点をわたら

ないようにするために右折に変更するまでの時間を長くしました。青付近で停止して終

了、Δ離廛蹈哀薀爐棒擇蠡悗錣襪uturnしてラインをまた逆戻りしそうになりますが、

またもとの向きに戻ってくれます。(完全にいらない動き(^_^;))

   
    while (FastTimer(3) <= 800){  // 8秒間続ける
      if (SENSOR_3 < BLACK){    //しきし値以下で前進
         go_forward;
          Wait(10); 
          ClearTimer(0);    //タイマー0をリセット
     }else if(SENSOR_3 > BLACK && FastTimer(0) >=40){ //しきい値以上か左折から
          n_turn;                    0.4後nturn
     }else if(SENSOR_3 > BLACK && FastTimer(0) >=10){  //しきい値以上か右折から
          turn_left;                    0.1秒後左折
     }else if(SENSOR_3 > BLACK){        //しきい値以上で右折
          turn_right;
   }
    }

最後の赤丸からゴールまでのプログラムです。ここまでプログラムを分けた理由は、説明

した通り時間の誤差を少なくするためです。ちょうど図の緑の円付近で停止します、あと

はГ離廛蹈哀薀爐妊ックがしやすい位置まで持ってくるだけです。

  Off(OUT_AC);  // ACを停止
   Wait(100);
   OnRev(OUT_AC); // 後退
   Wait(60);
   Off(OUT_AC);  //停止
   turn_left;
   Wait(40);
   OnFwd(OUT_B); //アーム上昇(キック)
   Wait(20);
   Off(OUT_B);  //アーム下降
   Off(OUT_AC);  //停止

キックのためのプログラム。ゴールにむかって真っ直ぐに向きをなをすために、いったん

後退し、右よりの機体を左折することにより向きを直します。またOffBは、ボールを離す

のと同時にキックもしてくれます(詳しくはページ上のアームの説明を参照)

ロボット制作の苦労

ロボット制作

アーム部分をどうするかが一番悩みました。なるべくコンパクトにしようと思いましたが

思いつかずある程度場所をとってしまいました。またボールを掴むだけならなんとかなり

ましたがどうやってボールを発射するかが悩みどころでした。しかし結果的にはキックも

キャッチも両方とも可能なアームを作ることができてよかってです。

プログラム制作

両方の交差点をどうしたら通過できるのかさっぱり分からずじまいで、かなりの時間がか

かりました。また本体の機構を変えるとプログラムも大幅に変更しないといけなくなるこ

とが多く、大変でした。自分の思い通りにいかなに日々が続きましたが、なんとかゴール

できたので良かったです。

反省点

.しきい値の設定が雑だった。

.動きがカクカク

.障害物にぶつかりすぎ

などなど、たくさんの課題が残る結果になってしまいました。次に生かしたいです。

最後に

プログラムだけでなく機構の両方が大切なんだと思い知らされました。でもチーム内で相談しながら作業を進められて楽しかったです。


添付ファイル: file無題.png 153件 [詳細] file201212172037000.jpg 156件 [詳細] file201212171955000.jpg 172件 [詳細] file201212172028000.jpg 166件 [詳細] file2012b-mission1.png 167件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2012-12-21 (金) 02:45:14