2018a/Member

課題

ライントレースロボットの製作

幅2ミリの黒線をトレースするロボットを作る

以下のコースを進み,課題を達成させる(課題としてはAコース)

コース
1. Aをスタート
2. Bを直進
3. Cで一時停止の後、直進
4. Dで一時停止の後、Xの空き缶をキャッチしてD地点に戻る
5. DからEに向かい、Eを直進
6. Fを左折
7. Gで一時停止の後、左折
8. Hで一時停止の後、右折
9. Iで一時停止の後、右折
10. Lを直進
11. Kを直進
12. Jで一時停止の後、空き缶をYに置きてJに戻りBに向かう
13. Bで一時停止の後、左折
14. Aで停止
(一時停止の指定がある場所は、1秒間停止すること)

製作したロボット

小回りを利かせるために2輪ローバーにした.また,そのためのバランサーの先に光センサーを取り付けた.光センサーの高さは床から3mm程の位置になるよう調整した.缶をつかむ機構はクワガタのような型にした.開閉にはラックを前後させ,2本の角に支点を設けることで動かす機構を採用した.

全体像

全体像

車体下部

車体下部

上から見た車体

車体上

つかみ部のラック

つかみ部

つかみ部の動き方

作動前 作動後

製作したプログラム

A端子が左車輪,B端子がつかみ部の開閉,C端子が右車輪を制御する.また,2番端子に光センサーを接続している.

ライントレースプログラムの仕組み

光センサーは赤色光を照射し,その反射光を検知し,明るいほど高い数値を表す.ライントレースのプログラムはそれを利用して,黒い部分と白い部分の中間をたどるように閾値を設定し,それぞれの明るさに応じた行動をとらせる.また,機体の向きを修正する時間がある値以上(FastTimer(0)<=55/2)になったらそこを交差点と判断するようにする.(これは直線や曲線ではこの時間以内に次の動作に入りFastTimer(0)がリセットされるが,交差点ではこの時間以内に次の動作に入らず,FastTimer(0)がリセットされないからである.)今回は光センサーの値が45となるところを基準とし,+ー7以上で急旋回,+−5以上で曲がり,−5から+5の間で直進するように設定している.また,急旋回する向き・曲がる向きは,右側トレースの時は+5以上で左,−5以下で右に,左側トレースの時は+5以上で右,−5以上で左となる.

使用したマクロ

#define x 45 //閾値の設定
#define r 65 //90度の旋回時間(roll time)
#define g 35 //缶をつかみに・離しに行くまでの時間(go time)

サブルーチン・右側トレース

sub line2()
{
ClearTimer(0);
   while(FastTimer(0)<=55/2){ //交差点を判断する値
   if(SENSOR_2>x+7){ //光センサーの値が閾値+7以上だったら左に急旋回
       OnRev(OUT_A);
       OnFwd(OUT_C);
       ClearTimer(0);
   }else if(SENSOR_2>=x+5){ //光センサーの値が閾値+5以上だったら左に曲がる
       Off(OUT_A);
       OnFwd(OUT_C);
       ClearTimer(0);
   }else if(SENSOR_2>x){ //光センサーの値が閾値より大きかったら直進
       OnFwd(OUT_AC);
       ClearTimer(0);
   }else if(SENSOR_2>=x-5){ //光センサーの値が閾値-5以上だったら右に曲がる
       Off(OUT_C);
       OnFwd(OUT_A);
       ClearTimer(0);
   }else{         //それ以外だったら右に急旋回
       OnRev(OUT_C);
       OnFwd(OUT_A);
	 }
    }
   Off(OUT_AC);      //交差点が来たらとまれ
   PlaySound(SOUND_DOUBLE_BEEP); //停止と同時に音を出せ
}

サブルーチン・左側トレース(基本)

sub line()
{
ClearTimer(0);
   while(FastTimer(0)<=55/2){ //交差点を判断する値
   if(SENSOR_2>x+7){ //光センサーの値が閾値+7以上だったら右に急旋回
       OnRev(OUT_C);
       OnFwd(OUT_A);
       ClearTimer(0);
   }else if(SENSOR_2>=x+5){ //光センサーの値が閾値+5以上だったら右に曲がる
       Off(OUT_C);
       OnFwd(OUT_A);
       ClearTimer(0);
   }else if(SENSOR_2>x){ //光センサーの値が閾値より大きかったら直進
       OnFwd(OUT_AC);
       ClearTimer(0);
   }else if(SENSOR_2>=x-5){ //光センサーの値が閾値-5以上だったら左に曲がる
       Off(OUT_A);
       OnFwd(OUT_C);
       ClearTimer(0);
   }else{         //それ以外だったら右に急旋回
       OnRev(OUT_A);
       OnFwd(OUT_C);
	 }
    }
   Off(OUT_AC);      //交差点が来たらとまれ
   PlaySound(SOUND_DOUBLE_BEEP); //停止と同時に音を出せ
}

サブルーチン・離すプログラム

sub release()
{
       OnFwd(OUT_C); //左に曲がる
       OnRev(OUT_A);
       Wait(r);
       Off(OUT_AC);
       OnFwd(OUT_AC); //前進
       Wait(g);
       Off(OUT_AC);
       OnRev(OUT_B); //腕を開く
       Wait(10);
       Off(OUT_B);
       OnRev(OUT_AC); //後退
       Wait(g);
       Off(OUT_AC);
       OnRev(OUT_C);180度旋回
       OnFwd(OUT_A);
       Wait(r*2);`
       Off(OUT_AC);
}

サブルーチン・掴むプログラム

sub cat()
{
       OnFwd(OUT_AC); //前進
       Wait(g);
       Off(OUT_AC);
       OnFwd(OUT_B); //腕を閉じる
       Wait(10);
       Off(OUT_B);
       OnRev(OUT_AC); //後退
       Wait(g);
       Off(OUT_AC);
}

メインプログラム

task main()
{
       SetSensor(SENSOR_2,SENSOR_LIGHT); //光センサーを定義
       OnFwd(OUT_AC); //最初の黒線を乗り越える
       Wait(30);
       Off(OUT_AC);
       line();
       line();
       Wait(100);  //until C
       OnFwd(OUT_AC); //Cの黒線を乗り越える
       Wait(70);
       Off(OUT_AC);
       line();
       Wait(100);  //until D
       cat(); //缶をつかむ
       Wait(100);  //Dで停止
       OnFwd(OUT_C);  //D turn
       OnRev(OUT_A);
       Wait(r);
       Off(OUT_AC);
       Wait(100);
       line();  //until E
       line();  //until G
       OnFwd(OUT_C);  //Gで曲がる
       OnRev(OUT_A);
       Wait(r);
       Off(OUT_AC);
       Wait(100);
       line();
       line();
       Wait(100);  //until H
       OnFwd(OUT_C);  //Hで曲がる
       Off(OUT_C);
       Wait(r);
       Off(OUT_AC);
       line();
       Wait(100);  //until I
       OnFwd(OUT_A);  //Iで曲がる
       Off(OUT_C);
       Wait(r/2);
       Off(OUT_AC);
       line2(); //ここから右トレース
       Wait(100); //until L
       line2();
       Wait(100);  //until K
       line2();
       Wait(100);  //until J
       release(); //缶を離す
       line();  //ここから左トレース
       Wait(100);  //until B
       OnFwd(OUT_C);
       OnRev(OUT_A);
       Wait(r);
       Off(OUT_AC); //Bで曲がる
       line(); //until A
       OnFwd(OUT_AC); /枠内へ
       Wait(300);
       Off(OUT_AC); //停止
}

まとめ

車体について

センサーやタイヤの劣化による誤差によって1回1回の結果が変わってしまった.また,つかむ機構が走行中にゆるんでしまい,缶が途中でこぼれてしまうことがあった.劣化のほうはどうにもならないが,ゆるんでしまうのはモーター側のトルクを大きくすることで改善できると思う.次に,缶をつかみに行く際に,最初はタッチセンサーを使用しようと考えていたが,缶が軽すぎて反応しなかった.そのため,タッチセンサーを反応しやすくする必要があるが,その場合車体の振動で反応してしまうことが考えられる.そのため,タッチセンサー以外の使用が望ましい.しかしそれ以外の面ではおおむね良好であったと思う.

プログラムについて

ライントレースのサブルーチンを右側トレース・左側トレースの二つを作ることにより,場所に応じて好ましいほうを選択できるようになり,片側だけでは突破の難しかったところを突破できた.この時の閾値の調整に手間取った.しかし直線の途中で止まってしまうことがあったが,同じプログラムを重ねることで解決した.そのほかには特に問題はなく,しっかりと動いてくれたので良かった.


添付ファイル: fileアーム2.png 183件 [詳細] fileアーム1.png 317件 [詳細] file車体上.jpg 349件 [詳細] file車体下.jpg 219件 [詳細] fileつかみ部.jpg 169件 [詳細] file全体像.jpg 165件 [詳細] fileコース.png 164件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-08-13 (月) 19:33:03