ロボットの紹介†
ロボット本体†
- 今回の課題には写真のロボット二つを使用した。
プログラム内の移動時間などがロボットの重量の差に左右されないように、二つのロボットの構造を同じにしてプログラム作りの負担を少なくした。
また、開発初期は3つのタイヤで動作させていたが、ライントレースの動きに不安定さが見られたので、前回と同じく一つのモーターで左右二つずつのタイヤを動かすことにした。
アーム†
- ボールを打ち出す、受け取る動作はロボットの前方に取り付けられたアームを上下させることによって行う。
アームの幅を広くすることによってボールをより確実に受け取る事が出来るようになっている。
コース攻略法†
初めにボールを取りに行く側†
- プログラム内の時間を合わせるためにスタートから同時にスタートする。
スタート後ライントレースを行い規定の位置に置かれたピンポン玉を取りに行く。
ピンポン玉を取りに行った後はライントレースを行いながら決められた時間に図の2、3、4のパスを行って4のパス終了後に停止する。
ボールをゴールにシュートする側†
- 初めにボールを取りに行く側と同じくスタートから同時にスタートする。
スタート後は図の2のパスが行われる時間まで図の2の矢印の先で待機する。
その後、決められた時間に3、4のパスを行う。
4のパスの後ライントレースを行ってゴールへボールをシュートする。
プログラムの説明†
- 二つのプログラムの時間を合わせることによってパスのタイミングを合わせるようになっている。
初めにボールを取りに行く側†
#define BLACK_high 36 //一番黒いしきい値
#define BLACK_low 38 //少し黒いしきい値
#define WHITE_low 42 //少し白いしきい値
#define WHITE_high 44 //一番白いしきい値
#define turn_left_senkai OnRev(OUT_A); OnFwd(OUT_C); //左旋回
#define turn_left_kaiten Off(OUT_A); OnFwd(OUT_C); //左前進
#define turn_right_kaiten OnFwd(OUT_A); Off(OUT_C); //右前進
#define turn_right_senkai OnFwd(OUT_A); OnRev(OUT_C); //右旋回
#define go_fwd OnFwd(OUT_AC); //前進
#define short_break Off(OUT_AC); Wait(100); //小休止
#define SHOTBALL OnFwd(OUT_B); Wait(500); //ボールを撃つ
#define CATCHBALL OnRev(OUT_B); Wait(500); //ボールを受け取る
#define TURNSTEP 10 //横のセンサーを使う時の繰り返しの待ち時間
#define time2 10 //シュートしない側が交差点から一回目に前進する時間
#define time3 10 //シュートしない側が交差点から二回目に前進する時間
#define nMAX 300 //交差点と判断する基準
#define STEP 1 //ライントレース時の待ち時間
task main(){
SetSensor(SENSOR_2,SENSOR_LIGHT);
int nOnline=0;
int nCross=0;
ClearTimer(0);
while(nCross <= 1){
while(nOnline < nMAX){
if(SENSOR_1 < BLACK_high){
turn_left_senkai ;
nOnline++ ;
} else if(SENSOR_2 < BLACK_low){
turn_left_kaiten;
} else if(SENSOR_2 < WHITE_low){
go_fwd;
} else if(SENSOR_2 < WHITE_high){
turn_right_kaiten;
} else {
turn_right_senkai;
}
}
nOnline == 0;
nCross ++;
short_break;
cross_line;
}
nCross=0;
go_fwd;
Wait(500);
OnRev(OUT_A);
OnFwd(OUT_C);
Wait(100); //ボールに向く
CATCHBALL;
OnFwd(OUT_AC);
Wait(200); //ボールを取る
until(SENSOR_1 < BLACK_low){
turn_left_kaiten;
} //コースに戻る
- ライントレースをしながら決まった位置まで動き、一回目のパスをする。
while(nCross <= 1){ //決まった位置までライントレース
if(SENSOR_1 < BLACK_high){
turn_left_senkai;
nOnline ++;
} else if(SENSOR_2 < BLACK_low){
turn_left_kaiten;
} else if(SENSOR_2 < WHITE_low){
go_fwd;
} else if(SENSOR_2 < WHITE_high){
turn_right_kaiten;
} else {
turn_right_senkai;
}
}
nCross=0;
turn_left_senkai; //相手の方向を向く
Wait(70);
until(FastTimer(1) > 4500); //一回目のパス
SHOTBALL;
turn_right_senkai;
Wait(70);
while(nCross <= 1){ //決まった位置までライントレース
if(SENSOR_1 < BLACK_high){
turn_left_senkai;
nOnline ++;
} else if(SENSOR_2 < BLACK_low){
turn_left_kaiten;
} else if(SENSOR_2 < WHITE_low){
go_fwd;
} else if(SENSOR_2 < WHITE_high){
turn_right_kaiten;
} else {
turn_right_senkai;
}
}
nCross=0;
while (FastTimer(0) <= time2){
if(SENSOR_1 < BLACK_high) {
turn_right_senkai;
} else if (SENSOR_1 < BLACK_low) {
back_turn_right_kaiten;
} else if (SENSOR_1 < WHITE_low) {
go_fwd;
} else if (SENSOR_1 < WHITE_high) {
back_turn_left_kaiten;
} else {
turn_left_senkai;
}
Wait(STEP);
}
turn_left_senkai; //相手の方向を向く
Wait(70);
until(FastTimer(1) > 6000);//二回目のパス
CATCHBALL;
turn_right_senkai;
Wait(70);
while (nCross < 1){ //決まった位置までライントレース
while (nOnline < nMAX){
if(SENSOR_1 < BLACK_high){
turn_right_senkai;
nOnline++;
} else {
if (SENSOR_1 < BLACK_low){
turn_right_kaiten;
} else if (SENSOR_1 < WHITE_low){
go_fwd
} else if (SENSOR_1 < WHITE_high){
turn_left_kaiten;
} else {
turn_left_senkai;
}
nOnline==0;
}
Wait(STEP);
}
PlaySound(SOUND_UP);
short_break;
nCross++;
nOnline=0;
}
turn_left_senkai; //相手の方向を向く
Wait(70);
until(FastTimer(1) > 7500); //3回目のパス
SHOTBALL;
Off(OUT_AC);
}
ボールをゴールにシュートする側†
#define BLACK_high 37 //一番黒いしきい値
#define BLACK_low 39 //少し黒いしきい値
#define WHITE_low 47 //少し白いしきい値
#define WHITE_high 49 //一番黒いしきい値
#define HIPOWER 5
#define LOWPOWER 1
#define TURNSENSOR 40 //サイドセンサーが線を感知するしきい値
#define set_power_H SetPower(OUT_AC,HIPOWER);
#define set_power_L SetPower(OUT_AC,LOWPOWER);
#define turn_left_senkai set_power_L; OnRev(OUT_A); OnFwd(OUT_C); //左旋回
#define turn_left_kaiten set_power_L; Off(OUT_A); OnFwd(OUT_C); //左前進
#define turn_right_kaiten set_power_L; OnFwd(OUT_A); Off(OUT_C); //右前進
#define turn_right_senkai set_power_L; OnFwd(OUT_A); OnRev(OUT_C); //右旋回
#define go_fwd set_power_H; OnFwd(OUT_AC); //前進
#define short_break Off(OUT_AC); Wait(100); //小休止
#define back_turn_left_kaiten Off(OUT_A); OnRev(OUT_C); //左後進
#define back_turn_right_kaiten OnRev(OUT_A); Off(OUT_C); //右後進
#define go_rev set_power_H; OnRev(OUT_AC); //後進
#define SHOTBALL OnFwd(OUT_B); Wait(500); //ボールを撃つ
#define CATCHBALL OnRev(OUT_B); Wait(500); //ボールを受け取る
#define TURNSTEP 10 //横のセンサーを使う時の繰り返しの待ち時間
#define time1 10 //シュートしない側が交差点からバックする時間
#define time2 1000 //シュートしない側が交差点から一回目に前進する時間
#define time3 10 //シュートしない側が交差点から二回目に前進する時間
#define mess1 1 //一回目のパス時に送受信するメッセージ
#define mess2 2 //二回目のパス時に送受信するメッセージ
#define mess3 3 //三回目のパス時に送受信するメッセージ
#define nMAX 5 //交差点と判断する基準
#define STEP 1 //ライントレース時の待ち時間
#define cross_time 30
#define cross_line go_fwd set_power_H; OnFwd(OUT_AC); Wait(cross_time); short_break;
task main(){
SetSensor(SENSOR_1,SENSOR_LIGHT);
SetSensor(SENSOR_2,SENSOR_LIGHT);
int nOnline=0;
int nCross=0;
int counter=0;
ClearTimer(0);
ClearTimer(1);
- スタートしてコースの端で位置で待機し、その後パスを受ける
go_fwd;
Wait(100);
while(nCross < 2){ //コースの端まで進む
while(nOnline < nMAX-1){
if (SENSOR_2 < BLACK_high){
turn_left_senkai;
nOnline++;
} else {
if (SENSOR_2 < BLACK_low){
turn_left_kaiten;
} else if (SENSOR_2 < WHITE_low){
go_fwd;
} else if (SENSOR_2 < WHITE_high){
turn_right_kaiten;
} else {
turn_right_senkai;
}
nOnline=0;
}
Wait(STEP);
}
short_break;
turn_right_senkai; Wait(nMAX*STEP);
cross_line;
PlaySound(SOUND_UP);
nOnline=0;
nCross++;
}
go_fwd;
Wait(20);
Off(OUT_AC);
Wait(50);
OnRev(OUT_A); OnFwd(OUT_C);
Wait(70);
Off(OUT_AC);
SHOTBALL;
until (FastTimer(1) == 4060); //待機
CATCHBALL; //1回目のパス
OnRev(OUT_A); OnFwd(OUT_C);
Wait(70);
Off(OUT_AC);
nCross=0;
while(nCross < 1){ //パスの位置まで進む
while(nOnline < nMAX+2){
if (SENSOR_2 < BLACK_high){
turn_right_senkai;
nOnline++;
} else {
if (SENSOR_2 < BLACK_low){
turn_right_kaiten;
} else if (SENSOR_2 < WHITE_low){
go_fwd;
} else if (SENSOR_2 < WHITE_high){
turn_left_kaiten;
} else {
turn_left_senkai;
}
nOnline=0;
}
Wait(STEP);
}
PlaySound(SOUND_UP);
nOnline=0;
nCross++;
}
OnRev(OUT_C); OnFwd(OUT_A);
Wait(170);
Off(OUT_AC);
until (FastTimer(1) == 6600); //待機
SHOTBALL; //2回目のパス
OnFwd(OUT_C); OnRev(OUT_A);
Wait(120);
Off(OUT_AC);
nCross=0;
while(nCross < 1){ //コースの端まで進む
while(nOnline < nMAX+2){
if (SENSOR_2 < BLACK_high){
turn_right_senkai;
nOnline++;
} else {
if (SENSOR_2 < BLACK_low){
turn_right_kaiten;
} else if (SENSOR_2 < WHITE_low){
go_fwd;
} else if (SENSOR_2 < WHITE_high){
turn_left_kaiten;
} else {
turn_left_senkai;
}
nOnline=0;
}
Wait(STEP);
}
PlaySound(SOUND_UP);
nOnline=0;
nCross++;
}
go_fwd;
Wait(160);
Off(OUT_AC);
Wait(50);
OnRev(OUT_C); OnFwd(OUT_A);
Wait(60);
Off(OUT_AC);
until (FastTimer(1) == 8050); //待機
CATCHBALL; //3回目のパス
- 前日の調整ではパス、シュートともにうまく通ったが、当日は調整が上手くいかず悔しい結果になってしまったのが残念だった。
- パスを行うときに二台のロボットの間隔を狭めるために前進させるなどして、確実にパスを通す工夫を行うべきだった。