[[2019a/Member]]
*課題2 [#a5b9a302]
下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成せよ。
http://yakushi.shinshu-u.ac.jp/robotics/?plugin=attach&refer=2019a%2FMission2&openfile=2019a-mission2.png
A地点から出発 → M → K(直進) → L(ピンポン玉をつかむ) → K(右折) → J(一時停止の後、左折) → I(直進) → H(直進) → G(左折) → F → E → D(一時停止の後、直進) → C(直進) → B(一時停止) → シュート→ A地点に入る(ゴール)
私は上記のコースでロボットを動かしながら,ピンポン玉を回収し、それをゴールまで運びました。
*ロボットの構造 [#ae476dc8]
ロボットを作る上でこ気を付けたことは小回りが利くという点です.
ロボットが大きくなりすぎて光センサーとタイヤの距離が離れすぎてしまったら軸がぶれてしまいプログラムが想定していたように動かなってしまいます.
また,私たちはピンポン玉を運ぶための方法としてアームを取り入れました.
アームを上げ下げすることでピンポン玉を移動させるのに成功しました.
全体像は以下の写真の通りです.
&ref(2019a/Member/Asahi/Mission2/IMG_1785.jpg,50%,�ゝ々�);
*プログラムの説明 [#c41805fa]
**定義したプログラム [#rba811eb]
何回も同じプログラムを書くことは無駄であるため定義しました.
#define black 30
#define white 50
#define speedH 30
#define speedL 10
#define mae OnFwd(OUT_BC,speedH);//直進
#define turnRRR OnFwd(OUT_C,speedH);OnRev(OUT_B,speedH);//微々右旋回
#define turnLLL OnFwd(OUT_B,speedH);OnRev(OUT_C,speedH);//微々左旋回
#define turnRR OnFwd(OUT_C,speedH);Off(OUT_B);//微右旋回
#define turnLL OnFwd(OUT_B,speedH);Off(OUT_C);//微左旋回
#define turnR OnFwd(OUT_C,speedH);OnFwd(OUT_B,speedL);//右旋回
#define turnL OnFwd(OUT_B,speedH);OnFwd(OUT_C,speedL);//左旋回
#define step 1
#define jikan 100
#define teishi Off(OUT_BC);Wait(300)
**サブルーチン [#s20991b8]
ライントレースや交差点で止まった後に直進するためのプログラムなどは上のように定義できないためサブルーチンとして定義しました.
***ライントレース [#q5d05bf3]
ライントレースは4つ用意しました.それは直進するときの左側のライントレース,直進するときの右側のライントレース,カーブを渡る時の左側のライントレース,カーブを渡る時の右側のライントレースです.またこららは全て交差点で止まるように設定しています.
それを以下に載せます.
交差点で止まり,直進するときの左側のライントレース
光センサーが指定した時間以上,黒と測定したら止まるようにプログラムされている.
これが交差点で止まるで止まるためのプログラムである.
void linetraceSL()//交差点で止まる
{
long t0=0,t_black=0,t_max=jikan;
t0=CurrentTick();//t0は現在の時間
while(t_black<t_max){//t_blackがt_maxを超えるまで続ける
if(SENSOR_3>white){//もし光センサーで白がが測定されると
turnRR;
} else if(SENSOR_3>white-5){//もし光センサーで白-5が測定されると
turnR;
} else if(SENSOR_3>black+5){//もし光センサーで黒+5が測定されると
mae;
} else if(SENSOR_3>black){//もし光センサーで黒が測定されると
turnL;
} else{
turnLL;
t0=CurrentTick();//t0は現在の時間
until((SENSOR_3<black+5)&&(SENSOR_3>black));//黒+5か黒になるまで
t_black=CurrentTick()-t0;
}
Wait(step);
}
}
交差点で止まり,直進するときの右側のライントレース
void linetraceSR()//交差点で止まる
{
long t0=0,t_black=0,t_max=jikan;
t0=CurrentTick();//t0は現在の時間
while(t_black<t_max){//t_blackがt_maxを超えるまで続ける
if(SENSOR_3>white){//もし光センサーで白がが測定されると
turnLL;
} else if(SENSOR_3>white-5){//もし光センサーで白-5が測定されると
turnL;
} else if(SENSOR_3>black+5){//もし光センサーで黒+5が測定されると
mae;
} else if(SENSOR_3>black){//もし光センサーで黒が測定されると
turnR;
} else{
turnRR;
t0=CurrentTick();//t0は現在の時間
until((SENSOR_3<black+5)&&(SENSOR_3>black));//黒+5か黒になるまで
t_black=CurrentTick()-t0;
}
Wait(step);
}
}
交差点で止まり,カーブを渡る時の左側のライントレース
void linetraceCL()//交差点で止まる
{
long t0=0,t_black=0,t_max=jikan;
t0=CurrentTick();//t0は現在の時間
while(t_black<t_max){//t_blackがt_maxを超えるまで続ける
if(SENSOR_3>white){//もし光センサーで白がが測定されると
turnRRR;
} else if(SENSOR_3>white-5){//もし光センサーで白-5が測定されると
turnRR;
} else if(SENSOR_3>black+5){//もし光センサーで黒+5が測定されると
mae;
} else if(SENSOR_3>black){//もし光センサーで黒が測定されると
turnLL;
} else{
turnLLL;
t0=CurrentTick();//t0は現在の時間
until((SENSOR_3<black+5)&&(SENSOR_3>black));//黒+5か黒になるまで
t_black=CurrentTick()-t0;
}
Wait(step);
}
}
交差点で止まり,カーブを渡る時の右側のライントレース
void linetraceCR()//交差点で止まる
{
long t0=0,t_black=0,t_max=jikan;
t0=CurrentTick();//t0は現在の時間
while(t_black<t_max){//t_blackがt_maxを超えるまで続ける
if(SENSOR_3>white){
turnLL;
} else if(SENSOR_3>white-5){//もし光センサーで白-5が測定されると
turnL;
} else if(SENSOR_3>black+5){//もし光センサーで黒+5が測定されると
mae;
} else if(SENSOR_3>black){//もし光センサーで黒が測定されると
turnR;
} else{
turnRR;
t0=CurrentTick();//t0は現在の時間
until((SENSOR_3<black+5)&&(SENSOR_3>black));//黒+5か黒になるまで
t_black=CurrentTick()-t0;
}
Wait(step);
}
}
***交差点で直進するプログラム [#kb17e0b6]
まず,光センサーが白-5を超えるまでまっすぐ進み,次に光センサーが光センサーが黒+5を超えるまで右に曲がる.これが交差点で直進するプログラムである.
void crossline()//交差点を渡る
{
mae;
until(SENSOR_3>white-5);//光センサーが白-5を超えるまで
turnR
until(SENSOR_3>black+5);//光センサーが黒+5を超えるまで
}
***右に曲がるプログラム [#e1ec5902]
void Rcurve()//右に曲がる
{
turnRRR;
until(SENSOR_3>white-5);//光センサーが白-5を超えるまで
}
***左に曲がるプログラム [#q94d9624]
void Lcurve()//左に曲がる
{
turnLLL
until(SENSOR_3>white);//光センサーが白を超えるまで
}
***ロボットの向きを変えるプログラム [#y70b7bfe]
void kaiten()//ロボットを180度回転させる
{
mae;
Wait(900)
OnFwd(OUT_B,20);OnRev(OUT_C,10);
until(SENSOR_3<black+5);
}
**メインプログラム [#td3fc862]
メインプログラムは、定義したものを組み合わせます.
task main()
{
SetSensorLight(S3);
linetraceCL();//M→K
crossline();//交差点を渡る
OnFwd(OUT_BC,30);Wait(2900);Off(OUT_BC);//K→L
OnFwd(OUT_A,30);Wait(1000);Off(OUT_A);//アームを下げてピンポン玉を取る
kaiten();//ロボットの向きを変える
linetraceSR();L→K
Rcurve();//右に曲がる
linetreceSL();//K→J
teishi;//一時停止
Lcurve();//左に曲がる
linetraceCL();//J→I
croseline();//交差点を渡る
linetraceCL();//J→H
croseline();//交差点を渡る
linetraceCL();//H→G
Lcurve();//左に曲がる
linetraceSL();//G→F
Lcurve();//左に曲がる
linetraceSL();//F→E
Lcurve();//左に曲がる
linetraceSL();//E→D
teishi;//一時停止
crossline();//交差点を渡る
linetraceCR();//D→B
teishi;//一時停止
OnRev(OUT_A,30);Wait(1000);Off(OUT_A);//アームを上げてピンポン玉を出す
}
*まとめ [#b322ee94]
今回のプログラムはサブルーチンを多く用いました.始めはライントレースをするだけでもロボットが思うように動かず大変苦労しました.しかし,結果として納得することができるプログラムができたので良かったです.ただ,ボールを取るところで止まるための効率的なプログラムが思いつかなかったので,次はそこを改良していきたいです.