2006a/C4

課題3 光を追いかけるロボット

ロボットの特徴

  • ベースはテキストに載っているものを使用
  • 光センサを一個(プログラムによっては二個)搭載させている

ロボットの製作過程

  • 6月30日:課題2のロボットを分解しつつ、課題3のロボットの構成を考える。
    課題3はプログラムが重要と判断し、ロボットはとりあえずテキストに載っているベースを使用したものにする。
  • 7月1日:光センサを二個搭載させたロボットが完成する。
    光センサを二個用いたプログラムが完成しないため、光センサを一個にしたロボットにする。
  • 7月5日:再び光センサを二個搭載させたものにする。

プログラムの製作過程

  • 6月30日:光を追いかけるにはどうすればいいか考える。この日はまったく見当がつかず、終了する。
  • 7月1日:Timer,whileを使用したプログラムを考えてみる。光センサを二個用いたプログラムが完成せず、やむを得ず光センサを一個にしてプログラムを考える。
    何度か調整をした結果、光を追いかけるプログラムが完成する。
  • 7月2日:曲のプログラムの製作に取り掛かる。著作権の問題などあるので民謡にすることにする。
    いろいろ考えた結果、簡単な「かえるの歌」に決定する。
    1時間のしないうちに「かえるの歌」の試作プログラムが完成する。音の高さや鳴らす時間を調整し、納得するものになる。
  • 7月3日:(1)〜(4)の内(1)にし、そのプログラムの製作に取り掛かる。光を追いかけるプログラムと曲のプログラムをmixさせる。
    (1)は難なく完成する。この勢いで(4)の条件を加えた(1)のプログラムの製作に取り掛かる。
    しかし、なかなかうまくいかず行き詰る。
  • 7月4日:光を追いかけるプログラムを変更する。while(true)を用いたものに改良する。
    なんとか(4)の条件を組み込んだプログラムが完成する。
  • 7月5日:時間に余裕ができたため、光センサを二個用いたプログラムを考える。
    (1)での条件のプログラムは完成する。
  • 7月6日:光センサでどの位置が一番明るいと認識する位置などを調べる。それを、プログラムに活用しプログラムの質の向上を計った。
  • 7月12日:abs(SENSOR_1-SENSOR_3)<○を用いて値に誤差が出来ても直進できるようにした。

曲のプログラム

  • 「かえるの歌」をハ長調で演奏するプログラム
製作日:7月3日
製作者:コミ  shibata
==============
#define Do 523
#define Re 587
#define Mi 659
#define Fa 698
#define So 784
#define Ra 880

task play_music()
{
   while(true)
   {
       PlayTone(Do,25); Wait(30);     //鳴らす時間を設定
       PlayTone(Re,25); Wait(30);   //また音が繋がらない
       PlayTone(Mi,25); Wait(30);   //ようにWaitを使って
       PlayTone(Fa,25); Wait(30);   //調整している
       PlayTone(Mi,25); Wait(30);
       PlayTone(Re,25); Wait(30);
       PlayTone(Do,25); Wait(60);            
       
       PlayTone(Mi,25); Wait(30);
       PlayTone(Fa,25); Wait(30);
       PlayTone(So,25); Wait(30);
       PlayTone(Ra,25); Wait(30);
       PlayTone(So,25); Wait(30);
       PlayTone(Fa,25); Wait(30);
       PlayTone(Mi,25); Wait(60);
       
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       
       PlayTone(Do,12); Wait(15);
       PlayTone(Do,12); Wait(15);
       PlayTone(Re,12); Wait(15);
       PlayTone(Re,12); Wait(15);
       PlayTone(Mi,12); Wait(15);
       PlayTone(Mi,12); Wait(15);
       PlayTone(Fa,12); Wait(15);
       PlayTone(Fa,12); Wait(15);
       
       PlayTone(Mi,25); Wait(30);
       PlayTone(Re,25); Wait(30);
       PlayTone(Do,25); Wait(60);
    }
}

工夫した点 苦労した点

  • いろいろな長調を試したがハ長調が一番よかったので、ハ長調にした。
  • 休符のことも考え、Wait()の時間を何度も変更した。
  • 四分音符や二分音符はどのくらいの時間でちょうど良いのか見つけるためにWait()の時間を何度も調整したのにかなり苦労した。

光源を見失った時には曲を演奏しながら旋回して光源を探すプログラム

  • 光センサ一個の場合
    製作日:7月1日
    製作者:コミ
    ==============
    #define Do 523
    #define Re 587
    #define Mi 659
    #define Fa 698
    #define So 784
    #define Ra 880
task play_music()                //かえるの歌を演奏
{
   while(true)
   {
       PlayTone(Do,25); Wait(30);
       PlayTone(Re,25); Wait(30);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Fa,25); Wait(30);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Re,25); Wait(30);
       PlayTone(Do,25); Wait(60);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Fa,25); Wait(30);
       PlayTone(So,25); Wait(30);
       PlayTone(Ra,25); Wait(30);
       PlayTone(So,25); Wait(30);
       PlayTone(Fa,25); Wait(30);
       PlayTone(Mi,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,12); Wait(15);
       PlayTone(Do,12); Wait(15);
       PlayTone(Re,12); Wait(15);
       PlayTone(Re,12); Wait(15);
       PlayTone(Mi,12); Wait(15);
       PlayTone(Mi,12); Wait(15);
       PlayTone(Fa,12); Wait(15);
       PlayTone(Fa,12); Wait(15);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Re,25); Wait(30);
       PlayTone(Do,25); Wait(60);
       Wait(20);
    }
}
#define turn_left OnFwd(OUT_C);OnRev(OUT_A);
#define turn_right OnFwd(OUT_A);OnRev(OUT_C);
#define turn_stop Float(OUT_A+OUT_C);
#define TURN_TIME 500
                        
task main ()
{
	SetSensor(SENSOR_1,SENSOR_LIGHT);  //センサ1が光センサであることを宣言
	int light_max=0,time_max=0;         //整数型変数light_max,time_maxを宣言し0を代入
	turn_right;                         //右旋回
	start play_music;                   //演奏停止
	ClearTimer(0);             //FastTimer(0)をリセット
	while(FastTimer(0) < TURN_TIME)
 {
	   if(SENSOR_1 > light_max)
    {
		    light_max=SENSOR_1;      //light_maxをSENSOR_1に代入
		    time_max=FastTimer(0);  //time_maxをFastTimerに代入
		 }
	 }
		turn_stop;          //旋回停止
		Wait(50);
		turn_left;          //左旋回
		Wait(TURN_TIME-time_max);
		turn_stop;          //旋回停止
		stop play_music;       //演奏停止
		while(true)                  //以下無限ループ
   {
      if(SENSOR_1<=light_max)
      {
         OnFwd(OUT_A+OUT_C);                   //直進
      }
      else{
           Wait(100);
           int light_max=0,time_max=0;
           turn_right;                      //右旋回
           start play_music;                   //演奏停止
           ClearTimer(0);                      //FastTimer(0)をリセット
           while(FastTimer(0) < TURN_TIME)
           {
              if(SENSOR_1 > light_max)
              {
                 light_max=SENSOR_1;           //light_maxをSENSOR_1に代入
                 time_max=FastTimer(0);        //time_maxをFastTimerに代入
              }
           }
            turn_stop;                         //旋回停止
            Wait(50);          
            turn_left;                   //左旋回
            Wait(TURN_TIME-time_max);
            turn_stop;                         //旋回停止
            stop play_music;                   //演奏停止
            }
  }
}
  • 光センサ二個の場合
    製作日:7月5日
    製作者:コミ
    変更日:7月12日 SENSOR_1,SENSOR_3の値に誤差が出来ても前進出来るようにした点
    ==============
    #define Do 523
    #define Re 587
    #define Mi 659
    #define Fa 698
    #define So 784
    #define Ra 880
task play_music()           //かえるの歌を演奏
{
   while(true)
   {
       PlayTone(Do,25); Wait(30);
       PlayTone(Re,25); Wait(30);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Fa,25); Wait(30);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Re,25); Wait(30);
       PlayTone(Do,25); Wait(60);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Fa,25); Wait(30);
       PlayTone(So,25); Wait(30);
       PlayTone(Ra,25); Wait(30);
       PlayTone(So,25); Wait(30);
       PlayTone(Fa,25); Wait(30);
       PlayTone(Mi,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,12); Wait(15);
       PlayTone(Do,12); Wait(15);
       PlayTone(Re,12); Wait(15);
       PlayTone(Re,12); Wait(15);
       PlayTone(Mi,12); Wait(15);
       PlayTone(Mi,12); Wait(15);
       PlayTone(Fa,12); Wait(15);
       PlayTone(Fa,12); Wait(15);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Re,25); Wait(30);
       PlayTone(Do,25); Wait(60);
       Wait(20);
    }
}
#define turn_left OnFwd(OUT_C);OnRev(OUT_A);
#define turn_right OnFwd(OUT_A);OnRev(OUT_C);
#define turn_stop Float(OUT_A+OUT_C);
#define TURN_TIME 500
#define turn_left_1 OnFwd(OUT_C);
#define turn_right_1 OnFwd(OUT_A);
task main ()
{
	SetSensor(SENSOR_1,SENSOR_LIGHT);    //センサ1が光センサであることを宣言
	SetSensor(SENSOR_3,SENSOR_LIGHT);    //センサ3が光センサであることを宣言
	int light_max=0,time_max=0;          //整数型変数light_max,time_maxを宣言し0を代入
	turn_right;               //右旋回
	start play_music;                    //演奏停止
	ClearTimer(0);              //FastTimer(0)をリセット
	while(FastTimer(0) < TURN_TIME)
  {
	   if(SENSOR_1> light_max)
    {
		    light_max=SENSOR_1;   //light_maxをSENSOR_1に代入
		    time_max=FastTimer(0); //time_maxをFastTimerに代入
		 }
   }
		turn_stop;          //旋回停止
		Wait(50);
		turn_left;                  //左旋回
		Wait(TURN_TIME-time_max);
		turn_stop;                  //旋回停止
		stop play_music;            //演奏停止
		while(true)                 //以下無限ループ
   {
      if(abs(SENSOR_1-SENSOR_3<=5))       //SENSOR_1,SENSOR_3の値が誤差5以内の時
      {
           OnFwd(OUT_A+OUT_C);               //直進する
      }
      if(SENSOR_1 > SENSOR_3)                //SENSOR_1の値の方が大きい時
      {
           turn_left_1;                   //左旋回
      }
      if(SENSOR_1 < SENSOR_3)                //SENSOR_3の値の方が大きい時
      {
           turn_right_1;                  //右旋回
      }
      if((SENSOR_1 < 45)&&(SENSOR_3 < 45))                       //SENSOR_1,SENSOR_3が45以下の時  
      {
           Wait(50);
           int light_max=0,time_max=0;
           turn_right;                  //右旋回
           start play_music;                 //演奏停止
           ClearTimer(0);                    //FastTimer(0)をリセット
           while(FastTimer(0) < TURN_TIME)
           {
              if(SENSOR_1 > light_max)
              {
                 light_max=SENSOR_1;         //light_maxをSENSOR_1に代入
                 time_max=FastTimer(0);      //time_maxをFastTimerに代入
              }
           }
            turn_stop;                 //旋回停止
            Wait(50);
            turn_left;                       //左旋回
            Wait(TURN_TIME-time_max);
            turn_stop;                       //旋回停止
            stop play_music;                 //演奏停止
      }
  }
}

工夫した点 苦労した点

  • どのようにして光源の方向に向かせるかでかなり悩んだ。
  • 二個センサを用いた場合に一個の場合のプログラムをちょっとかえればいいと思っていたが、そうはうまくいかず二個のセンサの明るさに多少誤差があってもプログラムどうりに動かせるようにするなど苦労した。
  • 二個センサを用いたことにより一個のときのような直線的な動き(光源を見失ったら光源を探し見つけたら直進、また見失ったら探して直進)ではなくなり滑らかに(曲線的な動きをしながら)光源について来るものになった。
  • Timerを用いて光源までの時間を計り、TURN_TIMEからその時間を引き、光源の方向に向かせるようにした。
  • while(true)で繰り返しで動作させるプログラムにした。
  • マクロを使用するなどしてスマートなプログラムなるようにした。
  • このプログラムを製作するにあたって、周りの明るさを光センサで計った。それにより、高い確率で光を追いかけたり、探したりするようになった。
  • アドバイスをもらったのでそれを用いて、値に誤差が出来ても直進できるようにした。

最初のプログラムに『光源に近づき過ぎると停止する』を追加したプログラム

製作日:7月4日
製作者:コミ
==============
#define Do 523
#define Re 587
#define Mi 659
#define Fa 698
#define So 784
#define Ra 880
task play_music()            //かえるの歌を演奏
{
   while(true)
   {
       PlayTone(Do,25); Wait(30);
       PlayTone(Re,25); Wait(30);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Fa,25); Wait(30);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Re,25); Wait(30);
       PlayTone(Do,25); Wait(60);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Fa,25); Wait(30);
       PlayTone(So,25); Wait(30);
       PlayTone(Ra,25); Wait(30);
       PlayTone(So,25); Wait(30);
       PlayTone(Fa,25); Wait(30);
       PlayTone(Mi,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,25); Wait(60);
       PlayTone(Do,12); Wait(15);
       PlayTone(Do,12); Wait(15);
       PlayTone(Re,12); Wait(15);
       PlayTone(Re,12); Wait(15);
       PlayTone(Mi,12); Wait(15);
       PlayTone(Mi,12); Wait(15);
       PlayTone(Fa,12); Wait(15);
       PlayTone(Fa,12); Wait(15);
       PlayTone(Mi,25); Wait(30);
       PlayTone(Re,25); Wait(30);
       PlayTone(Do,25); Wait(60);
       Wait(20);
    }
}
#define turn_left OnFwd(OUT_C);OnRev(OUT_A);
#define turn_right OnFwd(OUT_A);OnRev(OUT_C);
#define turn_stop Float(OUT_A+OUT_C);
#define TURN_TIME 500
task main ()
{
	SetSensor(SENSOR_1,SENSOR_LIGHT);    //センサ1が光センサであることを宣言
	int light_max=0,time_max=0;          //整数型変数light_max,time_maxを宣言し0を代入
	turn_right;                  //右旋回
	start play_music;                    //演奏停止
	ClearTimer(0);                       //FastTimer(0)をリセット
	while(FastTimer(0) < TURN_TIME)
 {
	   if(SENSOR_1 > light_max)
    {
		    light_max=SENSOR_1;   //light_maxをSENSOR_1に代入
		    time_max=FastTimer(0);  //time_maxをFastTimerに代入
		 }
	 }
		turn_stop;         //旋回停止
		Wait(50);
		turn_left;          //左旋回
		Wait(TURN_TIME-time_max);
		turn_stop;         //旋回停止
		stop play_music;      //演奏停止
		while(true)                //以下無限ループ
   {
      if(SENSOR_1<=light_max)
      {
           OnFwd(OUT_A+OUT_C);              //直進する
      }
      if(SENSOR_1>80)                  //80より値が大きい時
      {
           Off(OUT_A+OUT_C);               //停止する
      }
      if(SENSOR_1<45)                  //45より小さい時
      {
           Wait(100);
           int light_max=0,time_max=0;
           turn_right;                  //右旋回
           start play_music;                //演奏停止
           ClearTimer(0);                   //FastTimer(0)をリセット
           while(FastTimer(0) < TURN_TIME)
           {
              if(SENSOR_1 > light_max)
              {
                 light_max=SENSOR_1;       //light_maxをSENSOR_1に代入
                 time_max=FastTimer(0);    //time_maxをFastTimerに代入
              }
           }
            turn_stop;              //旋回停止
            Wait(50);
            turn_left;                     //左旋回
            Wait(TURN_TIME-time_max);
            turn_stop;                     //旋回停止
            stop play_music;               //演奏停止
           }
  }
}

工夫した点 苦労した点

  • 最初のプログラムに明るさがある一定の数値になったら止まるという動作を書き加えた。

プログラムによるロボットの動作

  • これらのプログラムでロボットがどのような動きをするか流れを軽く説明する。
  • 最初のプログラム(光源を見失った時には曲を演奏しながら旋回して光源を探す センサ二個の場合)
    • まず、曲を流しながら光源を探す。このとき光源のあるところまでの時間を計測しており、あらかじめプログラムしておいた旋回時間から光源のあるところまでの時間を減算することで光源の方向にロボットを向かせることができる。
    • そして二個のセンサの値が誤差5以内だった場合には直進、右側のセンサの方が明るいときは左旋回、左側のセンサの方が明るいときは右旋回をし、ある一定の値になったらまた光源を探しながら曲を流すという動きをするプログラムである。
  • 「光源に近づき過ぎると停止する」というプログラム
    • 最初のプログラムのときと同じように光源を探す。
    • センサの値がある一定の値になるまでは直進、その値より大きくなると停止、さらに設けた値より小さくなった場合には光源を探し始めるという動作をするプログラムである。

残っている問題点  

  • 「光源に近づきすぎると停止」のプログラムでは、周りの環境によってうまく動作してくれない時がある点。               
  • 走らせる環境によっては光源を見つけられないか、そのままずっと真っ直ぐ走り続けてしまう点。

反省点

  • 課題3の締め切り期間が一週間しかなかったため、プログラムにしか時間をかけることが出来なかった。
    なのでロボットには工夫もなにも無いものになってしまった。
  • ロボットにもっと工夫を凝らし、より良いものを作り上げたかった。
  • 自分(コミ)が作ったプログラムでは周りの環境で、うまくいったりいかなかったりするので、そのところを改良していきたい。
  • (4)の条件のプログラム(光センサ二個の場合)が完成しなかったので、できたら完成させたい。
    また、他の条件の場合のプログラムにも挑戦してすべて完成させたかった。
  • ロボコン前の最後の課題というだけあり、プログラムの製作で何度も行き詰った。
    行き詰ることがわかっていたにも関わらず取り組みが遅かったことに反省...

コメント

  • コメントをどうぞ
  • 左右のライトセンサの値を比較する際、まったく同じ値になってロボットが直進する時間は極めて短いので、差の絶対値がある値よりも小さいという条件、例えば、 abs(SENSOR_1-SENSOR_3) < ○ のような条件にすることもできると思います。 -- 松本(教員)? 2006-07-11 (火) 14:23:55
  • 「アドバイスをもらったのでそれを用いて、値に誤差が出来ても直進できるようにした。」とありますが、どのようなアドバイスからどのように修正したのか書いてみるといいですね。 -- まいける(TA) 2006-07-28 (金) 17:19:31


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2006-07-28 (金) 17:19:31 (4771d)