*目次 [#h7aacbec] #contents *課題2 [#z5994306] 次のいずれかのコースで黒い線に沿って動き、350mlの空き缶(黄色で表示)を移動させるロボットを製作せよ。 #ref(2018a/Member/tanaka/Mission2/IMG_0137.PNG,50%,コース) -コース Aをスタート Bを直進 Cで一時停止の後、直進 Dで一時停止の後、Xの空き缶をキャッチしてD地点に戻る DからEに向かい、Eを直進 Fを左折 Gで一時停止の後、左折 Hで一時停止の後、右折 Iで一時停止の後、右折 Lを直進 Kを直進 Jで一時停止の後、空き缶をYに置きてJに戻りBに向かう Bで一時停止の後、左折 Aで停止 *制作したロボット [#d3e5f5fc] 本に載っている基本のロボットを基礎として組み立てた.しかし,そのままだと光センサーの位置がロボット本体と離れていたためできるだけ近づけた. #ref(2018a/Member/tanaka/Mission2/IMG_0232.JPG,50%,機械) #ref(2018a/Member/tanaka/Mission2/IMG_0233.JPG,50%,機械) 缶をつかむ機構は広く長くすることで確実につかめるようにした.少し勢いが強く,安定感もあまりないのでもう少し改良すればよっかた. #ref(2018a/Member/tanaka/Mission2/IMG_0234.JPG,50%,つかむところ) *作成したプログラム [#k775b989] +ライントレースについて 5段階に分けて黒と白の境界をトレースしていく. 「完全に白」45以上「黒っぽい白」43「黒と白の境界」40「白っぽい黒」37「完全に黒」36以下 の5段階の値で判断させた. #define kirikaesi_migi OnFwd(OUT_A);OnRev(OUT_C);//45以上の時右に切り返し #define sasetu Off(OUT_A);OnFwd(OUT_C);//43の時少し右に旋回 #define zensin OnFwd(OUT_AC);//40の時前進 #define usetu OnFwd(OUT_A);Off(OUT_C);//37の時少し左に旋回 #define kirikaesi_hidari OnFwd(OUT_C);OnRev(OUT_A);//36以下の時左に切り返し 以上のマクロによって定義したものを使いライントレースしていく. -左側のライントレース #define THRESHOLD 40//境界部分の値 このように定義しておく 先ほどのマクロを使いラインをトレースして行く.真っ黒が続くとタイマーがリセットされないのでこれを利用して交差点だと判断した.黒が0.25秒続くと交差点だと判断してこのループから抜けるようにしてある sub Line_left() { ClearTimer(0); while(FastTimer(0)<25){ if(SENSOR_1>THRESHOLD+5){ //真っ白にいるとき kirikaesi_migi; //両方のタイヤを回して右に曲がる ClearTimer(0); //タイマーをリセット }else if (SENSOR_1>THRESHOLD+3){//黒っぽい白にいるとき usetu;//片方のタイヤだけ回して右に曲がる ClearTimer(0); }else if (SENSOR_1>THRESHOLD){//白と黒の間にいるとき zensin;//前に進む ClearTimer(0); }else if (SENSOR_1>THRESHOLD-3){//白っぽい黒にいるとき sasetu; //片方のタイヤだけ回して左に曲がる ClearTimer(0); }else{//真っ黒にいるとき kirikaesi_hidari; //両方のタイヤを回して左に曲がる }//この時タイマーをリセットしない } Off(OUT_AC); } 普通のラインはこれでトレースするが,途中の円がうまくいかないので新たなものを作った. これは黒が0.2秒続くまたは0.4秒以下のときはそのまま動作を続けるというプログラムを作り円をトレースした. sub Line_E() { ClearTimer(1); ClearTimer(0); while((FastTimer(0)<20)||(FastTimer(1)<t_musi)){/タイマー0が0.2秒以内またはタイマー1が関数より低い時に 繰り返す/ if(SENSOR_1>THRESHOLD+5){//ここから前と同じなので省略 kirikaesi_migi; ClearTimer(0); }else if (SENSOR_1>THRESHOLD+3){ usetu; ClearTimer(0); }else if (SENSOR_1>THRESHOLD){ zensin; ClearTimer(0); }else if (SENSOR_1>THRESHOLD-3){ sasetu; ClearTimer(0); }else{ kirikaesi_hidari; } } Off(OUT_AC); } -右のライントレース 左の場合とほとんど同じで違うところは黒の時と白の時の動きを逆にした. sub Line_right() { ClearTimer(0); while(FastTimer(0)<19){ if(SENSOR_1>THRESHOLD+5){ kirikaesi_hidari; ClearTimer(0); }else if (SENSOR_1>THRESHOLD+3){ sasetu; ClearTimer(0); }else if (SENSOR_1>THRESHOLD){ zensin; ClearTimer(0); }else if (SENSOR_1>THRESHOLD-3){ usetu; ClearTimer(0); }else{ kirikaesi_migi; } } Off(OUT_AC); } もう一つの円のときのプログラム sub Line_K() { ClearTimer(0); ClearTimer(1); while((FastTimer(0)<19)||(FastTimer(1)<t_musi)){ if(SENSOR_1>THRESHOLD+5){ kirikaesi_hidari; ClearTimer(0); }else if (SENSOR_1>THRESHOLD+3){ sasetu; ClearTimer(0); }else if (SENSOR_1>THRESHOLD){ zensin; ClearTimer(0); }else if (SENSOR_1>THRESHOLD-3){ usetu; ClearTimer(0); }else{ kirikaesi_migi; } } Off(OUT_AC); } 以上のプログラムでライントレース ~-その他のプログラム -その他のプログラム #define roll_left3 OnRev(OUT_A);OnFwd(OUT_C);until(SENSOR_1<=40);Off(OUT_AC);//線を探す #define roll_right3 OnRev(OUT_C);OnFwd(OUT_A);until(SENSOR_1<=40);Off(OUT_AC); この2つマクロで黒線を探すことで位置を調節する. #define cross_stop Off(OUT_AC);Wait(100);//1秒止まる #define go(t) OnFwd(OUT_AC);Wait(t);Off(OUT_AC);//t秒前進 #define TURN_RIGHT(t) OnFwd(OUT_A);OnRev(OUT_C);Wait(t);//右に曲がる #define TURN_LEFT(t) OnFwd(OUT_C);OnRev(OUT_A);Wait(t);//左に曲がる 4つのプログラムで位置を微調整していく. #define back(t) OnRev(OUT_AC);Wait(t);//t秒もどる 5つのプログラムで位置を微調整していく. -缶をつかむプログラム #define tukamu OnFwd(OUT_B);Wait(15);Off(OUT_B); #define back(t) OnRev(OUT_AC);Wait(t); #define hanasu OnRev(OUT_B);Wait(15);Off(OUT_B); *完成したプログラム [#a97744c6] まず関数を定義した int t_musi=0; task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); t_musi=400; Line_left(); cross_stop;//Cで一時停止 go(20); roll_right3;//位置を調整 Line_left();//D手前の直角のところ go(40); TURN_LEFT(100); roll_right3; Line_left(); cross_stop;//Dで一時停止 go(50);//缶による tukamu;//缶を掴む back(30);//戻る TURN_LEFT(100); roll_right3;//右側の線を探す Line_E(); go(50);//Eを前進 roll_right3; Line_left();//Fを通過しそのままGへ cross_stop;//Gで一時停止 TURN_RIGHT(40); roll_right3;//位置を調整 Line_left();//GからHの途中の最初の急カーブまで TURN_LEFT(150);//方向転換 roll_right3;//線を探す Line_left();//Hに到着 cross_stop;//一時停止 go(30);//Hを前進 TURN_RIGHT(50);//方向転換 go(20);//黒線を超える roll_right3;//線を探す Line_left();//Iまでいく cross_stop;//Iで一時停止 go(50) TURN_RIGHT(80);//右に曲がる roll_left3; Line_K();//Lまで行く go(50);//Lを通過 roll_left3;//位置を調整 Line_K();//Kに到着 go(50);//Kを通過 roll_left3; Line_K(); cross_stop;//Jで一時停止 TURN_LEFT(120);//Yの方を向く go(30); hanasu;//缶を離す back(50);//もとの位置戻る TURN_LEFT(150);//反転する roll_left3;//線を見つける Line_right(); cross_stop;//Bで一時停止 go(30); roll_left3; Line_right();//Aに到着 Off(OUT_AC);//終了 } 以上で終了 *反省と感想 [#ie79acd0] ライントレースのプログラム自体は簡単に作ることができたがそれを使いコースを走らせるのが大変だった.いろいろなところで微調整が必要で誤作動が起こるとうまくいかないので試行錯誤しながらだったの時間がかっかた.また,缶をつかむ機構の安定感がなくうまくいかなかった.プログラムに時間をかけすぎてしまったのでつぎは気を付けたい.