[[2010a]] #contents *課題 [#s5cc957b] 黄色いホイールを2個以上連射するロボットを作成し、以下の動きをするようにプログラムを作成せよ。&br;ただし1,3は懐中電灯を2個使用し、ロボットの動作中は懐中電灯を動かさないがいろいろな距離や方向にある懐中電灯に対応できるロボットにすること。&br;2は懐中電灯を1個使用し懐中電灯をゆっくり動かす。 (重複しないように一人一つ以上のプログラムを作成すること。2人のチームは1と2、3人のチームは1〜3) 1. 全方向から2つの懐中電灯の方向を探しだし、懐中電灯を狙ってホイールを投げる。可能な限り正確な方向に投げること。 2. 懐中電灯をゆっくり動かしたとき懐中電灯に向かって進み、懐中電灯の動きを止めれば一定の距離(懐中電灯から30cm以上離れた距離)まで近づいて懐中電灯を狙ってブロックを投げる。 3. 全方向から2つの懐中電灯の方向を探しだし、40cmの距離に近づいて懐中電灯を狙ってホイールを投げ、懐中電灯に当てる。 懐中電灯の代わりに携帯のライトなどを利用してもよい。 *ロボット [#pa121e8b] **完成したロボット [#ta25dcfa] &ref(kansei.JPG,,20%);&ref(kansei2.JPG,,20%);&br; 高床式倉庫かってくらいとんでもなく高床。&br; 高く持ち上げられたRCXのサイドにキャノンを搭載している。 **発射方法 [#dc0deafb] ***構想 [#e84733c9] 前提として、人の手を借りずに連射が可能でなくてはならないため、投擲する方式ではだめだと思った。初めは普通にモーターに直結された棒ではじくのを考えたが、次のホイールの補充やモーターの位置取りで悩んだ。そこで実際の拳銃のようにできないかと考えた。また足は前回の課題で使ったのをそのまま使いたかったので、発射はモーター一つでどうにかしようと思った。 ***完成形 [#y689e54d] &ref(hassha.jpg,,20%);丸く囲んだところが発射砲。 &ref(tama.jpg,,20%);上からホイールを補充する。重力によって次のホイールが下に落ちる。&br; &ref(gomu.JPG,,20%);トリガーを引き&ref(gomu2.JPG,,20%);ゴムの力でホイールをはじく。手動でも発射できる。&br; &ref(gomu3.jpg,,20%);このモーターに繋がれた棒が、トリガーを引く。回転することで素早い連射が可能になった。&br; &ref(1.jpg,,20%);ホイールが落ちてしまわないように、ゴムで上の方を、はじく棒に干渉しない程度に、支えている。地味に苦労した。 **その他工夫したところ [#wa48385f] ***土台 [#q45305d7] 弾であるホイールがおちてしまわないように、また飛距離を出すためには多少土台を斜めにする必要があった。&br;そうすると重心が高いため停止時に前のめりになる可能性がある。&br; &ref(sasae.JPG,,20%);こうして前に転倒防止用に補助輪みたいのをつけた。ぶっちゃけ、なくても動く。 ***光センサー [#i1eb3ac6] &ref(hikari.jpg,,20%);左右の光センサーがしっかりと別々の値をとるような間を広く取った。間の補助輪も光を左右に分けるのに一役買っていると思う。うれしい副作用。 **問題点 [#d2be9017] ・少しバランスが悪い&br; ・飛距離がまちまち **使用した懐中電灯 [#gdbc794f] &ref(dento.JPG,,20%);光量を三段階に調節できる。この課題にうってつけ。 *プログラム [#web54ed5] **ANDOのプログラム(課題2) [#sc80e0b2] ***初めの失敗したプログラム [#lea692f6] #define T 400//初めの旋回時間 int m;//光の最大値 int t;//光までの時間 int n;//m-20; sub find()//光の最大値を決めるサブルーチン { m=0; t=0; n=0; ClearTimer(0); while(FastTimer(0)<T)//一周して光の域値を決める { if(SENSOR_1>m)//光が最大値より大きければ { m=SENSOR_1;//光の値を代入 n=m-20; if(n<50){n=50;} t=FastTimer(0);//時間を計る } OnFwd(OUT_A);OnRev(OUT_C);//旋回 } Off(OUT_A+OUT_C); OnRev(OUT_A);OnFwd(OUT_C);Wait(T-t);Off(OUT_A+OUT_C);//光まで逆に旋回 ClearTimer(1); } task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); find(); while(FastTimer(1)<300)//光が止まって三秒たつまで追いかける { if((SENSOR_1>n)&&(SENSOR_3>n)){OnFwd(OUT_A+OUT_C);} else if((SENSOR_1>n)&&(SENSOR_3<n)){ClearTimer(1);OnFwd(OUT_C);Float(OUT_A);} else if((SENSOR_1<n)&&(SENSOR_3>n)){ClearTimer(1);OnFwd(OUT_A);Float(OUT_C);} else{find();}//光が見つからない時は探す } if(SENSOR_1>m){while(SENSOR_1>m){OnRev(OUT_A+OUT_C);}}//センサーの値が一周して決めた最大値より大きければ後退 else{while(SENSOR_1<=m){OnFwd(OUT_A+OUT_C);}}//それ以外は最大値まで前進 Off(OUT_A+OUT_C); OnRev(OUT_B);Wait(30);Float(OUT_B);OnFwd(OUT_B);Wait(200);Off(OUT_B);//ホイールを射出する } ***問題点 [#re291212] 先生の助言を参考にどんな懐中電灯にも対応しようと思って、一周して光の域値を決定しようと考えた。&br; しかし、最初の光の最大値を決める所がどうしてもうまくいかず、ぐるぐると回り続けるだけのプログラムになった。&br; どうやら、光センサーの感度が悪い(?)みたいで少し懐中電灯を真正面から相当(30cmよりもずっと)近づけないと部屋の明かりとあまり差が出ないとviewモードで分かった。&br;また光センサーの値にだいぶブレがあるため、瞬間的な値になってしまっていたのかもしれない。&br; 改善方法はあると思うけれど、結局部屋の明かりではぎりぎり届かない値を設定した方が簡単だと思い、次のように変えた。 ***最終的なプログラム [#a2716cc5] #define n 50//光の域値 task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT); ClearTimer(1); while(FastTimer(1)<200)//2秒前方に光を浴びる→懐中電灯が止まったと判定 { if((SENSOR_1>n)&&(SENSOR_3>n)){OnFwd(OUT_A+OUT_C);} else if((SENSOR_1>n)&&(SENSOR_3<n)){ClearTimer(1);OnFwd(OUT_C);Float(OUT_A);} else if((SENSOR_1<n)&&(SENSOR_3>n)){ClearTimer(1);OnFwd(OUT_A);Float(OUT_C);} else{while((SENSOR_1<n)||(SENSOR_3<n)){ClearTimer(1);OnRev(OUT_A);OnFwd(OUT_C);}}//光が見つからない時は探す } if(SENSOR_1>(n)){while(SENSOR_1>(n)){OnRev(OUT_A+OUT_C);}} else{while(SENSOR_1<=(n)){OnFwd(OUT_A+OUT_C);}} Off(OUT_A+OUT_C); SetPower(OUT_B,7);OnFwd(OUT_B);Wait(500);Off(OUT_B);//ホイールを射出する } ***工夫したところ [#zd81ce58] 最初から光の域値をviewモードをみて部屋の明かりではぎりぎり届かない値に変えてしまった。こうすることで感度の悪いセンサーでも一応追うことができた。 割とシンプルになってよかった。 ***反省点 [#xb5dfe2d] 30cm以上は近づけないと追ってくれない。はっきりいって致命的だけど、脳がストーミングしすぎた。いか漁に使うような強力なライトをつかえばいけるかもしれない。 **UMEのプログラム (課題1)[#e00ea379] #define THRESHOLD 60 //閾値 task main(){ SetSensor(SENSOR_1,SENSOR_LIGHT); //センサー1光センサー SetSensor(SENSOR_3,SENSOR_LIGHT); //せんさー3光センサー SetPower(OUT_B,7); //セットパワーを最大の7にする OnFwd(OUT_A); OnRev(OUT_C); //右回転 両センサーが強い光を感知したとき while(true){ int light_max=0; //光センサーの最大値 if((SENSOR_1>THRESHOLD)&&(SENSOR_3>THRESHOLD)){ Off(OUT_A+OUT_C); //止まる Wait(50); OnFwd(OUT_B); //ホイールを発射 Wait(20); Off(OUT_B); } センサー3がセンサー1より強い光を感知したとき if(SENSOR_3>SENSOR_1){ OnRev(OUT_A);OnFwd(OUT_C);//左回転 } センサー3が強い光を感知したとき if(SENSOR_3>THRESHOLD){ OnRev(OUT_A);OnFwd(OUT_C);//左回転 } *問題点、工夫した所 [#f772ab2b] ・ANDO とても簡単なプログラムになった。簡単なプログラムだけど、簡単に完成に至った訳ではなかった。時にはせっかく組んだものも思い切って初めから見直すことも必要だと感じた。ロボットは時間がないせいかごちゃごちゃと思いつくがままに組み合わせたようなものなので、キメラみたいな、なんだかまとまりがなくなった。でも連射がかっこいい。 ・UME 今回はホイールの発射に苦労しました。 うまく飛ばず、セットパワーを強くしたところ飛距離を伸ばすことができました。 シンプルなプログラムになってよかった。 *コメント [#fb40bf6a] コメントをどうぞ! - 一人目のプログラムではそのたびに判断することになりますが、if(SENSOR_1>(n)){while(SENSOR_1>(n))のwhile(SENSOR_1>(n)はないほうがすっきりするかもしれません。二人目に関しては自分なりのプログラムを作っているのは良いです。ただ、授業で説明した変数を使って最大値を求めるというプログラムも作ってみてください。(ロボコンがあるので、プログラムだけでよいです)。また、最後のほうの場合わけはもう少しすっきりさせられると思います -- [[FI]] &new{2010-07-30 (金) 22:00:21}; - ロボットの説明もシンプルにまとまっています -- [[TAKA]] &new{2010-08-08 (日) 11:45:15}; #comment