目次 ロボコン †課題:紙パック収集・分別ロボット †コースについて † ・紙パックを収集して色ごとに別の目的地まで運ぶ ルールについて † ・紙パックを所定の場所に運ぶ。 ロボットの説明 †ロボットA(ロボット運搬用):てつお †初めは四輪にしていたが旋回性能が極端に低くうまく曲がれなかったので、前二輪を排除して底部に滑りやすいパーツを付けた脚柱に交換した。 ロボットBを降ろすスロープはロボットに押されたときに倒れやすいようにそれぞれ1点で固定してある。また。倒れた時の衝撃を少しでも緩和するために接地点をチューブで保護した。(あまり効果はなかったようだが) 最後にロボットBを降ろした後にロボットBの作業の妨げにならないようにスロープを回収する必要があり、その作業を確実にするために凹凸の多いスロープの裏に直角三角形のパーツを仕込んだ。 ロボットB(牛乳パック運搬用);ごんぞう †ロボットBの移動は2つの光センサーによるライントレースで行った。 ロボットAに載せて運搬するためになるべく全体が小さくまとまるように制作した。 パックを掴む動作は4本のアームで左右からはさみこむように掴むものにした。 パックをしっかりと保持するためにギヤにトルクギヤを使い常にパックに力がかかるようにした。 ただし、パック同士の間隔が狭いのでアームが必要以上に開かない様にストッパーを付けた。 また、ロボットが壁に近づきすぎるとパックを押し出してしまうのでタッチセンサーを少し前に出してロボットと壁の間隔を確保している。 プログラム †てつお †#define go_straight(t) OnFwd(OUT_A+OUT_C);Wait(t);Off(OUT_A+OUT_C); //直進のマクロ #define turn_right OnFwd(OUT_A);OnRev(OUT_C);Wait(90);Off(OUT_A+OUT_C); //右旋回のマクロ #define turn_left OnFwd(OUT_C);OnRev(OUT_A);Wait(90);Off(OUT_C+OUT_A); /左旋回のマクロ #define SIGNALON 11 //行動開始の信号を11に設定 task main() { SetPower(OUT_A,7); //モーターA,Bの出力を7(最大)に設定 SetPower(OUT_C,7); go_straight(150); // 1.5秒間直進 turn_right; //右旋回 go_straight(150); //1.5秒間直進 turn_right; //右旋回 go_straight(150); //1.5秒間直進 turn_left; //左旋回 go_straight(100); //1秒間直進 Off(OUT_A+OUT_B); //停止 ClearTimer(0); //タイマーリセット ClearMessage(); //メッセージリセット while((Message()!==1)||(FastTimer(0)<700)){ //返事1を受け取る、または7秒経過するまで SendMessage(SIGNALON); //信号11を送り続ける } ClearTimer(0); //タイマーリセット until(FastTimer>150); //1.5秒経過するまで待機 OnRev(OUT_A+OUT_C); //1秒後退 wait(100); Off(OUT_A+OUT_C); //停止 } ごんぞう †サブルーチンを多用して調整をしやすくし、 それぞれのパックごとにプログラムを組んである 時間指定とセンサーによる2段構えの条件付けでT字路や十字路を認識させている 例えば { turn_l; until(SENSOR_2<LINE);} とすると、turn_lの中には90度の旋回時間が入っているのでその間はセンサーが反応しないので旋回時間が終わった後の黒線に反応するので少々旋回時間がいい加減でも上手く曲がる。 ここからが実際のプログラム #define T_T81 //旋回時間1 #define T_T2 170 //旋回時間2 #define LINE 40 #define SIGNALON 11 //行動開始の信号 #define straight(t) OnFwd(OUT_B+OUT_C);Wait(t);Off(OUT_B+OUT_C);//直進のマクロ 以下はサブルーチン sub turn_l() //左旋回1 { OnFwd(OUT_C);OnRev(OUT_B); Wait(T_T); Off(OUT_B+OUT_C); } sub turn_r() //右旋回1 { OnFwd(OUT_B);OnRev(OUT_C); Wait(T_T); Off(OUT_B+OUT_C); } sub turn2_l() //左旋回2 { OnFwdOUT_C);Off(OUT_B); Wait(T_T2); Off(OUT_C); } sub turn2_r() //右旋回2 { OnFwdOUT_B);Off(OUT_C); Wait(T_T2); Off(OUT_B); } sub catch() //パックを掴む動作 { OnFwd(OUT_B+OUT_C); //タッチセンサーが反応するまで前進 until(SENSOR_3==1); Off(OUT_B+OUT_C); OnRev(OUT_A); //パックを掴む Wait(60); OnRev(OUT_B+OUT_C); //少し後退 Wait(50); Off(OUT_B+OUT_C); } sub relese() //パックを放す { Off(OUT_B+OUT_C); OnFwd(OUT_A); Wait(60); OnRev(OUT_B+OUT_C); Wait(50); Off(OUT_B+OUT_C); } メインプログラム task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); センサー1、2は光センサー SetSensor(SENSOR_2,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_TOUCH); センサー3はタッチセンサー ClearTimer(0); タイマーリセット ClearMessage(); メッセージクリア until((Message()==SIGNALON)||(FastTimer(0)>1900));//信号を受信または19秒経過 SendMessage(1); // 返事を返す まで待機 OnFwd(OUT_B+OUT_C); //ロボットAから降りる Wait(130); OnFwd(OUT_A); Wait(50); Off(OUT_A+OUT_B+OUT_C); Wait(150); OnRev(OUT_B+OUT_C); until((SENSOR_1<LINE)&&(SENSOR_2<LINE)); //ラインを探す OnFwd(OUT_C);Off(OUT_B); Wait(150); start folloW_line; until(SENSOR_3==1); //タッチセンサーが反応するまでライントレース stop follow_line; Off(OUT_B+OUT_C); //停止 Wait(30); turn_l(); //左旋回 OnRev(OUT_B+OUT_C); //位置を調整 Wait(30); Off(OUT_B+OUT_C); catch(); //パックを掴む turn_l(); //左旋回 start follow_line; //光センサーが十字路を見つけるまでトレース until((SENSOR_1<LINE)&&(SENSOR_2<LINE)); stop follow_line; turn2_l; //光センサー2がラインに反応するまで右旋回 until(SENSOR_2<LINE); start follow_line; //2.1秒間ライントレース Wait(210); stop follow_line; relese(); //パックを放す OnFwd(OUT_C);OnRev(OUT_B); //反転 Wait(170); start follow_line; //タッチセンサーが反応するまでトレース until(SENSOR_3==1); stop follow_line; catch(); //パックを掴む OnFwd(OUT_C);OnRev(OUT_B); //反転 Wait(170); start follow_line; //2.1秒間ライントレース Wait(210); stop follow_line; relese(); //パックを放す OnFwd(OUT_C);OnRev(OUT_B); //反転 Wait(170); start follow_line; //十字路までトレース until((SENSOR_1<LINE)&&(SENSOR_2<LINE)); stop follow_line; turn2_r; //光センサー1が右旋回 until(SENSOR_1<LINE); straight(50); //0.5秒間直進 turn_l; //左旋回 catch(); //パックを掴む turn_l(); start follow_line; //十字路までトレース Wait(100); until((SENSOR_1<LINE)&&(SENSOR_2<LINE)); stop follow_line; turn2_l(); //センサー2が反応するまで左旋回 until(SENSOR_2<LINE); start follow_line; //2.1秒間直進 Wait(210); stop follow_line; relese(); //パックを放す OnFwd(OUT_C);OnRev(OUT_B); //反転 Wait(170); start follow_line; //タッチセンサーが反応するまでトレース until(SENSOR_3==1); stop follow_line; catch(); //パックを掴む OnFwd(OUT_C);OnRev(OUT_B); //反転 Wait(170); start follow_line; //2.1秒間ライントレース Wait(210); stop follow_line; relese(); //パックを放す OnFwd(OUT_C);OnRev(OUT_B); //反転 Wait(170); start follow_line; //十字路までトレース until((SENSOR_1<LINE)&&(SENSOR_2<LINE)); stop follow_line; turn2_l() //光センサー2が反応するまで左旋回 until(SESOR_2<LINE); start follow_line; //タッチセンサーが反応するまでトレース until(SENSOR_3==1); stop follow_line; turn_r(); //右旋回 OnRev(OUT_B+OUT_C); //位置を調整 Wait(30); Off(OUT_B+OUT_C); catch(); //パックを掴む turn_r(); //右旋回 start follow_line; //十字路までトレース until((SENSOR_1<LINE)&&(SENSOR_2<LINE)); stop follow_line; turn2_r; //光センサー1が反応するまで右旋回 until(SENSOR_1<LINE); start follow_line; //2.1秒間トレース Wait(210); stop follow_line; relese(); //パックを放す OnFwd(OUT_B);OnRev(OUT_C); //反転 Wait(170); start follow_line; //十字路までトレース until((SENSOR_1<LINE)&&(SENSOR_2<LINE)); stop follow_line; turn2_l; //光センサー2が反応するまで左旋回 until(SENSOR_2<LINE); straight(50); //0.5秒間直進 turn_r; //右旋回 catch(); //パックを掴む turn_r(); //右旋回 start follow_line; //十字路までトレース Wait(120); until((SENSOR_1<LINE)&&(SENSOR_2<LINE)); stop follow_line; turn2_r(); //光センサー1が反応するまで右旋回 until(SENSOR_1<LINE); start follow_line; //2.1秒間トレース Wait(210); stop follow_line; relese(); //パックを放す } task follow_line();{ //ライントレースのタスク while(true){ if(SENSOR_1>LINE){ //センサー1白 if(SENSOR_2<LINE){ //センサー2黒のとき OnFwd(OUT_B);Float(OUT_C); //右へ } else{ //センサー2白のとき OnFwd(OUT_B+OUT_C); //直進 } } else{ //センサー1黒 if(SENSOR_2>LINE){ //センサー2白のとき OnFwd(OUT_C);Float(OUT_B); //左へ } else{ //センサー2黒のとき OnFwd(OUT_B+OUT_C); //直進 } } } } 反省&感想 †ロボットBをコンパクトにまとめたつもりだったけど実際にはまだ大きかった様に思えた。また、プログラムについてはパックごとに分けたために非常に長くなってしまったのが反省点かと思う。(T.I) ロボットAは、細部にわたって頑丈にしたつもりだったけど、本番では壊れてしまったのが残念だった。(naoto) コメント欄(ご自由にどうぞ) † |