はじめに

課題の説明

下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成せよ。

コース

黒線の幅は20mmでなるべく均等な濃さにすること。なお図の中の寸法の単位はcmで、黒線についてはその真ん中からの距離である。

2016a-mission2.png

ミッション

次のいずれかの経路を黒い線にそって動くロボットを作成する (他のメンバーとは別の経路になるようにする)。ただし、なるべく速く正確に動くロボットになるように工夫して、交差点では1秒間停止すること。

  • A地点からB地点へ (一人目)
    • A地点 → P直進 → Q直進 → Q直進 → R左折 → B地点
  • B地点からC地点へ (二人目)
    • B地点 → R右折 → Q直進 → Q直進 →P右折 → S右折 → C地点
  • C地点からA地点へ (三人目)
    • C地点 → S左折 → P左折 → Q直進 → Q直進 → R右折 → P左折 → A地点

自分のコース

自分はA地点からB地点(A地点 → P直進 → Q直進 → Q直進 → R左折 → B地点)へ行くコースを担当した。

ロボットの説明

DSC_0769.png


DSC_0771.png

サンプルのロボットに光センサーを取り付けた。
光センサーの取り付け方は説明書通りに行った。
ロボットの機体にはあまり工夫ができなかった。
光センサーの位置をもっと機体に近づけたりすればもっと結果が変わったかもしれない。

プログラムの説明

プログラム

以下が今回使用したプログラムの全体である。

#define BLACK 45
#define WHITE 54 
#define SPEED1 20
#define SPEED2 30
#define go_forward OnFwd(OUT_BC,SPEED2);
#define turn_left(t,w1,w2) OnFwd(OUT_B,w1); OnRev(OUT_C,w2); Wait(t);Off(OUT_BC);
#define turn_left1 OnFwd(OUT_B,SPEED1);Off(OUT_C);
#define turn_left2 OnFwd(OUT_B,SPEED1);OnRev(OUT_C,SPEED1);
#define turn_right(t,w1,w2) OnFwd(OUT_C,w1); OnRev(OUT_A,w2); Wait(t);Off(OUT_BC);
#define turn_right1 Off(OUT_B);OnFwd(OUT_C,SPEED1);
#define turn_right2 OnRev(OUT_B,SPEED1);OnFwd(OUT_C,SPEED1);
#define STEP 1
#define short_break Off(OUT_BC);Wait(1000);PlaySound(SOUND_UP);
#define cross_line go_forward;Wait(200);Off(OUT_BC);Wait(1000);
#define nMAX 330

void line_trace()
{
	SetSensorLight(S1);
	int nOnline=0;
	while (nOnline < nMAX ) {
	if (SENSOR_1 < BLACK-5) {
	turn_left2;
	nOnline++;
	} else {
	if (SENSOR_1 < BLACK) {
	turn_left1;
	} else if (SENSOR_1 < WHITE) {
	go_forward;
	} else if (SENSOR_1 < WHITE+5) {
	turn_right1;
	} else {
	turn_right2;
	}
	nOnline=0;
	}
	Wait(STEP);
	}
	short_break;
	nOnline=0;
	Off(OUT_BC);
}

void line_closs()
{
	cross_line;
	SetSensorLight(S1);
	do{
	if (SENSOR_1 < BLACK) {
	turn_right1;
	} else if (SENSOR_1 > WHITE) {
	turn_left2;
	}
	}
	while((SENSOR_1 > BLACK)&&(SENSOR_1 < WHITE));
	Off(OUT_BC);
}

void line_left()
{
	cross_line;
	turn_left(1000,20,20)
	SetSensorLight(S1);
	do{
	if (SENSOR_1 < BLACK) {
	turn_right1;
	} else if (SENSOR_1 > WHITE) {
	turn_left2;
	}
	}
	while((SENSOR_1 > BLACK)&&(SENSOR_1 < WHITE));
	Off(OUT_BC);
}

void last_move()
{
	go_forward;
	Wait(1500);
	Off(OUT_BC);
}

task main()
{
	line_trace();
	line_closs();
	line_trace();
	line_closs();
	line_trace();
	line_closs();
	line_trace();
	line_left();
	line_trace();
	last_move();
}

プログラムの詳細と工夫した点の説明

定義

#define BLACK 45 //黒色の定義
#define WHITE 54 //白色の定義
#define SPEED1 20
#define SPEED2 30
#define go_forward OnFwd(OUT_BC,SPEED2); //前進
#define turn_left(t,w1,w2) OnFwd(OUT_B,w1); OnRev(OUT_C,w2); Wait(t);Off(OUT_BC); //左に曲がる
#define turn_left1 OnFwd(OUT_B,SPEED1);Off(OUT_C); //左に曲がる
#define turn_left2 OnFwd(OUT_B,SPEED1);OnRev(OUT_C,SPEED1); //左に曲がる
#define turn_right(t,w1,w2) OnFwd(OUT_C,w1); OnRev(OUT_A,w2); Wait(t);Off(OUT_BC); //右に曲がる
#define turn_right1 Off(OUT_B);OnFwd(OUT_C,SPEED1); //右に曲がる
#define turn_right2 OnRev(OUT_B,SPEED1);OnFwd(OUT_C,SPEED1); //右に曲がる
#define STEP 1 //1回の判断で動作させる時間 
#define short_break Off(OUT_BC);Wait(1000);PlaySound(SOUND_UP); //1秒止まってブザーを鳴らす
#define cross_line go_forward;Wait(200);Off(OUT_BC);Wait(1000); //交差点を渡る
#define nMAX 330 //カーブとみなせる回数の最大値
  • 左または右に曲がる,鉢△砲弔い ,和腓く曲がり△肋さく曲がれる。

サブルーチン

void line_trace()
{
	SetSensorLight(S1);
	int nOnline=0;
	while (nOnline < nMAX ) { //黒がnMAX回続かない限り線の左端をトレースする
	if (SENSOR_1 < BLACK-5) {
	turn_left2;
	nOnline++; //カウンタを増やす
	} else {
	if (SENSOR_1 < BLACK) {
	turn_left1;
	} else if (SENSOR_1 < WHITE) {
	go_forward;
	} else if (SENSOR_1 < WHITE+5) {
	turn_right1;
	} else {
	turn_right2;
	}
	nOnline=0; //カウンタを0にする
	}
	Wait(STEP);
	}
	short_break;
	nOnline=0; //カウンタを0にする
	Off(OUT_BC);
}

線の左端をトレースするプログラム。
光センサーが黒をnMAX(330)回以上連続で判断すると交差点とみなし停止する。

void line_closs()
{
	cross_line;
	SetSensorLight(S1);
	do{ //線の左端を探す
	if (SENSOR_1 < BLACK) {
	turn_right1;
	} else if (SENSOR_1 > WHITE) {
	turn_left2;
	}
	}
	while((SENSOR_1 > BLACK)&&(SENSOR_1 < WHITE));
	Off(OUT_BC);
}

交差点を渡り切った後、次のライントレースのためにロボットの向きを調節するプログラム。

void line_left()
{
	cross_line;
	turn_left(1000,20,20); //左に曲がる
	SetSensorLight(S1);
	do{ //線の左端を探す
	if (SENSOR_1 < BLACK) {
	turn_right1;
	} else if (SENSOR_1 > WHITE) {
	turn_left2;
	}
	}
	while((SENSOR_1 > BLACK)&&(SENSOR_1 < WHITE));
	Off(OUT_BC);
}

void line_clossの左折バージョン。

void last_move()
{
	go_forward;
	Wait(1500);
       PlaySound(SOUND_UP);
	Off(OUT_BC);
}

最後にB地点の囲いに入り、ブザーを鳴らす。

メインタスク

task main()
{
	line_trace();
	line_closs();
	line_trace();
	line_closs();
	line_trace();
	line_closs();
	line_trace();
	line_left();
	line_trace();
	last_move();
}

サブルーチンを組み合わせてA地点からB地点へ行くプログラム。

結果

何とかゴールまでたどり着くことはできた。
A地点からB地点までにかかった時間は1分27秒ほどだった。

反省

反省点

もっと早くゴールできるようにしたかったが、速度を上げると交差点を認識しなくなったり、逆に急なカーブを交差点と認識してしまい、結果的にあまり早くはできなかかった。
また、先にも述べたがロボット自体にあまり手を加えられなかったので、もしかすると速度の問題も解決できたかもしれない。

感想

始めは前回の似顔絵の課題よりは難しくなさそうに感じたが、実際やってみると前回より格段にプログラムが複雑になっていてなかなかうまくいかなかった。例えば、速度を落としてライントレースを正確にすると交差点を認識せずそのまま曲がってしまったり、かといって速度を上げすぎてもカーブや交差点で問題が起きてしまった。結果的にはうまくいったが、もっと思い通りにプログラムを書けるようになりたいと思った。


添付ファイル: fileDSC_0769.png 72件 [詳細] fileDSC_0771.png 87件 [詳細] file2016a-mission2.png 88件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-07-08 (金) 00:03:50