[[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; &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(); } ***メインプログラム [#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(45); turn_right(95); go_straight(55); nigaoe_megane3(25); for(i=0;i<3;i++){ back_straight(27); turn_right(96); go_straight(40); turn_left(96); nigaoe_megane3(25); } Off(OUT_A+OUT_C); } **苦労した点・工夫した点[#hfa33386] ロボットの回転の中心にペンを持ってくることができず、補正するためのプログラムを作るのが大変だった。&Br; 同じプログラムでも動かす度に違う絵が描けることがあり、どう修正していいかわからないときがあった。 *まとめ [#ua067378]