[[2011a]] *ハードウェア [#sbee2c19] *ソフトウェア [#y2c68105] **showのコード [#y9c0a2b6] 定義した動き #define turn_left(t) OnRev(OUT_A);OnFwd(OUT_C);Wait(t);Off(OUT_A+OUT_C);//左に曲がる #define turn_right(t) OnFwd(OUT_A);OnRev(OUT_C);Wait(t);Off(OUT_A+OUT_C);//右に曲がる #define go_straight(t) OnFwd(OUT_A+OUT_C);Wait(t);Off(OUT_A+OUT_C);//まっすぐ進む #define A 20//進む距離の目安 #define B 29//30度曲がる時間 #define pen_up OnFwd(OUT_B);Wait(5);Off(OUT_B);//ペンを上げる #define pen_down OnRev(OUT_B);Wait(5);Off(OUT_B);//ペンを下げる 顔を描く動き ***解説 [#oa079d78] まず動きの定義では進む距離の目安を決めることによりその何倍かすることで 直線の長さを表すことができた。また曲がる角度がバラバラなのでひとつの角度の 曲がる時間をはかり、その角度を掛け算や割り算を使い表現することにより プログラムがより楽になった。初めに距離と曲がる時間を定義することにより 電池消耗で変化する時間を直すのは定義した数字を変えるだけなので 非常に楽だった。 ***考察 [#fb29c456] ロボットが曲がる時のずれがでて、曲がるときは線が繋がらなかった。 ロボットを作ったりプログラミングなど始めてのことが多く上手く 出来なかった。またあまり時間がかけれなかった。 **hirosのコード [#j39ac7d1] マクロと関数定義 #define L 100 #define NNM 35 #define NNMn 50 #define TURN_T 115 #define PEN_T 5 #define COR_T 10 void go_straight(int length){ OnFwd(OUT_A); OnFwd(OUT_C); Wait(length); Off(OUT_A+OUT_C); } void turn_right(int angle){ penUP(); OnFwd(OUT_A); OnRev(OUT_C); Wait(TURN_T*angle/90); Off(OUT_A+OUT_C); correct(); } void turn_left(int angle){ penUP(); OnFwd(OUT_A); OnRev(OUT_C); Wait(TURN_T*angle/90); Off(OUT_A+OUT_C); correct(); } void penUP(){ OnRev(OUT_B); Wait(PEN_T); Off(OUT_B); } void penDOWN(){ OnFwd(OUT_B); Wait(PEN_T); Off(OUT_B); } void correct(){ OnRev(OUT_A); OnRev(OUT_C); Wait(COR_T); Off(OUT_A+OUT_C); penDOWN(); } main関数 task main () { //hair go_straight(NNMn); turn_left(90); go_straight(NNM * 2); turn_right(90); go_straight(NNM); turn_left(90); go_straight(NNM); //head go_straight(L); turn_right(90+45); go_straight(NNM); turn_right(45); go_straight(L/2); turn_right(90); go_straight(L/4); turn_right(90); go_straight(L*3/4); turn_left(45); go_straight(NNM * 2); turn_left(45); go_straight(L/4); turn_left(45); go_straight(NNM * 3); turn_left(45); go_straight(L/2); turn_left(90); go_straight(L/4); turn_left(90); go_straight(L*3/4); turn_right(180); go_straight(L*3/4); //eyes turn_left(45); go_straight(NNM); turn_left(45); go_straight(NNM); turn_left(45); //eye1 repeat(4){ go_straight(L/4); turn_left(90); } turn_right(90); penUP(); go_straight(L/4); penDOWN(); //eye2 repeat(4){ go_straight(L/4); turn_left(90); } turn_right(45); go_straight(NNM); turn_left(90); go_straight(NNM); //mouth turn_left(45); go_straight(L*3/4); penUP(); go_straight(L/4); penDOWN(); go_straight(L*3/4); } ***解説 [#le9e8b5d] マクロを使い、ハードの変化や調整に対応できるようにした。また、低レベルの操作をまとめて関数を定義しておくことで、main()内の把握をしやすくした。また引数によって調整できるようにしたことで、容易に再利用が可能となり、今後の作業における負担を減らせると考えた。関数で小分けにしたことで、修正をしやすくし生産性をあげたことが時間の節約になった。 具体的には、忘れがちなモータの制御や、回転の際のペンの位置のずれの修正を関数内にまとめ、main()で全体の構成に集中できるように工夫した。マクロは引数チェックが怖かったので定数の置き換えのみに使用した。 電池の残量によって変わる距離などに対応するため、機体の制御にある距離L(時間で表す。マクロ)をおき、それを基準とし比例で距離を表したり、機体の回転を角度で表すことで、結果的に引数をも簡潔にできた。 途中ハードの大幅な変更があったが、なんとか切り抜くことが出来た。 ***考察 [#gfc664a5] モータを制御する関数をどれほど汎用なものにするか、ということに悩んだ。 void motor(MOTOR m; int length);や、turn(LR lr; int angle);といったようなものも考えたが、これだと低レベルの操作と何も変わらない/わかりにくいので今のコーディングでいいと考えた。 NQCにdoubleが備わっていないということで、小数点の計算が出来ず、精度の悪い回転となってしまった。 また、今回main()内をサブルーチンで整理しなかったのは、次の動きが前の動きによる位置に依存するので、逆にわかりにくいと考えたためである。 今回の課題に十分な時間をかけられなかったことが残念であり、今回の最大の反省点である。 **感想 [#e287b0d6] ***hiros [#u5cea58b] ***show [#p5fe693e] 今回始めてということで楽しかったけれど、最後の方は思いどおりにいかなく つらかった。けどパートナーはこのロボットに対しての知識が多く いろんなことを教えてもらい非常に助かった。もう少し上手くやりたかった。 次の課題は早めから取り組み頑張りたいです。 - NQC自体はdoubleを扱うことができませんが、ギア比を工夫して動作のスピードを遅くすることで、1/100秒の制御でも十分精度のよい動作をさせることができます。 -- [[松本]] &new{2011-05-16 (月) 23:40:24}; - 工夫が足りませんでした。もう少し改良したいと思います。 -- [[hiros]] &new{2011-05-19 (木) 23:01:19}; #comment