目次
#contents
*課題2:黒線をトレースするロボット [#k2c26994]
**目的 [#k4f32cdd]
自ら作成したコースに自ら作成したロボットを走らせる
**コース作成上の条件 [#oade94a5]
-交差点2個以上作成する
-直角カーブを作る
-出口を4つ作る
-ヘアピンカーブ1個以上を作る
**ルール [#d6a21977]
4つある出口の一つから侵入しコースを1周半以上し出口から突破する
*ロボット紹介 [#ve268a24]
~ 全体図
#ref(20120619_143809 - c.jpg)
~ リア写真
#ref(20120619_144224 - c.jpg)
~ 今回のロボットはハンディカム並みの手のひらサイズとなっています。
~ 車輪の間隔を狭くするということよりもセンサーとタイヤの距離をできるだけ短くしてセンサーの感知とタイヤの挙動の誤差を少なくしました。
~ また、ロボット本体が安定するようにRCX部分と車体部分をがっちりと固定しました。
~ 車重が最もかかっていると思われる場所にタイヤを配置し、必要のない部品を極力減らして軽量化をしました。
~ 稼働部分
#ref(20120619_144050 - c.jpg)
ギアをいくつかつけることによってタイヤの回転速度を落としより正確なライントレースを実現しました。
~ センサーの取り付け部分
#ref(20120619_143828 c.jpg)
~ センサーを2つ取りつけ、上下からブロックではさみ、機動時にぶれないようにきっちりと固定しました。
*コース紹介 [#f39a1d49]
#ref(20120615_172735 - c.jpg)
~ 赤が直角カーブ、青がヘアピンカーブ、オレンジが交差点。
~ わりと難解なコースになってます。プログラムでの難関な箇所となるのは写真の輪で囲ってある部分に加え、出口がある場所でコースに行くか出口に行くかを選択させるところです。
*ライントレース [#c7d9f5fc]
**直線、交差点編 [#d2195a0f]
~ ライントレースの方法はいたって簡単です。
~ ロボットには2つセンサーがあるので図1のように黒い線をはさんでセンサーが両方とも白を認識した場合直進するようにプログラムする。
~ 図1
#ref(line1.jpg)
~ もしロボットが右に逸れてしまい左側のセンサーが黒、右側のセンサーが白を認識してしまった場合、図2のように左に修正するようにブログラムする。
~ また、もしロボットが左に逸れてしまい右側のセンサーが黒、左側のセンサーが白を認識してしまった場合、図3のように右に修正するようにプログラムする。
~ 図2
#ref(line2.jpg)
~ 図3
#ref(line3.jpg)
交差点ではセンサー2つとも黒線の上に来るのでセンサーが両方とも黒の場合、図4のよう直進するようにプログラムする。
~ 図4
#ref(line4.jpg)
**出入口編 [#n43046e1]
~ 出入口の部分では片方センサーは黒、もう片方のセンサーは白となってしまい、これでは上記の右または左に修正するプログラムと同じになってしまう。
~ そこでタイマーを利用して出入口の部分だけ違うプログラムとすることによって差別化をする。
~ 図5のように右側に出入口がある場合センサーが(左 右)=(白 黒),(白 白),(黒 黒)のとき直進させ、(左 右)=(黒 白)のときは左に修正するようにプログラムする。
~ また図6のように左側に出入口がある場合センサーが(左 右)=(黒 白),(白 白),(黒 黒)のとき直進させ、(左 右)=(白 黒)のときは右に修正するようにプログラムする。
~ 図5
#ref(line5.jpg)
~ 図6
#ref(line6.jpg)
**コースイン、コースアウト編 [#ea630ed0]
~ 出入口編を応用してコースイン、コースアウトのときもプログラムを別にしタイマーを使い差別化する。
~ コースインのときは図7のようになるので(左 右)=(黒 白),(白 白),(黒 黒)のとき直進させ、(左 右)=(白 黒)のときは右に修正するようにプログラムする。
~ コースアウトのときは図8のようになるのでコースインと同じく(左 右)=(黒 白),(白 白),(黒 黒)のとき直進させ、(左 右)=(白 黒)のときは右に修正するようにプログラムする。
~ 図7
#ref(line7.jpg)
~ 図8
#ref(line8.jpg)
*プログラム紹介 [#m80e28dd]
**コース攻略 [#cf761914]
#ref(20120615_172735 - cc.jpg)
~ 赤→青→黄→ピンク→緑→オレンジ→紫→黄緑→紺 の順番にコースを辿っていく。
~ それぞれの色をプログラム上では第� 銑�セクションに分けてタイマーを使いプログラムを分別。
**プログラム [#g1fc0443]
~ ※プログラムをする上でセンサーが黒を認識しているか白を認識しているかを視覚的に判断できるようにするためわざわざ2通りで同じ定義をした。
~ ちなみに白と認識するのは40以上で黒と認識するのは40以下。
~ パターン化されているものはサブルーチンで定義した。
#define BLACK 40 //※
#define WHITE 40 //※
#define RUN_SECTION1 100 //第1セクションの時間
#define RUN_SECTION2 445 //第2セクションの時間
#define RUN_SECTION3 470 //第3セクションの時間
#define RUN_SECTION4 210 //第4セクションの時間
#define RUN_SECTION5 240 //第5セクションの時間
#define RUN_SECTION6 620 //第6セクションの時間
#define RUN_SECTION7 200 //第7セクションの時間
#define RUN_SECTION8 360 //第8セクションの時間
#define RUN_SECTION9 150 //第9セクションの時間
sub line_1st() //直進:(左 右)=(黒 白),(黒 黒),(白 白) 右に旋回:(左 右)=(白 黒)
{
if ((SENSOR_1 < BLACK) && (SENSOR_3 > WHITE))
{
OnFwd(OUT_AC);
}
if ((SENSOR_1 > WHITE) && (SENSOR_3 < BLACK))
{
OnFwd(OUT_C);
OnRev(OUT_A);
}
if ((SENSOR_1 < BLACK) && (SENSOR_3 < BLACK))
{
OnFwd(OUT_AC);
}
if ((SENSOR_1 > WHITE) && (SENSOR_3 > WHITE))
{
OnFwd(OUT_AC);
}
}
sub line_2nd() //直進:(左 右)=(白 黒),(黒 黒),(白 白) 左に旋回:(左 右)=(黒 白)
{
if ((SENSOR_1 < BLACK) && (SENSOR_3 > WHITE))
{
OnFwd(OUT_A);
OnRev(OUT_C);
}
if ((SENSOR_1 > WHITE) && (SENSOR_3 < BLACK))
{
OnFwd(OUT_AC);
}
if ((SENSOR_1 < BLACK) && (SENSOR_3 < BLACK))
{
OnFwd(OUT_AC);
}
if ((SENSOR_1 > WHITE) && (SENSOR_3 > WHITE))
{
OnFwd(OUT_AC);
}
}
sub line_default() //直進:(左 右)=(黒 黒),(白 白) 左に旋回:(左 右)=(黒 白) 右に旋回:(左 右)=(白 黒)
{
if ((SENSOR_1 < BLACK) && (SENSOR_3 > WHITE))
{
OnFwd(OUT_A);
OnRev(OUT_C);
}
if ((SENSOR_1 > WHITE) && (SENSOR_3 < BLACK))
{
OnFwd(OUT_C);
OnRev(OUT_A);
}
if ((SENSOR_1 < BLACK) && (SENSOR_3 < BLACK))
{
OnFwd(OUT_AC);
}
if ((SENSOR_1 > WHITE) && (SENSOR_3 > WHITE))
{
OnFwd(OUT_AC);
}
}
task main ()
{
SetSensor(SENSOR_1, SENSOR_LIGHT); //
SetSensor(SENSOR_3, SENSOR_LIGHT); //
SetSensor(SENSOR_1, SENSOR_LIGHT); //端子1に接続されたセンサーが光センサーと定義
SetSensor(SENSOR_3, SENSOR_LIGHT); //端子3に接続されたセンサーが光センサーと定義
ClearTimer(0);
while ( Timer(0) <= RUN_SECTION1 ) //第1セクション開始
{
line_1st();
}
Off(OUT_AC);
PlaySound(SOUND_DOUBLE_BEEP); //音を鳴らす プログラムの切り替え時に音で変更を知らせる
ClearTimer(0);
while ( Timer(0) <= RUN_SECTION2 ) //第2セクション開始
{
line_default();
}
Off(OUT_AC);
PlaySound(SOUND_DOUBLE_BEEP); //プログラム変更音
ClearTimer(0);
while ( Timer(0) <= RUN_SECTION3 ) //第3セクション開始
{
line_2nd();
}
Off(OUT_AC);
PlaySound(SOUND_DOUBLE_BEEP); //プログラム変更音
ClearTimer(0);
while ( Timer(0) <= RUN_SECTION4 ) //第4セクション開始
{
line_default();
}
Off(OUT_AC);
PlaySound(SOUND_DOUBLE_BEEP); //プログラム変更音
ClearTimer(0);
while ( Timer(0) <= RUN_SECTION5 ) //第5セクション開始
{
line_1st();
}
Off(OUT_AC);
PlaySound(SOUND_DOUBLE_BEEP); //プログラム変更音
ClearTimer(0);
while ( Timer(0) <= RUN_SECTION6 ) //第6セクション開始
{
line_default();
}
Off(OUT_AC);
PlaySound(SOUND_DOUBLE_BEEP); //プログラム変更音
ClearTimer(0);
while ( Timer(0) <= RUN_SECTION7 ) //第7セクション開始
{
line_2nd();
}
Off(OUT_AC);
PlaySound(SOUND_DOUBLE_BEEP); //プログラム変更音
ClearTimer(0);
while ( Timer(0) <= RUN_SECTION8 ) //第8セクション開始
{
line_default();
}
Off(OUT_AC);
PlaySound(SOUND_DOUBLE_BEEP); //プログラム変更音
ClearTimer(0);
while ( Timer(0) <= RUN_SECTION9 ) //第9セクション開始
{
line_1st();
}
Off(OUT_AC);
PlaySound(SOUND_DOUBLE_BEEP); //プログラム変更音
OnFwd(OUT_AC); //出口脱出後少し直進
Wait(RUN_SECTION9);
Off(OUT_AC);
PlaySound(SOUND_CLICK); //終了音
}
*感想 [#k405afde]
~ 今回のロボットは似顔絵のときに失敗したり改善したほうがよいと思われた点を参考にして作ったロボットでした。発表会のときはまさかのトップバッターで見事にミスコースしました。(笑)トップバッターは失敗するという掟でもあるものなのか。。似顔絵の時もそうでしたがロボットに愛着が沸き、壊したくないという気持ちが強くなります。不思議ですね^^前回の課題のときと比べたら今回は上出来だったのではないのでしょうか。