[[2008b/MemberOnly/進行状況A]]
#contents
*課題1:お絵描きロボット [#r9e61532]
**課題内容:お絵描きロボット [#xb071dcb]
A3の紙に相棒の似顔絵を描くロボットを作成せよ。

*ロボットの作成 [#u971828f]
-&size(16){ロボット本体について};
**ロボットにペンを持たせる [#z53de16d]
今回の課題を解決するのに最低限必要な機能
<・ロボット本体とペンを固定する。&Br;
・ロボットが方向転換するときに線を描かないようにするためのペンの上げ下げ機構。
***問題点 [#x79e50a9]
1、ペンをロボットの中心に持って来るのは本体の機構上難しい。&Br;
2、ペンがロボットの中心に無いため、図形を描くときにプログラムで補正をかけないといけない。&Br;
3、モーターとペンホルダーを直結すると力が強すぎて調節が難しい。&Br;
4、サンプルの土台の組み方ではペンホルダーと干渉し、ペンを垂直に保てない。

***解決策 [#y39b75f5]
問題点1の解決策:ペンホルダーを作り本体と連結する。ペンの上げ下げはモーターを使う。&Br;
問題点2の解決策:プログラムで補正をかける。&Br;
問題点3の解決策:ギアを使いペンホルダーの上げ下げのスピードをゆっくりにする。&Br;
&ref(gia.jpg);&Br;
問題点4の解決策:干渉する部分を前方にずらし、干渉しないようにした。&Br;
&ref(body_front_s.jpg);&ref(budy_back_s.jpg);&Br;
-&size(16){プログラムについて};
**基本的な動作 [#y84b59de]
今回ロボットを動かすプログラムを書くために、直進や左右の回転などの基本的な動作は全て関数としてまとめた。&Br;
サブルーチンではなく、関数にした理由は関数を呼び出す際に動作時間を自由に指定するためである。
***前進 [#ta3ba012]
 void go_straight(int t){ //t/100秒前進
	OnFwd(OUT_A);
	OnFwd(OUT_C);
	Wait(t);
	Off(OUT_A+OUT_C);
	Wait(45);
 }
***後退 [#pa50170f]
 void back_straight(int t){ //t/100秒後退
	OnRev(OUT_A);
	OnRev(OUT_C);
	Wait(t);
	Off(OUT_A+OUT_C);
	Wait(45);
 }
***左回転1 [#p221c221]
 void turn_left(int t){ //t/100秒車体の中央を中心として左回転
	OnRev(OUT_A);
	OnFwd(OUT_C);
	Wait(t);
	Off(OUT_A+OUT_C);
	Wait(45); 
 }
***左回転2 [#r119bf16]
 void turn2(int t){ //t/100秒左前輪を中心として左回転
	OnFwd(OUT_C);
	Wait(t);
	Off(OUT_A+OUT_C);
	Wait(45);
 }
***右回転 [#c933c648]
 void turn_right(int t){ //t/100秒車体の中央を中心として右回転
	OnFwd(OUT_A);
	OnRev(OUT_C);
	Wait(t);
	Off(OUT_A+OUT_C);
	Wait(45);
 }
***ペン上げ [#tc20db87]
 void pen_up(){ //ペンを上げる
	OnFwd(OUT_B);
	Wait(90);
	Off(OUT_B);
 }
***ペン下げ [#xbd32041]
 void pen_down(){ //ペンを下げる
	OnRev(OUT_B);
	Wait(90);
	Off(OUT_B);
 }	
**今回描かせたい似顔絵 [#d5da7e2c]
A4右チームは二人とも眼鏡をかけているため、共通部分としてまず&Br;
・顔の輪郭&Br;
・口&Br;
・眼鏡&Br;
の3つのパーツを描かせ、そこから&Br;
・それぞれの顔の特徴&Br;
を描かせ、2つの似顔絵をロボットに描かせることにした。&Br;
&ref(kadai1-nigaoe.jpg);&Br;
↑今回の目標の似顔絵(共通部分)&Br;


***顔の輪郭 [#s2dbef99]
輪郭の円を描く際に関数turn_leftを用いるよりも関数turn2を用いた方が大きい円が描けるため、turn2を用いた。
 void nigaoe_rinkaku(){ 
	turn2(815);
	pen_up();
 }
&ref(kadai1-hontai-en1.jpg);&ref(kadai1-hontai-en2r.jpg);&Br;
左図:関数turn_leftを用いたときに描かれる円 右図:関数turn2を用いたときに描かれる円
***口 [#y0ba0898]
シンプルに直線にした。
 void nigaoe_kuchi(){
	pen_down();
	go_straight(75);
	pen_up();
 }
***眼鏡 [#u830f77e]
&ref(kadai1-nigaoe-megane.jpg);&Br;
上図のような眼鏡を描くための行程は&Br;
&ref(kadai1-nigaoe-megane-koutei1.jpg);
&ref(kadai1-nigaoe-megane-koutei2.jpg);
&ref(kadai1-nigaoe-megane-koutei3.jpg);
&ref(kadai1-nigaoe-megane-koutei4.jpg);&Br;
上のような4つに分けられる。このうち、行程1、3は同じ動作によって実現できるので眼鏡を描く行程を下の3つに分けた。&Br;
 void nigaoe_megane1(){  //行程1、3
	pen_down();
	go_straight(38);
	pen_up();
	go_straight(38);
	pen_down();
	go_straight(38);
	pen_up();
 }

 void nigaoe_megane2(){  //行程2
	pen_down();
	go_straight(25);
	pen_up();
	go_straight(38);
	pen_down();
	go_straight(38);
	pen_up();
	go_straight(38);
	pen_down();
	go_straight(25);
	pen_up();
 }

 void nigaoe_megane3(int len){ //行程4
	pen_down();
	go_straight(len);
	pen_up();
 }

***それぞれの顔の特徴 [#dbb9b47c]
今回、二つの似顔絵を差別化するために&Br;
・鼻&Br;
・髪&Br;
を描く関数を用意し、プログラムでどちらかを呼び出すか指定できるようにした。&Br;
 void nigaoe_tokuchou_hana(int len){  //鼻を描く
        turn_left(220);
        go_straight(190);
        turn_right(160);
        go_straight(175);
        pen_down();
        go_straight(len);
        pen_up();
 }

 void nigaoe_tokuchou_kaminoke(){  //髪を描く
        turn_left(95);
        go_straight(58);
        turn_right(92);
        pen_down();
        go_straight(60);
        pen_up();
        back_straight(60);
        turn_right(40);
        pen_down();
        go_straight(60);
        pen_up();
        back_straight(60);
        turn_left(80);
        pen_down();
        go_straight(60);
        pen_up();
 }

 void nigaoe_tokuchou(int f){  //fの値が0なら鼻、それ以外なら髪を描く
       if(f==0){
            nigaoe_tokuchou_hana(40);
       }else{
            nigaoe_tokuchou_kaminoke();
       }
 }


***メインプログラム [#p227e784]
以上のプログラムは関数であり、これらの関数を呼び出すためのメインプログラムは以下の通り。
 task main(){
	int i;
        nigaoe_rinkaku();
	go_straight(30);
	nigaoe_kuchi(); 
	turn2(204);
	turn_left(95);
	go_straight(155);
	nigaoe_megane1();
	back_straight(139);
	turn_right(95);
	back_straight(5);
	turn_left(95);
	
	nigaoe_megane2();
	
	back_straight(130);
	turn_right(95);
	back_straight(5);
	turn_left(95);
	
	nigaoe_megane1();
	
	back_straight(50);
	turn_right(95);
	go_straight(55);
	
	nigaoe_megane3(25);
	for(i=0;i<3;i++){
		back_straight(30);
		turn_right(101);
		go_straight(38);
		turn_left(100);
		nigaoe_megane3(25);
	}
        
         nigaoe_tokuchou(0); //この例では鼻を描いている
	Off(OUT_A+OUT_C);
	
	
 }
**完成した似顔絵[#hfa33386]
&ref(kansei1.jpg);&ref(kansei2.jpg);&Br;
左図では髪を描き、右図では鼻を描いた。



*まとめ [#ua067378]
**苦労した点・工夫した点[#hfa33386]
ロボットの回転の中心にペンを持ってくることができず、補正するためのプログラムを作るのが大変だった。&Br;
同じプログラムでも動かす度に違う絵が描けることがあり、どう修正していいかわからないときがあった。&Br;
関数を使うことで、わかりやすいプログラムにすることができたと思う。&Br;




*コメント [#rcfab3a8]
何かコメントがありましたらお願いします。&Br;
&Br;
とても丁寧でわかりやすく、いろいろと工夫があるとても良いレポートです。~
ただ、一人につき一つのプログラムが必要なので、もう一つ載せてください。 F.I
- 特にロボットの絵があるところが良いです。この調子でがんばってください。 -- [[なかむら]] &new{2008-11-12 (水) 17:08:07};

#comment

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS