*課題1 〜似顔絵を描くロボット〜 [#jae8dd54] 目次 #contents **ロボット本体 [#l761666e] ***・ロボットの特徴 [#h3273336] 1.ペンの上げ下げをするのに4つの細い車輪を使っているところ 2.前の方に重心おきキャスターにあまり負荷をかけないようにしている 3.左右対称に設計し、左右の旋回をなるべく動きが同じように動かすことができる 3.左右対称に設計し、左右の旋回の動きが同じように動かすことができる &ref(2012a/A3/Hexa/M1/DSC_0042.JPG,30%,車体); ***・工夫した点 [#o1a01c9c] 1.車体の車軸の中心にペン先がくるようにする &ref(2012a/A3/Hexa/M1/ura.jpg,30%,車体裏); 上の写真のように車軸上に丸で囲ったペンを持つところに持っていき車軸上にペン先設置ことにより旋回しても前の書いた位置からずれないようにした。 2.ペン先のブレをなくす &ref(2012a/A3/Hexa/M1/yoko.jpg,30%,車体横); 上の写真はロボットが似顔絵を書き終わった時の状態である。この時のペンの状態が赤い線とずれていてペン先が車軸上からずれてしまっている。これを改善するためにおこなったのが次の写真である。 &ref(2012a/A3/Hexa/M1/sasae.jpg,30%,支え); このように、2本の棒で支えることによってペンが動かないようにしてペン先がぶれないようにしている。 ***・失敗した点 [#o0dfa239] ・ペン先が中心軸からずれている &ref(2012a/A3/Hexa/M1/ura2.jpg,30%,車体裏2); 上の写真のように中心軸が左にずれています。中心軸からずれてまうと旋回した時に前に描いた位置からずれてしまいます。何度か車体を改造して中心に持っていこうとしようとしましたができなかったのでプログラムで調整しました。 **プログラム [#m319ead6] ***方針 [#r3cfefa2] すべての部分を直線で表現すること、またロボットがなるべく紙の上にいるように小さく書き紙を動かないようにする。 手順としては、輪郭→目→鼻→口の順番で描く。 予定としては下の通りになる。 &ref(2012a/A3/Hexa/M1/housin.jpg,70%,方針); ***結果 [#k073e75f] &ref(2012a/A3/Hexa/M1/kekka.JPG,30%,結果); 全体的に小さくなってしまった。顔の部品が斜めになっているのは、旋回時に紙がゆがんでしまって旋回角度がずれてしまったためである。 ***ソース [#pf2879fe] /*-------------------------------------------- 似顔絵描きロボット ekaki.nxc ---------------------------------------------*/ /*-------------------------------------------- 定数 ---------------------------------------------*/ #define PAI 3 //円周率 #define T_R 55 //タイヤの直径(mm) #define T_D 131 //車体のトレッド(mm) #define DUTY 40 #define FF 1 //前進 #define FR 2 //右旋回 #define RF 3 //左旋回 #define RR 4 //後進 #define BB 5 //ブレーキ #define UP 30 //ペンを上げる #define DOWN 31 //ペンを下げる /*-------------------------------------------- 関数プロトタイプ宣言 ---------------------------------------------*/ void pen_ct(int up_or_down); void mt_ct(int mt_ct,int ang_d); void rinkaku(); void eye(); void mouth(); void nose(); /*-------------------------------------------- グローバル変数 ---------------------------------------------*/ /*-------------------------------------------- メインルーチン ---------------------------------------------*/ task main() { rinkaku(); //輪郭 eye(); //目 nose(); //鼻 mouth(); //口 } /*-------------------------------------------- サブルーチン ---------------------------------------------*/ void nose() { pen_ct(UP); //ペンを上げる mt_ct(FF,8); //前進 mt_ct(FR,90); //90度旋回 mt_ct(FF,10); //前進 mt_ct(FR,90); //90度旋回 mt_ct(FF,25); //前進 mt_ct(RF,90); //90度旋回 pen_ct(DOWN); //ペンを下げる mt_ct(FF,5); //前進 pen_ct(UP); //ペンを上げる mt_ct(RR,10); //誤差調整 mt_ct(RF,90); //90度旋回 pen_ct(DOWN); //ペンを下げる mt_ct(FF,5); //前進 } //口 void mouth() { pen_ct(UP); //ペンを上げる mt_ct(FF,8); //前進 mt_ct(FR,90); //90度旋回 mt_ct(FF,5); //前進 mt_ct(FR,90); //90度旋回 mt_ct(FF,20); //前進 pen_ct(DOWN); //ペンを下げる mt_ct(FF,10); //前進 } //目 void eye() { pen_ct(UP); //ペンを上げる mt_ct(RF,90); //90度旋回 mt_ct(FF,7); //前進 pen_ct(DOWN); //ペンを下げる mt_ct(FF,7); //前進 pen_ct(UP); //ペンを上げる mt_ct(FF,5); //前進 pen_ct(DOWN); //ペンを下げる mt_ct(FF,7); //前進 } //輪郭 void rinkaku() { mt_ct(FF,50); //前進 mt_ct(RR,10); //誤差調整 pen_ct(UP); //ペンを上げる mt_ct(RF,90); //45度左旋回 pen_ct(DOWN); //ペンを下げる mt_ct(FF,50); //前進 mt_ct(RR,10); //誤差調整 pen_ct(UP); //ペンを上げる mt_ct(RF,90); //90度左旋回 pen_ct(DOWN); //ペンを下げる mt_ct(FF,50); //前進 mt_ct(RR,10); //誤差調整 pen_ct(UP); //ペンを上げる mt_ct(RF,90); //45度左旋回 pen_ct(DOWN); //ペンを下げる mt_ct(FF,50); //前進 mt_ct(RR,10); //誤差調整 pen_ct(UP); //ペンを上げる mt_ct(RF,90); //45度左旋回 pen_ct(DOWN); //ペンを下げる } /* 進む距離回転する角度計算用関数 */ //第一引数:タイヤの回転方向,第2引数:進む距離 or 回転角 void mt_ct(int mt_ct,int ang_d) { int r,d,g,mt; int iNum1=0,iNum2=0; r = T_R * PAI; //タイヤの円周 // 進む距離計算 if(mt_ct == FR || mt_ct == RF){ d = T_D * PAI * ang_d / 360; } else{ d = ang_d; } mt = 360 * d / r; //進む距離からパルス数計算 switch(mt_ct){ case FF: //前進 OnFwdSyncEx(OUT_AC,DUTY,0,RESET_ALL); break; case FR: //右旋回 OnFwdSyncEx(OUT_AC,DUTY,100,RESET_ALL); break; case RF: //左旋回 OnFwdSyncEx(OUT_AC,DUTY,-100,RESET_ALL); break; case RR: //後進 OnRevSyncEx(OUT_AC,DUTY,0,RESET_ALL); break; case BB: //ブレーキ Off(OUT_AC); break; default: Off(OUT_AC); break; } while(abs(iNum1) < mt || abs(iNum2) < mt){ //左右のパルス数が目標値になるまで待つ iNum1 = MotorTachoCount(OUT_A); iNum2 = MotorTachoCount(OUT_C); NumOut(0,LCD_LINE1,iNum1); NumOut(0,LCD_LINE2,iNum2); } Off(OUT_AC); //両輪停止 Wait(500); //500ms待つ ResetScreen(); //LCDクリア Wait(100); //100ms待つ } /* ペン上げ下げ用関数 */ //引数:UP or DOWN void pen_ct(int up_or_down) { int iNum1=0; if(up_or_down == UP){ OnFwdEx(OUT_B,50,RESET_ALL); } else{ OnFwdEx(OUT_B,-50,RESET_ALL); } while(abs(iNum1) < up_or_down){ iNum1 = MotorTachoCount(OUT_B); } Off(OUT_B); Wait(100); } **反省・感想 [#va4efdbd] -電池を変えても旋回角度が変わらないようにタコメータを使用して回転角や進む距離を制御しようとしたが、場所によって旋回角度が変わってしまったりして調整が必要でした。 -1つのタイヤが紙の外に出てしまうと旋回時に紙が動いてしまうので、なるべく紙の上にロボットが来るようにしようとしたら、顔が小さくなってしまった。 -ロボットを組み立てる点で、車軸上にペン先を持っていこうとしたため、車体が大きくなってしまったので次回の課題では、車体の大きさも考えていきたい。