[[2018b/Member]]
#contents
*課題2 [#g0917994]
課題2のコース
&ref(http://yakushi.shinshu-u.ac.jp/robotics/?plugin=attach&pcmd=open&file=2018b-mission2.png&refer=2018b%2FMember%2Fyuto%2FMission2);

このコースで、次のルートを通る
    ロボットを正方形X内におき、Lをスタート
    Eを一時停止して直進
    Iを一時停止して左折
    Hを直進
    Kを直進
    Jを左折
    Cを一時停止して右折
    Eを一時停止して直進
    Gを一時停止して直進
    長方形X内に入って停止
*ロボットの概要 [#w0a4fd15]
&ref(S__232890381.jpg);

今回はこちらのロボットを作った。
**光センサー [#s3815857]
&ref(S__232890383.jpg);

光センサーを使って線の濃さを見分ける。
地面に近づきすぎると全てを黒と判断してしまい、逆に話しすぎると色の濃さを見分けづらいため、ちょうどよい場所を探すのに苦労した。
**超音波センサー [#x0c1b05e]
&ref(S__232890382.jpg);

超音波センサーを使って缶との距離を測る
今回は高い位置に設置したが、高すぎると反応しなくなってしまうためここでも少し苦労した。
**ボールを当てる機能 [#gda2ca74]
&ref(S__232890384.jpg);

ボールは転がして落とすことで当てるようにした。
図のモータが回ることで、横の支えが回転してボールが滑り落ちていくという仕組みだ。
*プログラミング [#t9db7ee0]
**ライントレースのプログラムの説明 [#o5b8de29]
今回使ったプログラムはこれである。
 #define middle 48
 sub Line()
 {
 SetSensorLight(S1);
 long t0=CurrentTick();
 while(CurrentTick()-t0<=28) 
	{
	if(SENSOR_1>middle+8)//光センサーの値が56より大きければ
		{
		migi0;//右旋回
		t0=CurrentTick();
		}
	else if(SENSOR_1>middle+4)//52より大きければ
		{
		migi1;右へ曲がる
		t0=CurrentTick();
		}
	else if(SENSOR_1>middle)//48より大きければ
		{
		OnFwd(OUT_AC,30);//直進
		t0=CurrentTick();
                }
	else if(SENSOR_1>middle-4)//44より大きければ
		{
		hidari0;//左へ曲がる
		t0=CurrentTick();
		}
	else
		{
		hidari1;//左旋回
              t0=CurrentTick();
		}}
 Off(OUT_AC); 
 }
このプログラミングは、ラインの左側を通っていくプログラミングである。説明でも書いてあるが、明るければ明るいほど右に、暗ければ暗いほど左に進むようにプログラミングされている。これによって、道を挟むように機械が進んでいくことができる。また、速度が速すぎると光センサがうまく反応してくれないので、なるべくゆっくり進ませることにした。また子のプログラミングは交差点の判断もできる。同じ行動を28以上する、つまり曲がり続けると、機械が止まるようになっている。これによって交差点の判断をする。しかしこのコースには急カーブが存在する。そこで重要となってくるのがこの後登場する2つ目のラインとレースのプログラムである。ほとんど同じなのでここでは記述しないが、スタートしてから一定時間は止まらないようになっている。これによって、急カーブも進めるようにした。
** [#t8b38046]
**全体のプログラム [#t80a6ea2]
ロボットを動かすためのプログラミングを作る。まずおおもとの定義を
 #define migi0 OnFwd(OUT_A,15);OnRev(OUT_C,10);//右旋回 
 #define migi1 OnFwd(OUT_A,15);Off(OUT_C);//右曲がり 
 #define hidari0 OnFwd(OUT_C,15);OnRev(OUT_A,10);//左曲がり 
 #define hidari1 OnFwd(OUT_C,15);Off(OUT_A);//左旋回 
 #define middle 48//光の値の中心 
 #define go(time) OnFwd(OUT_AC,15);Wait(time);Off(OUT_AC);//前に進む 
 #define back(time) OnRev(OUT_AC,15);Wait(time);Off(OUT_AC);//後ろに進む 
 #define LEFT(angle) OnFwd(OUT_C,15);OnRev(OUT_A,10);Wait(angle);Off(OUT_AC);//左に曲がる 
 #define RIGHT(angle) OnFwd(OUT_A,15);OnRev(OUT_C,10);Wait(angle);Off(OUT_AC);//右に曲がる
まず、通常のラインを進んでいくプログラミングは 
 sub Line()
 {
 SetSensorLight(S1);
 long t0=CurrentTick();
 while(CurrentTick()-t0<=28) 
	{
	if(SENSOR_1>middle+8)//光センサーの値が56より大きければ
		{
		migi0;//右旋回
		t0=CurrentTick();
		}
	else if(SENSOR_1>middle+4)//52より大きければ
		{
		migi1;右へ曲がる
		t0=CurrentTick();
		}
	else if(SENSOR_1>middle)//48より大きければ
		{
		OnFwd(OUT_AC,30);//直進
		t0=CurrentTick();
                }
	else if(SENSOR_1>middle-4)//44より大きければ
		{
		hidari0;//左へ曲がる
		t0=CurrentTick();
		}
	else
		{
		hidari1;//左旋回
              t0=CurrentTick();
		}
	}
 Off(OUT_AC); 
 }
なお、全てにおいてCurrentTick();が入っているのは、そこでタイムをリセットするためである
つぎに、1つだけある急カーブのために、ある一定時間は曲がらないプログラムを作る。
 sub Line2() 
 {
 SetSensorLight(S1);
 long t0=CurrentTick();
 while(CurrentTick()-t0<=2500)
	{
	if(SENSOR_1>middle+8)
		{
		migi0;
		}
	else if(SENSOR_1>middle+4)
		{
		migi1;
		}
	else if(SENSOR_1>middle)
		{
		OnFwd(OUT_AC,30); 
		}
	else if(SENSOR_1>middle-4)
		{
		hidari0;
                }
	else
		{
		hidari1;
		}
	}
 Off(OUT_AC);
 }
次は、空き缶を見つけるためのプログラムである
 void mitsukeru()
 {
   ResetTachoCount(OUT_ABC);
   OnFwd(OUT_A,50);
   OnRev(OUT_C,50);
   SetSensorLowspeed(S4);            
   int d1;
   d1=1000;//仮の最小値  
   long t0=CurrentTick();
   long t1=CurrentTick();
   long t2=CurrentTick();
   while(t2-t0<=3570){
       t2=CurrentTick();
       if(SensorUS(S4)<d1){
           d1=SensorUS(S4);//最小値より小さい値が出た時、そこを新しい最小値とする
           t1=CurrentTick();//時間をリセットする
       }
       t2=CurrentTick();
   }
   t0=CurrentTick();
   Off(OUT_AC);
   OnFwd(OUT_C,50);
   OnRev(OUT_A,50);
   Wait(t0-t1);//最後に、最小値をとった場所まで回る
 }
これらをすべて合わせたプログラミングがこちらである
 task main()
 {
 Line();//AからB
 RIGHT(15);//Bを右折
 Line();//BからK
 Wait(1000);//一時停止
 LEFT(15);//Kを左折
 Line();//KからJ
 go(50);//微調節
 Line();//KからJ
 go(100);//微調節
 mitsukeru();//缶を探す
 OnFwd(OUT_B,30);//缶を落とす
 Wait(2000);
 Off(OUT_B);
 Line();//JからI
 go(50)//微調節
 Line();//IからH
 LEFT(15);//左に曲がる
 Line();//HからG
 Wait(1000);//一時停止
 LEFT(15);//Gで左折
 Line2();//ある場所まで進み続ける
 Line();//そこからEmまで
 Wait(1000);//一時停止
 RIGHT(15);//Eを曲がる
 Line();//Lまで行く
 go(100);//ゴールに入る
 Off(OUT_BC);// 
 }
*感想と考察 [#d01d7853]
・道を走るだけでこんなにも難しいものだと知った
・自動運転の技術は本当にすごいんだなと思った
・前回の反省を生かし、しっかりと短めで終わらせた
・次回はもっと工夫したプログラミングを作りたい

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