- 追加された行はこの色です。
- 削除された行はこの色です。
[[2018a/Member]]
目次
#contents
*課題2の概要 [#xfd5ba78]
**課題の内容 [#g6fca52f]
課題2では,あらかじめ決められたコースの線に沿って進むロボットを作ることである.
**コース説明 [#pee02b78]
#ref(2018a-mission2.png);
自分は第2コースを担当し,コースの道順は次のように与えられた.
1.Aをスタート
2.Bを右折
3.Jで一時停止の後、Yの空き缶をキャッチしてJに戻る
4.JからKに向かい、Kを直進
5.Lを直進
6.Iを左折
7.Hで一時停止の後、左折
8.Gで一時停止の後、右折
9.Fで一時停止の後、右折
10.Eを直進
11.Dで一時停止の後、空き缶をXに置いてDに戻り、Cに向かう
12.Cで一時停止の後、直進
13.Bを直進
14.Aで停止
ただし,一時停止の箇所では一秒間停止する
*ロボットの説明 [#j3a8150d]
**センサーの取り付け位置について [#z7f80b06]
センサーは,より地面と平行に設置,また,地面とすれすれに設置することで,線の認識をよりしやすくなるように心がけた.
#ref(IMG_0822.JPG);
**アームの機構について [#xa261ab6]
アームは,上から缶に向かって振り下ろす形にした.上から振り下ろすことでプログラミングを単調にすることができた.しかし,アームが重くなってしまい,ロボット自体のバランスが悪くなってしまい,あまり安定しなかった.
#ref(IMG_0826.JPG);
*ロボットのプログラミング(動作) [#h87e50fd]
**ライントレースについて [#b51605e0]
ライントレースのプログラミングをするのにあたり,レースの紙上の「白」「白と線の境界付近」「境界」「黒と線の境界付近」「黒」の5段階のパートに分けた.以下の図は5段階の色を測定した結果の値である.
5段階に分けることによって,下の図のようにそれぞれの段階に合わせた動作を実行させることにした.
***主に使用するプログラミング [#q0566dbe]
#define Qian1 OnFwd(OUT_B,40);OnFwd(OUT_C,-30); //1の方向に進む
#define Qian2 OnFwd(OUT_B,30);OnFwd(OUT_C,-20); //2の方向に進む
#define Qina3 OnFwd(OUT_B,40);OnFwd(OUT_C,40); //3の方向に進む
#define Qian4 OnFwd(OUT_B,-20);OnFwd(OUT_C,30); //4の方向に進む
#define Qian5 OnFwd(OUT_B,-30);OnFwd(OUT_C,40); //5の方向に進む
ここで,「Qian」とは,「前」という意味として表した.
***左側のライントレース [#sc6cb0be]
5段階に分けた進み方を利用したサブルーチンを設け,次のようにライントレースをするようにプログラミングをした.
sub LINEleft()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<130)
{
if(SENSOR_1<33) //「白」を認識したとき,Qian1方向に進む
{
Qian1;
Shijian++;
}
else if(SENSOR_1<38) //「白と線の境界付近」を認識したとき,Qian2方向に進む
{
Qian2;
Shijian = 0;
}
else if(SENSOR_1<46) //「境界」を認識したとき,Qian3方向に進む
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53) //「黒と線の境界付近」を認識したとき,Qian4方向に進む
{
Qian4;
Shijian = 0;
}
else //「黒」を認識したとき,Qian5方向に進む
{
Qian5;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
}
ここで,「Shijian」とは,「時間」という意味として表した.
***右側のライントレース [#xc77eb96]
左側のライントレースと同様の考えで,右側のライントレースも5段階の進み方を利用し,サブルーチンを設ける.
sub LINEright()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<130)
{
if(SENSOR_1<33)
{
Qian5;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian4;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian2;
Shijian = 0;
}
else
{
Qian1;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
}
このプログラミングから,左側と右側のライントレースではプログラミングが互いに逆転しているということがわかる.
**交差点の認識について [#i4ab219d]
交差点の認識方法としては,ライントレース中に,指定した動作を連続で指定した秒数以上繰り返した場合,強制的にライントレースを終了させるという形にした.左側のライントレース中の場合,Qian1が,右側のライントレース中の場合Qian5が指定した秒数以上繰り返した場合,交差点を認識するようにした.
***左側のライントレースの場合の交差点認識 [#oe4d89c6]
sub LINEleft()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<130) //センサーが33以下の値を連続0,13秒以上読み取ればwhileは実行されない
{
if(SENSOR_1<33)
{
Qian1;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian2;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian4;
Shijian = 0;
}
else
{
Qian5;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
Shijian = 0;
}
***右側のライントレースの場合の交差点認識 [#t07dc11c]
sub LINEright()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<130)
{
if(SENSOR_1<33)
{
Qian5;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian4;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian2;
Shijian = 0;
}
else
{
Qian1;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
Shijian = 0;
}
*ロボットのプログラミング(全体) [#ude6bcb1]
**プログラミングの進め方 [#yfed0a04]
コースを進むのにあたり,以下のようにサブルーチンをわけ,交差点の認識や,缶をつかんだり離したりする動作を対処対処に細かく分けた.
1.AB
2.BJ
3.Ycatch(J地点でYにある空き缶をつかむ)
4.JK
5.KL
6.LI
7.IH
8.HG
9.GF
10.FE
11.ED
12.Xrelease(D地点でXに空き缶を置く)
13.DC
14.CB
15.BA
***AB間のプログラミング [#re515a00]
スタートし,AB間は右側のライントレースを実行すれば交差点を認識する必要なしにB地点を右折することができる.よって,AB間はサブルーチンとして作成した【LINEright】を利用する
***BJ間のプログラミング [#n6d989f2]
BJ間は,前と同じく右側をライントレースし,J地点で一時停止する.よって,次のようなプログラミングになる.
sub BJ()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<130)
{
if(SENSOR_1<33)
{
Qian5;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian4;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian2;
Shijian = 0;
}
else
{
Qian1;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
Wait(1000); //交差点を認識したとき一秒間止まる
}
***Ycatch(J地点でYにある空き缶をつかむ)動作のプログラミング [#l92d307f]
J地点で一時停止後,少し前に動き,その後空き缶をキャッチしてから再びライン上に戻る.
sub Ycatch()
{
OnFwd(OUT_BC,30); //少し前に進む
Wait(600);
Off(OUT_BC);
OnFwd(OUT_A,30); //アームを下す
Wait(800);
Off(OUT_A);
OnRev(OUT,BC,30); //元の線上に戻る
Wait(600);
Off(OUT_BC);
***JK間のプログラミング [#kbda1faf]
JK間では左側をライントレースし,K地点の交差点を認識し,直進する.
sub JK()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<130)
{
if(SENSOR_1<33)
{
Qian1;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian2;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian4;
Shijian = 0;
}
else
{
Qian5;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
Shijian = 0;
Qian3;
Wait(270);
Off(OUT,BC);
}
***KL間のプログラミング [#lfb7b567]
KL間は,左側をライントレースし,L地点の交差点を認識した後直進すればよいので,JK間と全く同じ動きをする.よって,この間のプログラミングはJK間のサブルーチンと同じとする.
***LI間のプログラミング [#ae30ca84]
LI間では線の左側をライントレースし,I地点で左折すればよい.
sub LI()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<130)
{
if(SENSOR_1<33)
{
Qian1;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian2;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian4;
Shijian = 0;
}
else
{
Qian5;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
Shijian = 0;
Qian1;
Wait(400);
Off(OUT_BC);
}
この後,再び線の左側をライントレースするので,【LINEleft】のサブルーチンを利用する.
***IH間のプログラミング [#i7ea1383]
IH間は,線の左側のライントレースをし,H地点で一時停止後,左折するようにする.よって,基本動作として,【LINEleft】のプログラミングを利用すればよい.
sub IH()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<130)
{
if(SENSOR_1<33)
{
Qian1;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian2;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian4;
Shijian = 0;
}
else
{
Qian5;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
Shijian = 0;
Qian1;
Wait(1000);
}
この後,再び【LINEleft】のサブルーチンを利用して左折する.
***HG間のプログラミング [#y05f8b59]
HG間は急カーブがあり,センサーが黒色の部分を認識する時間が長く交差点として扱ってしまうことがある.このような事を回避するために,交差点を認識するように指定していた時間を長くすることで,このような誤りを回避した.
sub HG()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<500)
{
if(SENSOR_1<33)
{
Qian1;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian2;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian4;
Shijian = 0;
}
else
{
Qian5;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
Shijian = 0;
}
***GF間のプログラミング [#f882bb80]
GF間では,左側をライントレースし,F地点で一時停止後,左折すればよい.
sub GF()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<130)
{
if(SENSOR_1<33)
{
Qian1;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian2;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian4;
Shijian = 0;
}
else
{
Qian5;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
Shijian = 0;
Qian1;
Wait(1000);
}
この後,再び【LINEleft】のサブルーチンを利用して左折する.
***FE間のプログラミング [#j17318c6]
FE間では,線の左側のライントレースをするので,交差点を認識する必要がなく,ただ,ライントレースを実行すればよい.よって,【LINEleft】のサブルーチンを利用する.
***ED間のプログラミング [#i3766604]
ED間も,FE間と同じく線の左側をライントレースし,次のD地点で空き缶を離すという動作につなげることができたらよい.よって,ここでも【LINEleft】のサブルーチンを利用する.
***Xrelease(D地点でXに空き缶を置く)動作のプログラミング [#tc82aeac]
D地点で一時停止後,機体を円の中心に向けた後,少し前に動き,空き缶を置いてから再びライン上に戻る.
sub Xrelease()
{
OnFwd(OUT_C,50); //90度回転する
OnFwd(OUT_B,-50);
Wait(500);
Off(OUT_BC);
OnFwd(OUT_BC,30); //少し前に進む
Wait(600);
Off(OUT_BC);
OnRev(OUT_A,30); //アームを上げる
Wait(800);
Off(OUT_A);
OnRev(OUT,BC,30); //元の線上に戻る
Wait(600);
Off(OUT_BC);
***DC間のプログラミング [#y7b3c6c5]
DC間では線の右側をライントレースし,C地点で一時停止する.一度垂直な曲がり角があり,また,急なカーブの箇所があるので,次のようにプログラミングをした.
sub DC()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<130)
{
if(SENSOR_1<33)
{
Qian5;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian4;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian2;
Shijian = 0;
}
else
{
Qian1;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
Shijian = 0;
Qian5;
Wait(400);
Off(OUT_BC);
while(Shijian<300)
{
if(SENSOR_1<33)
{
Qian5;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian4;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian2;
Shijian = 0;
}
else
{
Qian1;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
Shijian = 0;
Qian1;
Wait(1000);
Qian3;
Wait(400);
Off(OUT_BC);
}
***CB間のプログラミング [#g84cc3b6]
CB間では右側のライントレースをし,B地点では直進をする.
sub CB()
{
SetSensorLight(S1);
int Shijian = 0;
while(Shijian<130)
{
if(SENSOR_1<33)
{
Qian5;
Shijian++;
}
else if(SENSOR_1<38)
{
Qian4;
Shijian = 0;
}
else if(SENSOR_1<46)
{
Qian3;
Shijian = 0;
}
else if(SENSOR_1<53)
{
Qian2;
Shijian = 0;
}
else
{
Qian1;
Shijian = 0;
}
Wait(STEP);
}
Off(OUT_BC);
Qian1; //傾きを戻す
Wait(100);
Qian3; //交差点部分を渡る
Wait(150);
Off(OUT_BC);
shijian = 0;
}
***BA間のプログラミング [#j3747998]
BA間はひたすらCB間に続き,右側のライントレースをすればよいので,初めにサブルーチンとして設けた【LINEright】を利用すればよい.
**完成したプログラミング [#b0bb5984]
task main()
{
LINEright(); //AB間
BJ();
Ycatch();
JK();
JK(); //KL間
LI();
IH();
HG();
GF();
LINEleft(); //FE間
LINEleft(); //ED間
Xrelease();
DC();
CB();
LINEright(); //BA間
}
*まとめ [#qac38568]
**問題点・課題 [#e2048179]
まずロボットの問題点としては,組み立てる際に隙間の多い構造をとってしまい,つなぎ目が重さによりすぐ取れたりと,コース上を長い時間は知る必要があるのにも関わらず,非常にバランスの悪いものとなってしまった.また,アームによる重さが原因でタイヤの向きによっては大きく傾いてしまったりと,こちらもよいバランスを保てたとは言えなかった.改善策としては,ロボットを作る際に工夫してできる限りパーツ間の隙間を小さくする,アームを両サイドから挟むような固いにすることでアームを持ち上げの負担を軽くし,バランスを保てるようにするなどが挙げらた.
次に,プログラミングの問題点は,コースに沿って一つ一つサブルーチンを作成したので時間がかかってしまったということだ.一つのサブルーチンとしてのプログラミングを,コースの様々な箇所で多用することで時間短縮,また,考えたプログラミングの有効活用にも繋がったのではないかと思う.
**感想 [#weae42c0]
今回の,課題2では新しくサブルーチンというものを活用した.問題点・課題にも書いたように,今回はあまり有効活用ができていなかったので最終課題では有効活用していきたい.