[[2011a]]
*ハードウェア [#sbee2c19]

*ソフトウェア [#y2c68105]
**showのコード [#y9c0a2b6]


定義した動き
 #define turn_left(t) go_straight(10);Wait(30);OnRev(OUT_A);OnFwd(OUT_C);Wait(t);Off(OUT_A+OUT_C);Wait(50);OnRev(OUT_A+OUT_C);Wait(10);Off(OUT_A+OUT_C);Wait(50);//修正をいれ左に曲がる
 #define turn_right(t) go_straight(10);Wait(30);OnFwd(OUT_A);OnRev(OUT_C);Wait(t);Off(OUT_A+OUT_C);Wait(50);OnRev(OUT_A+OUT_C);Wait(10);Off(OUT_A+OUT_C);Wait(50);//修正をいれ右に曲がる
 #define go_straight(t) OnFwd(OUT_A+OUT_C);Wait(t);Off(OUT_A+OUT_C);//まっすぐ進む
 #define A 18//進む距離の目安
 #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);//ペンを下げる

顔を描く動き
task main()
 {
 //face//顔を描く
       go_straight(2*A);//輪郭を描く
       pen_up;
       turn_right(B);//30度右に旋回
       pen_down;
       go_straight(3*A);//輪郭を描く
       pen_up;
       turn_right(B);//30度右に旋回
       pen_down;
       go_straight(2*A);//輪郭を描く
       pen_up;
       turn_left(4*B);
       pen_down;
       go_straight(5*A);//輪郭を描く
       pen_up;
       turn_left(7/3*B);
       pen_down;
       go_straight(7/2*A);//輪郭を描く
       pen_up;
       turn_left(7/3*B);
       pen_down;
       go_straight(7/2*A);//輪郭を描く
       pen_up;
       turn_left(7/3*B);
       pen_down;
       go_straight(11/2*A);//輪郭を描く
       pen_up;
       turn_right(3*B);//90度右に旋回
       pen_down;
 //ear&glass//耳&眼鏡を描く
       go_straight(A);//耳を描く
       pen_up;
       turn_right(3*B);//90度右に旋回
       pen_down;
       go_straight(A);//耳を描く
       pen_up;
       turn_right(3/2*B);//45度右に旋回
       pen_down;
       go_straight(2*A);//耳を描く
       pen_up;
       turn_right(4*B);//120度右に旋回
       go_straight(5/2*A);//左の眼鏡の位置に移動
       turn_left(11/2*B);
       pen_down;
       go_straight(A); //左の眼鏡を描く
       pen_up;      
       turn_right(3*B);//90度右に旋回
       pen_down;
       go_straight(A);//左の眼鏡を描く
       pen_up;
       turn_right(3*B);//90度右に旋回
       pen_down;
       go_straight(A);//左の眼鏡を描く
       pen_up;
       turn_left(3*B);
       go_straight(A);//右の眼鏡の位置に移動
       turn_left(3*B);
       pen_down;
       go_straight(A);//右の眼鏡を描く
       pen_up;
       turn_right(3*B);//90度右に旋回
       pen_down;
       go_straight(A);//右の眼鏡を描く
       pen_up;
       turn_right(3*B);//90度右に旋回
       pen_down;
       go_straight(A);//右の眼鏡を描く
       pen_up;
       turn_left(10/3*B);
       go_straight(2*A);右耳の位置に移動
       turn_right(2*B);//60度右に旋回
       pen_down;
       go_straight(3/2*A);//右耳を描く
       pen_up;
       turn_right(3/2*B);//45度右に旋回
       pen_down;
       go_straight(A);//右耳を描く
       pen_up;
       turn_right(3*B);//90度右に旋回
       pen_down;
       go_straight(A);//右耳を描く
       pen_up;
       go_straight(2*A);髪の位置に移動
       turn_left(3*B);
       pen_down;
 //hair//髪を描く
       go_straight(A);//髪を描く
       pen_up;
       turn_right(3*B);//90度右に旋回
       go_straight(A);//移動
       turn_right(3*B);//90度右に旋回
       pen_down;
       go_straight(A);//髪を描く
       pen_up;
       turn_left(3*B);
       go_straight(A);//移動
       turn_left(3*B);
       pen_down;
       go_straight(A);//髪を描く
       pen_up;
       turn_right(3*B);//90度右に旋回
       go_straight(A);//移動
       turn_right(3*B);//90度右に旋回
       pen_down;
       go_straight(A);//髪を描く
       pen_up;
       go_straight(4*A);//鼻の位置に移動
       turn_right(3*B);//度右に旋回
       go_straight(A);//鼻の位置に移動
       turn_left(3/2*B);
       pen_down;
 //nose&mouth//鼻&口を描く
       go_straight(A);//鼻を描く
       pen_up;
       turn_left(3*B);
       pen_down;
       go_straight(A);//鼻を描く
       pen_up;
       turn_right(3/2*B);//度右に旋回
       go_straight(A);//口の位置に移動
       turn_right(3/2*B);//度右に旋回
       pen_down;
       go_straight(A);//口を描く
}


***解説 [#oa079d78]
まず動きの定義では進む距離の目安を決めることによりその何倍かすることで
直線の長さを表すことができた。また曲がる角度がバラバラなのでひとつの角度の
曲がる時間をはかり、その角度を掛け算や割り算を使い表現することにより
プログラムがより楽になった。初めに距離と曲がる時間を定義することにより
電池消耗で変化する時間を直すのは定義した数字を変えるだけなので
非常に楽だった。

***考察 [#fb29c456]
ロボットが曲がる時のずれがでて、曲がるときは線が繋がらなかった。
それを修正するために、バックなどを取り入れ線のずれを少なくした。
ロボットを作ったりプログラミングなど始めてのことが多く上手く
出来なかった。またあまり時間がかけれなかった。

**hirosのコード [#j39ac7d1]

 #define L 25
 #define NNM 35
 #define NNMn 55
 #define TURN_T 86
 #define PEN_T 5
 #define COR_T 10
 
 void go(int length){
	Wait(50);
	OnFwd(OUT_A);
	OnFwd(OUT_C);
	Wait(length);
	Off(OUT_A+OUT_C);
	Wait(50);
 }
 void back(int length){
	Wait(50);
	OnRev(OUT_C);
	OnRev(OUT_A);
	Wait(length);
	Off(OUT_A+OUT_C);
	Wait(length);
 }
 void tl(int angle){
	penUP();
	go(COR_T);
	OnFwd(OUT_C);
	OnRev(OUT_A);
	Wait(TURN_T*angle/90);
	Off(OUT_A+OUT_C);
	back(COR_T);
	penDOWN();
	correct();
 }
 void tr(int angle){
	penUP();
	go(COR_T);
	OnFwd(OUT_A);
	OnRev(OUT_C);
	Wait(TURN_T*angle/90);
	Off(OUT_A+OUT_C);
	back(COR_T);
	penDOWN();
	correct();
 }
 void penUP(){
	Wait(50);
	OnFwd(OUT_B);
	Wait(PEN_T);
	Off(OUT_B);
 }
 void penDOWN(){
	Wait(50);
	OnRev(OUT_B);
	Wait(PEN_T);
	Off(OUT_B);
 }
 void correct(){
 }
 
 task main()
 {
	//ear
	go(2*L);
	tl(90);
	go(L);
	tl(90);
	go(L);
	tl(45);
	go(NNM);
	
	tr(15);//why???
	
	//jaw
	
	go(NNMn);
	tl(28);
	go(NNM);
	tl(45);
	go(L);
	
	tl(45);
	
	go(NNM);
	tl(20);
	go(NNMn);
	
	tl(30);
	
	//ear
	go(2*L);
	tr(90);
	go(L);
	tr(90);
	go(L);
	tr(45);
	go(NNM);
	
	penUP();
	go(NNM);
	tr(45);
	
	//mouth
	penDOWN();
	go(3*L);
	
	tr(90);
	penUP();
	go(2*L);
	tr(90);
	penDOWN();
	
	//eyes
	go(L);
	penUP();
	go(L);
	penDOWN();
	go(L);
	
 }
***完成品 [#w573ce03]
#ref(110520_1613~01.JPG)

***解説 [#le9e8b5d]
マクロを使い、ハードの変化や調整に対応できるようにした。また、低レベルの操作をまとめて関数を定義しておくことで、main()内の把握をしやすくした。また引数によって調整できるようにしたことで、容易に再利用が可能となり、今後の作業における負担を減らせると考えた。関数で小分けにしたことで、修正をしやすくし生産性をあげたことが時間の節約になった。

具体的には、忘れがちなモータの制御や、回転の際のペンの位置のずれの修正を関数内にまとめ、main()で全体の構成に集中できるように工夫した。マクロは引数チェックが怖かったので定数の置き換えのみに使用した。
電池の残量によって変わる距離や用紙のサイズなどに対応するため、機体の制御にある距離L(時間で表す。マクロ)をおき、それを基準とし比例で距離を表したり、機体の回転を角度で表すことで、結果的に引数をも簡潔にできた。
途中ハードの大幅な変更があったが、なんとか切り抜くことが出来た。
ただ、耳からあごにかけての角度調整で、tl()を使うはずなのに、どうしてなのかtr()でないと期待した動作が得られなかった。

***考察 [#gfc664a5]
モータを制御する関数をどれほど汎用なものにするか、ということに悩んだ。
void motor(MOTOR m; int length);や、turn(LR lr; int angle);といったようなものも考えたが、これだと低レベルの操作と何も変わらない/わかりにくいので今のコーディングでいいと考えた。
NQCにdoubleが備わっていないということで、小数点の計算が出来ず、精度の悪い回転となってしまった。
また、今回main()内をサブルーチンで整理しなかったのは、次の動きが前の動きによる位置に依存するので、逆にわかりにくいと考えたためである。
今回の課題に十分な時間をかけられなかったことが残念であり、今回の最大の反省点である。

**感想 [#e287b0d6]

***hiros [#u5cea58b]
ハードウェアがあらかじめ完成しているケースでは、ソフトの改良に努めるだけ?だが、今回はハードも自分でデザインすることが出来、そのことが生むたくさんの選択肢(手段)の、どれを選ぶかで悩んだ。作業自体はパズルのようで非常に楽しく、いつかMindstreamのようなおもちゃを自作してみたいという新たな目標が出来た。

***show [#p5fe693e]
今回始めてということで楽しかったけれど、最後の方は思いどおりにいかなく
つらかった。けどパートナーはこのロボットに対しての知識が多く
いろんなことを教えてもらい非常に助かった。もう少し上手くやりたかった。
次の課題は早めから取り組み頑張りたいです。

- NQC自体はdoubleを扱うことができませんが、ギア比を工夫して動作のスピードを遅くすることで、1/100秒の制御でも十分精度のよい動作をさせることができます。 -- [[松本]] &new{2011-05-16 (月) 23:40:24};
- 工夫が足りませんでした。もう少し改良したいと思います。 -- [[hiros]] &new{2011-05-19 (木) 23:01:19};

#comment

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS