目次
参照 → 2014a/Mission1
yukiyamaneko
ゴールから出発しスタートに到着したらボールを放つ
tacchan 参照 → 2014a/Member/tacchan/Mission1
スタートから出発しゴールに到着したらボールを放つ
黒線上をライントレースするために光センサーを取り付け黒色と白色の認識をするようにしました。
コース上のボールを回収するために超音波センサーをロボット前方の下方に設置、 ボールをつかむためにアームを取り付けました。
ロボットを進ませるためにモーターを二つ付け、それぞれのモーターを前進後進させることにより 左旋回や右旋回させることも出来ます。
プログラムを作っていくときに繰り返し使うような動作や数値、すぐに変更したい数値をtaskの外で扱えるようにしたい。
そこで『#define』を使っていくつかの動作や数値を定義します。
#define THRESHOLD 50 //しきい値 #define SPEED_H 35 //高速 #define SPEED_L 25 //低速 #define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); #define go_forward OnRL(SPEED_H,SPEED_H);//直進 #define turn_left1 OnRL(SPEED_L,-SPEED_L);//左旋回 #define turn_left0 OnRL(SPEED_L,0);//左折 #define turn_right0 OnRL(0,SPEED_L);//右折 #define turn_right1 OnRL(-SPEED_L,SPEED_L);//右旋回 #define STEP 1 #define nMAX 250//玉を取るまでの黒線カウンターの最大値 #define nMAX2 175//玉をとった後の黒線カウンターの最大値 #define short_break Off(OUT_BC);Wait(1000);//小休憩 #define CROSS_TIME 450 //交差点の通過時間 #define cross_line OnRL(SPEED_L,SPEED_L);Wait(CROSS_TIME);short_break; //交差点を渡る
ロボットに付けた光センサーを使って、線の左側をトレースして進ませます。
黒線と白色の紙とのしきい値を使って、その値とどのくらい違うかによって右に旋回するのか
左に旋回するかを決めるプログラムを作ります。
黒線の左側をライントレースするプログラムだけでは交差点に進入したときに右折してしまいます。
そこで何回以上黒線上にいると判断したときには交差点を通過し軌道修正して元のライントレースを
続けるというプログラムを作成します。
while(nOnline<nMAX) //nOnineの数値がnMAXの数値を下回るときに作動する { if(SENSOR_3<THRESHOLD-15) //しきい値より-15未満の時は左旋回します { turn_left1; nOnline++;//カウンターの数値を増やす }else{ if(SENSOR_3<THRESHOLD-7)//しきい値より-7未満のときは左折 { turn_left0; }else if(SENSOR_3<THRESHOLD+7) //しきい値より+7未満のときは直進 { go_forward; }else if(SENSOR_3<THRESHOLD+15) //しきい値より+15未満のときは右折 { turn_right0; }else{ //それ以外の時は右旋回をする turn_right1; } nOnline=0; //nOnlineカウンターをリセット } Wait(STEP); } short_break; //小休憩 turn_left1;Wait(nMAX*STEP); //左旋回することで軌道修正。 cross_line; //交差点を通過 PlaySound(SOUND_UP); //交差点判断したことを確認するために交差点判断したら音を鳴らす nOnline=0; //nOnlineのカウンターをリセットする cross_number++; //cross_numberのカウンターの数値を増やす }
今回のMissionで一番苦労した点がこの途中にあるボールを回収するという動作でした。
タッチセンサーでは球が軽すぎるためセンサーが反応する前にロボットが球を押して転がって
しまったので、このロボットでタッチセンサーを使って回収するということは不可能ではないかと
考え、超音波センサーを使って一定の距離になったらアームを下げて球を回収するプログラムを作りました。
{ SetSensorLowspeed(S4); //超音波センサーの設置 if(SensorUS(S4)<10)//センサーとの距離が10cm以下になった時玉を取る { Off(OUT_BC); //BCの端子に接続しているモーターを停止する turn_right1; //右旋回 Wait(200); //0.2秒間右旋回 Off(OUT_BC); //停止 OnFwd(OUT_A,20);//アームを下ろす Wait(1300); //1.3秒かけてアームを下す Off(OUT_A); sensor_number++;//センサーのカウンターを増やす }
#define THRESHOLD 50 #define SPEED_H 35 #define SPEED_L 25 #define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); #define go_forward OnRL(SPEED_H,SPEED_H); #define turn_left1 OnRL(SPEED_L,-SPEED_L);//左旋回 #define turn_left0 OnRL(SPEED_L,0);//左折 #define turn_right0 OnRL(0,SPEED_L);//右折 #define turn_right1 OnRL(-SPEED_L,SPEED_L);//右旋回 #define STEP 1 #define nMAX 250//玉を取るまでの黒線カウンターの最大値 #define nMAX2 175//玉をとった後の黒線カウンターの最大値 #define short_break Off(OUT_BC);Wait(1000); #define CROSS_TIME 450 #define cross_line OnRL(SPEED_L,SPEED_L);Wait(CROSS_TIME);short_break; task main() { SetSensorLight(S3); SetSensorLowspeed(S4); //超音波センサーの設置 int nOnline=0;//続けて黒になった回数 int cross_number=0;//交差点を渡った回数 int sensor_number=0;//センサーが反応した回数 go_forward; Wait(1000); while(cross_number<1)//最初の交差点までのライントレース { while(nOnline<nMAX) { if(SENSOR_3<THRESHOLD-15) { turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7) { turn_left0; }else if(SENSOR_3<THRESHOLD+7) { go_forward; }else if(SENSOR_3<THRESHOLD+15) { turn_right0; }else{ turn_right1; } nOnline=0; } Wait(STEP); } short_break; turn_left1;Wait(nMAX*STEP); cross_line; PlaySound(SOUND_UP); nOnline=0; cross_number++; } while(sensor_number==0)//玉を認識して取るまでのライントレース。カウンターが0以外の時は作動しない。
{ if(SensorUS(S4)<10)//センサーとの距離が10cm以下になった時玉を取る { Off(OUT_BC); turn_right1; Wait(200); Off(OUT_BC); OnFwd(OUT_A,20);//アームを下ろす Wait(1300); Off(OUT_A); sensor_number++;//センサーのカウンターを増やす } if(SENSOR_3<THRESHOLD-15) { turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7) { turn_left0; }else if(SENSOR_3<THRESHOLD+7) { go_forward; }else if(SENSOR_3<THRESHOLD+15) { turn_right0; }else{ turn_right1; } nOnline=0; } Wait(STEP); } while(cross_number<=3)//玉をとった後のライントレース { while(nOnline<nMAX2) { if(SENSOR_3<THRESHOLD-15) { turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7) { turn_left0; }else if(SENSOR_3<THRESHOLD+7) { go_forward; }else if(SENSOR_3<THRESHOLD+15) { turn_right0; }else{ turn_right1; } nOnline=0; } Wait(STEP); } short_break; if(cross_number==2) //2番目の交差点の時は軌道修正をせずに直進する { cross_line; }else if(cross_number==3) //3番目の交差点の時は少し左に修正する量を多くする。 { turn_left1;Wait(nMAX*STEP+300); cross_line; }else { cross_line; } PlaySound(SOUND_UP); nOnline=0; cross_number++; } turn_right1; Wait(500); Off(OUT_BC);//玉をゴールに入れる動作 OnRev(OUT_A,20); Wait(400); Off(OUT_A); }
中心にある交差点と他の箇所にある交差点とでは交差している角度が違ったため黒色判断を何回したら交差点と認識するときの値を見つけるのに手間取った。