[[2012b/Member]] *課題1レポート [#ude5aad5] **メンバー紹介 [#bba6749b] mokomiti 工学部機械システムなんちゃら学科。真面目に勉強してる学徒。~ shief 繊維学部機械ロボなんちゃら学科。まともなこと言わない。遅刻魔。~ 卵ご飯は卵だけといてご飯にかける方。~ **ロボットの構造 [#c6937ebd] スムーズなライントレースをするような構造であること。~ 小回りが聞くこと。~ コース上にフラグが立てられているためそのフラグに干渉せずにライントレスするための構造であること。~ 緩やかな動きをするロボットであること。~ センサーの反応前に動ききってしまっては意味がないため。~ そのため適切なギア比を設定して走行速度を落とした。~ もちろんプログラム上でもパワーを小さくしている。~ #ref(./IMG_1159.JPG,39845bytes,車体) 初期のロボットではピンポン球をうまくつかめない。~ すぐ壊れる。~ など様々な問題があったが改良や度重なる作りなおしで解決した。~ ただし、特定の場所がすぐ壊れるという問題だけは最後まで解決できず。~ よく言えば分解しやすいとも受け取れるだろう。~ 画像は車体前部のボールをつかむパーツ #ref(./IMG_1170.JPG,49401bytes,動作部分) #ref(./IMG_1169.JPG,48996bytes,ベース) **プログラムの構造と変遷 [#g89bfae9] #ref(./IMG_1171.JPG,29293bytes,コース) ***初期プログラム [#y421ad6e] もっとも正確にライントレスしたが、~ ゴール地点でのシュート機構を考えていなかったため不採用。~ なによりもシュートする地点を判別できなかった。~ 発進地点から秒数による制御は安直過ぎるとのことで見送り。~ /*左からスタートで最初カーブ(コースをさす)するプログラム*/ #define THRESHOLD 48 /*閾値調整 */ #define HIPOWER 7 /*出力調整*/ #define LOWPOWER 2 /*出力調整*/ #define RUN_TIME1 600 /*トレースする時間(単位 1/100 秒) */ #define RUN_TIME2 3000 /*調整 */ #define set_power_H SetPower(OUT_AC,HIPOWER); #define set_power_L SetPower(OUT_AC,LOWPOWER); #define go_forward set_power_H;OnFwd(OUT_AC); #define turn_left1 set_power_L;\ OnFwd(OUT_C); OnRev(OUT_A); /*左旋回*/ #define turn_left0 set_power_L;\ OnFwd(OUT_C); Off(OUT_A); /*左折*/ #define turn_right1 set_power_L;\ OnFwd(OUT_A); OnRev(OUT_C); /*右旋回*/ #define turn_right0 set_power_L;\ OnFwd(OUT_A); Off(OUT_C); /*右折*/ #define STEP 1 task main() /*ボールへ向かう*/ { go_forward; Wait(100); Off(OUT_AC); /*ボール回収に使うモータの動き*/ OnRev(OUT_B); Wait(70); Off(OUT_B); /*進行方向左側トレース*/ { SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while ( FastTimer(0) <= RUN_TIME1 ) /*時間調整*//*カーブ走行中にトレスするラインを変更する時間*/ { if(SENSOR_2 <= THRESHOLD -9) { turn_left1; /*とても黒い時左旋回*/ } else if (SENSOR_2 < THRESHOLD -5) { turn_left0; /*黒い時左折*/ } else if (SENSOR_2 < THRESHOLD +2) { go_forward; /*灰色の時前進*/ } else if (SENSOR_2 < THRESHOLD +7) { turn_right0; /*白い時右折*/ } else { turn_right1; /*白い時右旋回*/ } Wait(STEP); } /*右側トレスに切り替わる*/ while ( FastTimer(0) > RUN_TIME1) /*時間調整*/ { if (SENSOR_2 < THRESHOLD -9) { turn_right1; /*とても黒い時右旋回*/ } else if (SENSOR_2 < THRESHOLD -5) { turn_right0; /*黒い時右折*/ } else if (SENSOR_2 < THRESHOLD +2) { go_forward; /*灰色の時直進*/ } else if (SENSOR_2 < THRESHOLD +7) { turn_left0; /*白いとき左折*/ } else { turn_left1; /*それ以外のとき左旋回*/ } Wait(STEP); } } while ( FastTimer(0) > RUN_TIME2 ) /*時間調整*/ { if(SENSOR_2 <= THRESHOLD -9) { turn_left1; /*とても黒い時左旋回*/ } else if (SENSOR_2 < THRESHOLD -5) { turn_left0; /*黒い時左折*/ } else if (SENSOR_2 < THRESHOLD +2) { go_forward; /*灰色の時直進*/ } else if (SENSOR_2 < THRESHOLD +7) { turn_right0; /*白い時右折*/ } else { turn_right1; /*とても白い時右旋回*/ { turn_right1; /*その他の時右旋回*/ } Wait(STEP); } } /* 最後にボール開放動作予定*/ ***実装プログラム [#l4226696] ライントレスは上記プログラムを流用し二点目の交差点からの秒数によって~ シュートする地点を大まかに指定してやろうというプログラム。~ 時間による大まかな縛りを加えて誤差を防ごうとしたが挙動が不安定になり取り消し。~ /*左からスタートで最初カーブ(コースをさす)するプログラム*/ #define THRESHOLD 48 /*閾値調整 */ #define HIPOWER 7 /*出力調整*/ #define LOWPOWER 2 /*出力調整*/ #define RUN_TIME1 600 /*トレースする時間(単位 1/100 秒) */ #define RUN_TIME2 800 #define set_power_H SetPower(OUT_AC,HIPOWER); #define set_power_L SetPower(OUT_AC,LOWPOWER); #define go_forward set_power_H;OnFwd(OUT_AC); #define turn_left1 set_power_L;\ OnFwd(OUT_C); OnRev(OUT_A); /*左旋回*/ #define turn_left0 set_power_L;\ OnFwd(OUT_C); Off(OUT_A); /*左折*/ #define turn_right1 set_power_L;\ OnFwd(OUT_A); OnRev(OUT_C); /*右旋回*/ #define turn_right0 set_power_L;\ OnFwd(OUT_A); Off(OUT_C); /*右折*/ #define STEP 1 int n=0; /*20*/ task main() { /*ボールへ向かう*/ go_forward; Wait(100); Off(OUT_AC); /*ボール回収に使うモータの動き*/ OnFwd(OUT_B); Wait(70); // 30 Off(OUT_B); n==0; /*進行方向左側トレス*/ SetSensor(SENSOR_2,SENSOR_LIGHT); ClearTimer(0); while ( FastTimer(0) <= RUN_TIME1 ) /*時間調整*/ { if(SENSOR_2 <= THRESHOLD -9) { turn_left1; /*とても黒い時左旋回*/ n==0; } else if (SENSOR_2 < THRESHOLD -5) { turn_left0; /*黒い時左折*/ n==0; } else if (SENSOR_2 < THRESHOLD +2) { go_forward; /*灰色の時直進*/ n==0; } else if (SENSOR_2 < THRESHOLD +7) { turn_right0; /*白い時右折*/ n==0; } else { turn_right1; /*その他の時右旋回*/ n==0; } Wait(STEP); } /*右側トレス時間制限Ver.*/ while ( RUN_TIME1 < FastTimer(0) <= RUN_TIME2) /*時間調整*/ { if (SENSOR_2 < THRESHOLD -9) { turn_right1; /*とても黒い時右旋回*/ n==0; } else if (SENSOR_2 < THRESHOLD -5) { turn_right0; /*黒いとき右折*/ n==0; } else if (SENSOR_2 < THRESHOLD +2) { go_forward; /*灰色の時直進*/ n==0; } else if (SENSOR_2 < THRESHOLD +7) { turn_left0; /*白いとき左折*/ n==0; } else { turn_left1; /*それ以外の時左旋回*/ n==0; } Wait(STEP); } /*右側トレス時間経過後*/ while ( FastTimer(0)>RUN_TIME2 ) /*時間調整*/ { if (SENSOR_2 < THRESHOLD-9) { turn_right1; /*とても黒い時右旋回*/ n++; /*右旋回をカウント。もしカウントしたら下へ。*/ } else if (n>=3) /*三回連続右旋回を処理したら*/ { turn_left0; /*左へ切り返して*/ Wait(50); go_forward; /*前進して*/ Wait(100); Off(OUT_AC); ClearTimer(2); while(600>FastTimer(2)) /*時間調整*//*右側トレスへ*/ { if (SENSOR_2 < THRESHOLD -9) { turn_right1; /*とても黒い時右旋回*/ } else if (SENSOR_2<THRESHOLD-5) { turn_right0; /*黒い時右折*/ } else if (SENSOR_2<THRESHOLD+2) { go_forward; /*灰色の時直進*/ } else if (SENSOR_2<THRESHOLD+7) { turn_left0; /*白い時左折*/ } else { turn_left1; /*その他の時左旋回*/ } Wait(STEP); } while(600<FastTimer(2)) /*閾値調整 *//*シュート動作*/ { go_forward; /*前進*/ Wait(100); Off(OUT_AC); OnRev(OUT_B); /*シュート用モータ動作*/ Wait(100); Off(OUT_B); OnFwd(OUT_AC); /*前進*/ Wait(50); OnRev(OUT_AC); /*後退*/ Wait(50); Off(OUT_AC); Wait(1000); } } else if (SENSOR_2 < THRESHOLD -5) { turn_right0; n==0; /*黒いとき右折*/ } else if (SENSOR_2 < THRESHOLD +2) { go_forward; /*灰色の時直進*/ n==0; } else if (SENSOR_2 < THRESHOLD +7) { turn_left0; /*白いとき左折*/ n==0; } else { turn_left1; /*それ以外の時左旋回*/ n==0; } Wait(STEP); } } **改善点及び感想 [#c1cbacde] ***改善点 [#i181e67a] 試行時ですら誤差が大きい。~ プログラムの組み方によるものだと考えられる。~ もう少しなんとかならなかったのか。~ ライントレスのみの時点では正確にトレスできていたのだからそれを活かして~ シュートタイミングの判別をどのような基準にするかを再考する必要がある。 ***感想 [#s607e7f6] うまくいったのは一度だけ…~ こんな博打打ちのようなプログラムでは…~ もし2013年度生の方が見ることがあれば以下を注意してください~ コースの紙は折らない方がよい。~ タイヤとギア(前述ギア比の関係)が紙に干渉してスムースな動作をしなくなる。~ 白い部分で光センサーの感知する閾値が変わることによってその地点で立ち止まる。~ コースに描く線は丁寧かつレギュレーションギリギリの太さで。~ 上記実装プログラムのようなカウントを用いる場合値の変更が必要となるだろうが、その点を考慮していないため注意すること。~