2007b/MemberOnly/進行状況A


課題2:黒い線に沿って動くロボット

今日のアクセス数 1
総アクセス数 &counter([total|today|yesterday]);
目次

課題

2箇所以上交差点のある周回コース(黒い線)をA0版の画用紙上描き、その自作のコースを3周する
ロボットを作成せよ。ただし、速さと正確さを追求すること。
交差点で優先側を走っていない場合には一時停止し、もう一台のロボットが優先道路上にある場
合には行き過ぎるのを待つこと。
前方を進むもう一台のロボットに追いついて接触した時、以下のいずれかの動作をさせること
(重複しないようにひとり一つ選ぶ)

1、3秒間停止して待つ
2、その場で1回だけ360度旋回する
3、180度旋回して5秒間コースを逆走し、再び180度旋回してもとの向きに走る

コース

画像の説明

特徴and考察 

1、コーナーが多くセンサーの判定間隔を短くする必要がある。
2、交差点の非優先路の間隔が一定ではないので交差点通過後に黒線を探す処理をするプログラムを書く必要がある。
3、交差点通過時の他車との衝突した場合についての処理を考える必要がある

ロボット作成

タッチセンサについて

画像の説明 画像の説明 画像の説明

1、スイッチの黄色い部分が押されると信号を出します。今回の課題では、前を走行するマシンに衝突したときにタッチセンサを反応させ指定された動作を行うようにした。
2、マシン前方にバンパーを装着させれば問題ないと思ったので、最初はシングルバンパーを装着させたが、すれ違い時にもマシンが接触することがあり、コースから外れてしまうことが多々あったため最終的にダブルバンパーに改良し横方向からの接触にも対応できるようにした
3、すこしバンパーが光センサよりも前に出ているので、交差点で一時停止した時に接触してしまった場合を考え、少し後退してから指定された動作をするようにした。

光センサについて

画像の説明 画像の説明

1、光センサは、明るさによって1〜100までの値を判断します。値が大きいほど明るいと判断してくれます。部屋の明るさにもよるが、閾値を40ぐらいで白と黒の区別をつけることができます。私たちは、光センサの閾値を40に設定しました。
2、最初は、黒い線を挟み込んで光センサが黒を見つけたら(閾値が40以下の場合)車体の向きを変えるように設定したが、一時停止線の問題や速さの点で、黒い線にそって走らせ、黒い線からはみ出たら(閾値が40以上の場合に)車体の向きを変えるようにした。
3、光センサが両方とも白と判断すると(閾値が40以上の場合)交差点を渡るプログラムが発動します。

一代目

1、黒線を挟み込み、光センサが黒線を感知したら(閾値が40以下の場合に)車体の向きを調整するようになっている。
2、一時停止線が無いとコースを完走することができない。
3、シングルバンパを使用しているがバンパー部分が光センサよりもかなり前方にはみ出でいるため、もっとコンパクトに
しなくてはならないかもしれない。
4、三輪駆動にして動きやすくした。

ロボット

画像の説明
斜め45度 
画像の説明
下、三輪駆動である。センサとセンサの間に黒線を挟む
画像の説明
正面、センサー二つで黒線を探す
画像の説明
横、車輪の付け替えがしやすい
画像の説明
後方
画像の説明

ソースコード(三秒間停止の場合)

#define Do 523
#define Re 587
#define Mi 659
#define Fa 698
#define So 784
task music1(){//タッチセンサ反応中になる音楽
	while(1){
		PlayTone(Do,20);Wait(20);
		PlayTone(Re,20);Wait(20);
		PlayTone(Mi,20);Wait(20);
		PlayTone(Re,20);Wait(20);
		PlayTone(Do,20);Wait(40);
		PlayTone(Do,20);Wait(20);
		PlayTone(Re,20);Wait(20);
		PlayTone(Mi,20);Wait(20);
		PlayTone(Re,20);Wait(20);
		PlayTone(Do,20);Wait(20);
		PlayTone(Re,20);Wait(20);
	}
}
task music2(){//タッチセンサが反応してないときになる音楽
	while(1){
		PlayTone(Mi,25);Wait(30);
		PlayTone(Re,5);Wait(10);
		PlayTone(Do,15);Wait(20);
		PlayTone(Re,15);Wait(20);
		
		PlayTone(Mi,15);Wait(20);
		PlayTone(Mi,15);Wait(20);
		PlayTone(Mi,35);Wait(40);
		
		PlayTone(Re,15);Wait(20);
		PlayTone(Re,15);Wait(20);
		PlayTone(Re,35);Wait(20);
		
		PlayTone(Mi,15);Wait(20);
		PlayTone(So,15);Wait(20);
		PlayTone(So,35);Wait(40);
		
		PlayTone(Mi,25);Wait(30);
		PlayTone(Re,5);Wait(10);
		PlayTone(Do,15);Wait(20);
		PlayTone(Re,15);Wait(20);
		
		PlayTone(Mi,15);Wait(20);
		PlayTone(Mi,15);Wait(20);
		PlayTone(Mi,35);Wait(40);
		
		PlayTone(Re,15);Wait(20);
		PlayTone(Re,15);Wait(20);
		PlayTone(Mi,25);Wait(30);
		PlayTone(Re,5);Wait(10);		
		PlayTone(Do,55);Wait(60);
		Wait(20);
	}
}
task main (){
	 int i=0;
      SetSensor(SENSOR_1,SENSOR_LIGHT);               
      SetSensor(SENSOR_3,SENSOR_LIGHT);              
      SetSensor(SENSOR_2,SENSOR_TOUCH);
      ClearTimer(0); 
      start music2;                  
      while(Timer(0)<=1000){       		
      		if(SENSOR_2 == 1){// タッチセンサが反応した場合
		       stop music2;
                     	  start music1;        
                         Off(OUT_A+OUT_C ); //3秒停止
                         Wait(300);   
                         i=0;
                         stop music1;
                         start music2;                     
                  } 
                 else { // 2 タッチセンサが反応しない場合
                 	if(SENSOR_1 >40){ // 光センサ1が白と判断
                     		if(SENSOR_3 > 40){ //光センサ1、3共に白と判断した場合
                                            if(0==i){           			                                   			
                           		OnFwd(OUT_A+OUT_C);
                           		Wait(30);
                                   Off(OUT_A+OUT_C);
                                   i++;                                   
                                   PlaySound(SOUND_CLICK);
                                   }
                                   if(1==i){                     			
                           		OnFwd(OUT_A+OUT_C);
                           		Wait(10);
                                   Off(OUT_A+OUT_C);
                                   i++;                                   
                                   PlaySound(SOUND_CLICK);
                                   }
                                   if(2<=i){                                          
                                   	while(true){//黒線を発見できない場合、黒線を発見するまで回転	
                                   		OnFwd(OUT_A);
                                   		OnRev(OUT_C);
                                   		Wait(1);
                                   		if(SENSOR_1<40||SENSOR_3<40){
                                   		i=0;
                                   		break;
                                   		}
                                   	}
                                   }                                                                                                          
                    		}
                    		else { //光センサ1白、3黒の場合
                       			OnFwd(OUT_A); //進行方向左に回転
                       			Off(OUT_C);          
                       			until(SENSOR_3 > 40); 
                       			i=0; 
                          	}
                          }
                  	else { //光センサ1が黒のとき
                        	if(SENSOR_3 > 40){ //光センサ1黒、3白の場合
                       			 Off(OUT_A); //進行方向右に回転
                       			 OnFwd(OUT_C);       
                       			 until(SENSOR_1 > 40);
                       			 i=0;  
                           	 }
                            	else{ // 光センサ1、3ともに黒の場合
                                           OnFwd(OUT_A+OUT_C); //直進
                                           i=0;                                             
                             }                   
                       }
              }// 2 No Touch
     }//while 
     stop music2;
     Off(OUT_A+OUT_C);
}

ソースコード2(その場で360度回転する場合、音楽省略)

task main()
{ 
	SetSensor(SENSOR_1,SENSOR_LIGHT);
	SetSensor(SENSOR_3,SENSOR_LIGHT);
	SetSensor(SENSOR_2,SENSOR_TOUCH);
	int i=0;
	
	
	while(true){
		if(SENSOR_2 == 1){//タッチセンサが反応した場合
			Off(OUT_A+OUT_C);
			Wait(100);
			repeat(2){//360度回転する命令
				OnFwd(OUT_A);
				OnRev(OUT_C);
				Wait(140);
			
			}
			i=0;
		}
		else{
			if(SENSOR_1 > 40){	//光センサ1が白と判断
				if(SENSOR_3 > 40){	//光センサ1、3ともに白と判断した場合
					if(0==i){
						Off(OUT_A+OUT_C);
						Wait(50);
						OnFwd(OUT_A+OUT_C);
						Wait(30);
						i++;
					}
					if(1==i){
						Off(OUT_A+OUT_C);
						Wait(50);
						OnFwd(OUT_A+OUT_C);
						Wait(30);
						i++;
					}
					if(2<=i){//二回進んでも線が発見できない場合は回転して線を探せ
						while(true){
							OnFwd(OUT_A);
							OnRev(OUT_C);
							Wait(1);
							if(SENSOR_1<40||SENSOR_3<40){
								i=0;
								break;
							}
						}
					}
				}
				else{	//光センサ1白、光センサ3黒と判断した場合
					OnFwd(OUT_A); //進行方向左に回転
					Off(OUT_C);
					until(SENSOR_3 > 40);
					i=0;
				}
			}
			else{	//光センサ1が黒を判断
				if(SENSOR_3 > 40){	//光センサ1黒、光センサ3白と判断した場合
					OnFwd(OUT_C); //進行方向右に回転
					Off(OUT_A);
					until(SENSOR_1 > 40);
					i=0;
				}
				else{	//光センサ1、3ともに黒と判断した場合
 					OnFwd(OUT_A+OUT_C); //直進
					i=0;
				}
			}
			
		}
	}
}

二代目

画像の説明
横から見た写真
画像の説明
光センサの幅をなくすことにより白を感知すると(閾値が40以上の場合)進む方向を調節する

改良点

1、車輪を大きいものにすることによって速度をはやくした
2、センサーの幅をなくすことにより黒線を追うようにした。これにより非優先の交差点の認識が可能になった。
3、音を出すことにより進行中の処理を確認することが可能となった。

ソースコード

#define Do 523
#define Re 587
#define Mi 659
#define Fa 698
#define So 784

task music1(){  //タッチセンサが反応しているときの音楽
    while(1){
        PlayTone(Do,20);Wait(20);
        PlayTone(Re,20);Wait(20);
        PlayTone(Mi,20);Wait(20);
        PlayTone(Re,20);Wait(20);
        PlayTone(Do,20);Wait(40);
        PlayTone(Do,20);Wait(20);
        PlayTone(Re,20);Wait(20);
        PlayTone(Mi,20);Wait(20);
        PlayTone(Re,20);Wait(20);
        PlayTone(Do,20);Wait(20);
        PlayTone(Re,20);Wait(20);
    }
}

task music2(){ //タッチセンサが反応してないときになる音楽
    while(1){
        PlayTone(Mi,25);Wait(30);
        PlayTone(Re,5);Wait(10);
        PlayTone(Do,15);Wait(20);
        PlayTone(Re,15);Wait(20);
        
        PlayTone(Mi,15);Wait(20);
        PlayTone(Mi,15);Wait(20);
        PlayTone(Mi,35);Wait(40);
        
        PlayTone(Re,15);Wait(20);
        PlayTone(Re,15);Wait(20);
        PlayTone(Re,35);Wait(20);
        
        PlayTone(Mi,15);Wait(20);
        PlayTone(So,15);Wait(20);
        PlayTone(So,35);Wait(40);
        
        PlayTone(Mi,25);Wait(30);
        PlayTone(Re,5);Wait(10);
        PlayTone(Do,15);Wait(20);
        PlayTone(Re,15);Wait(20);
        
        PlayTone(Mi,15);Wait(20);
        PlayTone(Mi,15);Wait(20);
        PlayTone(Mi,35);Wait(40);
        
        PlayTone(Re,15);Wait(20);
        PlayTone(Re,15);Wait(20);
        PlayTone(Mi,25);Wait(30);
        PlayTone(Re,5);Wait(10);
        
        PlayTone(Do,55);Wait(60);
        Wait(20);
    }
}
task main (){
     int i=0,n=0;
       SetSensor(SENSOR_1,SENSOR_LIGHT);              
       SetSensor(SENSOR_3,SENSOR_LIGHT);             
       SetSensor(SENSOR_2,SENSOR_TOUCH);
       ClearTimer(0);
       start music2;                 
       while(Timer(0)<=1000){               
               if(SENSOR_2 == 1){// タッチセンサが反応したときのプログラム
                     stop music2;
                            start music1;       
                          Off(OUT_A+OUT_C ); //3秒停止
                          Wait(300);  
                          i=0;
                          stop music1;
                          start music2;                    
                   }
                  else { // タッチセンサが反応してないときのプログラム
                      if(SENSOR_1 >40){ // 光センサ1が白と判断
                              if(SENSOR_3 > 40){ //光センサ1、3共に白と判断した場合
                                  if(0==i){                                   
                                    OnFwd(OUT_A+OUT_C);
                                    Wait(30);     //0.3秒間前進
                                    Off(OUT_A+OUT_C);
                                    i++;                                  
                                    PlaySound(SOUND_CLICK);
                                    }
                                    if(1==i){                                 
                                    OnFwd(OUT_A+OUT_C);
                                    Wait(10);              //0.1秒間前進
                                    Off(OUT_A+OUT_C);
                                    i++;                                  
                                    PlaySound(SOUND_CLICK);
                                    }
                                    if(SENSOR_1<40||SENSOR_3<40){
                                              	i=0;
                                            	break;
				    }
                                    if(2<=i){                          
                                        while(true){ 
					    if(SENSOR_1<40||SENSOR_3<40){ //黒線を発見したら元の動作をする
                                            	i=0;
                                            	break;
                                            }   
                                            if(n<=5){ //nが5になるまで左に首振りをする
					    	OnFwd(OUT_A);
                                            	OnRev(OUT_C);
                                            	Wait(1);
						n++;
					    }
					    else if(15<=n&&n<=17){ //nが15から17の間で元の向きに戻る
							OnFwd(OUT_A);
                                            		OnRev(OUT_C);
                                            		Wait(1);
							n++;
                                           }
                                           else if(n==18){ //0.1秒間後退
				           	PlaySound(SOUND_CLICK);			
						OnRev(OUT_A+OUT_C);
						Wait(10);
						n=0;
					     }
					    else{//nが4以上14以下のとき右に首振り
					    	OnFwd(OUT_C);
                                            	OnRev(OUT_A);
                                            	Wait(1);
						n++;
					    }
                                        }
                                    }                                                                                                         
                             }
                             else { //光センサ1、白/光センサ3、黒と判断した場合
                                     OnFwd(OUT_A); //進行方向左に回転
                                     Off(OUT_C);         
                                     until(SENSOR_3 > 40);
                                     i=0;
                               }
                           }
                       else { // 光センサ1が黒と判断
                              if(SENSOR_3 > 40){ //光センサ1、黒/光センサ3、白と判断した場合          
                                     Off(OUT_A); //進行方向右に回転
                                     OnFwd(OUT_C);      
                                     until(SENSOR_1 > 40);
                                     i=0; 
                                 }
                                 else{ // 光センサ1、3共に黒と判断した場合  
                                            OnFwd(OUT_A+OUT_C); //直進
                                            i=0;                                            
                              }                  
                        }
               }// 2 No Touch
      }//while
      stop music2;
      Off(OUT_A+OUT_C);
}

ソースコード処理内容

光センサーにより黒線にそって進む
衝突時をタッチセンサーにより判定し、三秒間停止した後、衝突前の処理を実行
交差点通過後にコースからはずれてしまった場合、左右近くにコースがないか確認し見つかった場合は再び黒線にそって進み、見つからなかった場合、0.1秒後退の後に再び近くの黒線を探す

二代目の考察

1、二台目はセンサーの幅をなくした。それを実現するためにソースは一代目の両方のセンサーが黒を認識した場合の処理と両方が白を認識した処理を逆にした。これにより非優先交差点の認識が可能になった。
2、二代目では非優先交差点を直進して渡った後に黒線が見つからなかった場合、左右旋回することでコースを探す処理をするようにプログラミングした。これにより衝突によるコースをはずれてしまった場合やコースを認識できなかった場合でもコースにもどることができるようになった。
3、横からロボットが衝突した場合にシングルバンパーでは対応できないのでダブルバンパに改良するべきである。

三代目

画像の説明 画像の説明 画像の説明

三代目の考察

1、二代目の反省を生かして、バブルバンパに改良。横からの接触に対しても対応が可能になった。
2、横からの接触の場合、接触した位置で指定されたプログラムを行うと、どの場合でももう一度接触してしまうため、後ろに下がってから指定されたプログラムを行うように改良した。
if(SENSOR_2 == 1){// タッチセンサが反応した場合
		       stop music2;
                     	  start music1;  
                         OnRev(OUT_A+OUT_C); //1秒後退
                         Wait(100);     
                         Off(OUT_A+OUT_C );3秒間停止
                         Wait(300);   
                         i=0;
                         stop music1;
                         start music2;                     
  } 

360度回点の場合も回転する前に後退するプログラムを入れました。

if(SENSOR_2 == 1){//タッチセンサが反応した場合
          stop music2;
          start music1; 
	OnRev(OUT_A+OUT_C);//一秒後退
	Wait(100);
	   repeat(2){//360度回転する命令
	     OnFwd(OUT_A);
	     OnRev(OUT_C);
	     Wait(140);
             stop music1;
             start music2;   
 }

今後の課題

交差点を渡るときに反対側に渡らずに優先コースに進んでしまうことがあるので改良が必要。
衝突時にバンパーが反応しないときがたまにあったので改良が必要。

感想

吉沢
横から衝突するのは、予想外だったので車体、プログラムの改良が大変だった。
タイヤの径が大きいと誤差が大きくなるので正確さを求めるか速さを求めるかで悩んだ。
北田
視覚のないロボットに明暗だけで道を認識させるのがこんなに難しいものだとは思ってなかった。正確さは情報量が多いほどよくなると思った。

備考

Windows VistaでのUSBのIRタワーの使用法

1,BrickxCCをダウンロード
2,LEGO社のwebページからUSB Tower patch(上から三番目のUSB Tower patchのところをクリックするとダウンロード画面が出る)をダウンロードする
3,ダウンロードしたファイルを解凍しSetup.exeを実行する
*検証は不十分ですがたぶんUSBタワーをパソコンにつけてからpatchをダウンロードしたほうがいいと思う。 Firmwareを最新のものにした前提で行う必要がある

コメント

よろしければコメントお願いします。 また、上記のvistaでの使用法についてのことも受け付けています

  • まず、光センサーがどのようにマシンにとりつけられていて、光センサーの値をもとに、どのようなトレースを行うかの解説がありません。 -- まいける(TA) 2007-12-14 (金) 08:30:16
  • 初めて見た人にもわかるように、そのバンパーの機構でどのように接触センサーを押しているかの説明がほしいです。 -- クノ? 2007-12-14 (金) 16:42:12


添付ファイル: filerobo1-5.jpg 302件 [詳細] fileDSCF0015.JPG 304件 [詳細] fileDSCF0012.JPG 297件 [詳細] fileDSCF0018.JPG 302件 [詳細] fileDSCF0017.JPG 306件 [詳細] filerobo4-2.jpg 303件 [詳細] fileDSCF0014.JPG 301件 [詳細] filerobo4-1.jpg 317件 [詳細] filerobo1-3.jpg 305件 [詳細] filerobo2-1.jpg 290件 [詳細] filerobo1-2.jpg 325件 [詳細] file1206_2.JPG 133件 [詳細] file1206_1.JPG 155件 [詳細] file300_0002.JPG 141件 [詳細] fileco.jpg 291件 [詳細] filecour..jpg 147件 [詳細] file2.jpg 301件 [詳細] filerobo6.jpg 298件 [詳細] filerobo5.jpg 300件 [詳細] filerobo4.jpg 299件 [詳細] filerobo3.jpg 131件 [詳細] filerobo2.jpg 153件 [詳細] filerobo1.jpg 147件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-01-02 (水) 01:11:16