[[2012a/Member]] [[2012a/A4]] [[2012a/A4/Tnakano]] 目次 #contents *課題1 似顔絵を描くロボット [#t363be1f] -パートナーの似顔絵を描くロボットを作成する。 ***ルール [#ie6d3ba5] -ひとりにつき一つ以上のプログラムを作成すること。 -ペン以外はキットに含まれる部品を使うこと。 -A4の紙はセロテープ等で固定しないこと -キットに付属の高価な輪ゴムは切れやすいので切れないように細心の注意を払うこと。 -改良や調整をしやすくするため、ロボット本体だけでなく、プログラムについても可能な部分についてはサブルーチンや関数、マクロなどを使って部品に分けること。 **ロボット本体について [#g5e0862e] 今回作成したロボットは前輪2つ、後輪が1つで、前輪2つにモータを取り付け2輪駆動で動くロボットです。ペンは前輪2つの中心あたりに取り付け、モータにより上下に動かせるようにしました。ペンは紙に対して垂直にするより斜めにしたほうが抵抗が少なくなると思ったので、紙にペンを下した時に斜めになるようにしました。また、ロボット全体を小さく作り、小回りが利くようにしました。 #ref(kadai1_r_01.jpg,left,nowrap,全体の画像) **プログラムについて [#e5f9c62c] パートナーが眼鏡をかけていたので、そこをうまく表現できるようにしたいと思いました。図の順番に描いていきました。 #ref(kadai1_r_04.png,left,nowrap,完成予想図) ***工夫した点 [#sa2b97cd] -フロントターンとバックターンを用意し、使い分けることで、細かい場所の調整を行いました。 -ペンを上げる時のパワーと下げる時のパワーを同じにしてしまうと、ペンがだんだん下がってきて、上まで上がらなくなってしまったので、上げる時のパワーを下げる時より強くすることで、ペンをいつも同じ位置まで持ってきて描けるようにしました。 -似顔絵の精度を上げるために駆動輪への出力は、「OnFwd();」ではなく、「RotateMotor();」を使いタイヤの角度で制御しました。 -駆動輪を紙の外まで動かしてしまうと、紙全体が動いてしまい、ずれてしまうので、駆動輪が紙から出ないようにプログラムしました。 ***プログラムリスト [#v46f5d98] /****************************************************************/ /* nxtプログラム kadai1.似顔絵 */ /****************************************************************/ //定義文 #define turn90 350 //回転角度90度 #define turn45 175 //回転角度45度 //バックターン 右 void bturn_r(int i){ //引数i 戻り値なし Float(OUT_BC); //モータBCフリー RotateMotor(OUT_B,-50,i); //モータBをi度逆転 Wait(200); //0.2秒待機 Off(OUT_BC); //モータBCストップ Wait(200); //0.2秒待機 } //バックターン 左 void bturn_l(int i){ //引数i 戻り値なし Float(OUT_BC); //モータBCフリー RotateMotor(OUT_C,-50,i); //モータCをi度逆転 Wait(200); //0.2秒待機 Off(OUT_BC); //モータBCストップ Wait(200); //0.2秒待機 } //フロントターン 左 void fturn_l(int i){ //引数i 戻り値なし Float(OUT_BC); //モータBCフリー RotateMotor(OUT_B,50,i); //モータBをi度正転 Wait(200); //0.2秒待機 Off(OUT_BC); //モータBCストップ Wait(200); //0.2秒待機 } //フロントターン 右 void fturn_r(int i){ //引数i 戻り値なし Float(OUT_BC); //モータBCフリー RotateMotor(OUT_C,50,i); //モータCをi度正転 Wait(200); //0.2秒待機 Off(OUT_BC); //モータBCストップ Wait(200); //0.2秒待機 } //直進 void go(int i){ //引数i 戻り値なし Float(OUT_BC); //モータBCフリー OnFwd(OUT_BC,20); //モータBC20%で正転 Wait(200); //0.2秒待機 RotateMotor(OUT_BC,50,i); //モータBCをi度正転 Wait(200); //0.2秒待機 Float(OUT_BC); //モータBCフリー Wait(200); //0.2秒待機 } //バック void back(int i){ //引数i 戻り値なし Float(OUT_BC); //モータBCフリー OnRev(OUT_BC,20); //モータBC20%で逆転 Wait(200); //0.2秒待機 RotateMotor(OUT_BC,-50,i); //モータBCをi度逆転 Wait(200); //0.2秒待機 Float(OUT_BC); //モータBCフリー Wait(200); //0.2秒待機 } //ペン上げ void up(void){ //引数なし 戻り値なし Wait(200); //0.2秒待機 OnRev(OUT_A,30); //モータA30%で逆転 Wait(400); //0.4秒待機 Off(OUT_A); //モータAストップ Wait(200); //0.2秒待機 } //ペン下げ void down(void){ //引数なし 戻り値なし Wait(200); //0.2秒待機 OnFwd(OUT_A,20); //モータA20%で正転 Wait(400); //0.4秒待機 Off(OUT_A); //モータAストップ Wait(200); //0.2秒待機 } //顔 輪郭 void rinkaku(void){ //引数なし 戻り値なし int i; //整数符号あり変数iの宣言 for(i=0;i<=1;i++){ //2回繰り返し down(); //ペン下げ go(70); //直進 up(); //ペン上げ go(140); //直進 bturn_l(turn45); //バックターン左45度 back(45); //バック } down(); //ペン下げ go(35); //直進 up(); //ペン上げ go(140); //直進 bturn_l(turn45); //バックターン左45度 back(45); //バック for(i=0;i<=1;i++){ //2回繰り返し down(); //ペン下げ go(70); //直進 up(); //ペン上げ go(140); //直進 bturn_l(turn45); //バックターン左45度 back(45); //バック } } //顔 口 void kuti(void){ //引数なし 戻り値なし bturn_l(turn45); //バックターン左45度 go(120); //直進 down(); //ペン下げ go(30); //直進 up(); //ペン上げ } //顔 髪 中 左 void kami_cl(void){ //引数なし 戻り値なし back(5); //バック fturn_r(turn90); //フロントターン右90度 back(5); //バック down(); //ペン下げ back(15); //バック up(); //ペン上げ } //眼鏡 中 左 void megane_cl(void){ //引数なし 戻り値なし back(30); //バック down(); //ペン下げ back(15); //バック up(); //ペン上げ } //眼鏡 下 void megane_u(void){ //引数なし 戻り値なし back(5); //バック fturn_l(turn90); //フロントターン左90度 back(135); //バック down(); //ペン下げ back(15); //バック up(); //ペン上げ back(40); //バック down(); //ペン下げ back(15); //バック up(); //ペン上げ } //眼鏡 右 void megane_r(void){ //引数なし 戻り値なし back(5); //バック fturn_r(turn90); //フロントターン右90度 back(150); //バック down(); //ペン下げ back(15); //バック up(); //ペン上げ } //眼鏡 上 void megane_a(void){ //引数なし 戻り値なし go(250); //直進 bturn_l(turn90); //バックターン左90度 down(); //ペン下げ go(160); //直進 up(); //ペン上げ } //眼鏡 左 void megane_l(void){ //引数なし 戻り値なし back(5); //バック fturn_r(turn90); //フロントターン右90度 back(200); //バック down(); //ペン下げ back(10); //バック up(); //ペン上げ } //眼鏡 中 右 void megane_cr(void){ //引数なし 戻り値なし go(90); //直進 bturn_l(turn90); //バックターン左90度 back(85); //バック fturn_r(turn90); //フロントターン右90度 back(85); //バック down(); //ペン下げ go(25); //直進 up(); //ペン上げ } //眼鏡 void megane(void){ //引数なし 戻り値なし megane_cl(); //眼鏡 中 左 megane_u(); //眼鏡 下 megane_r(); //眼鏡 右 megane_a(); //眼鏡 上 megane_l(); //眼鏡 左 megane_cr(); //眼鏡 中 右 } //顔 髪 中 右 void kami_cr(void){ //引数なし 戻り値なし go(20); //直進 down(); //ペン下げ go(25); //直進 up(); //ペン上げ } //顔 髪 右 void kami_r(void){ //引数なし 戻り値なし back(30); //バック fturn_r(turn45); //フロントターン右90度 back(20); //バック down(); //ペン下げ back(20); //バック up(); //ペン上げ } //顔 髪 左 void kami_l(void){ //引数なし 戻り値なし back(150); //バック fturn_l(turn90); //フロントターン左90度 back(25); //バック down(); //ペン下げ back(20); //バック up(); //ペン上げ } //メイン関数 task main(void){ //引数なし 戻り値なし rinkaku(); //輪郭線 kuti(); //口 kami_cl(); //髪 中 左 megane(); //眼鏡 kami_cr(); //髪 中 右 kami_r(); //髪 右 kami_l(); //髪 左 } **完成品 [#fd8eef5b] 少し左に傾いてしまいましたが、何とか描くことができました。 #ref(kadai1_r_03.jpg,left,nowrap,完成写真) **反省・感想 [#f991bbca] 今回始めてNXTのロボットの組み立て、プログラミングを行いました。ロボットの組み立てでは、構造をシンプルにしたことで、ペン先を合わせたりする時、小回りが利きプログラミングしやすくなりました。しかしプログラムの終盤になってくると、それまでの歪みが影響して顔のパーツがずれてしまうことがあり、その都度調整していたのでかなり時間がかかってしまいました。今後はハードウェアの設計をしっかりと行い、できるだけ簡単にプログラムの調整ができるようにしたいと思いました。実際のプログラミングの時は、よく使う直進、バック、ターン、ペンの上げ下げを先に関数化し、似顔絵全体の見通しが立ってきたら、顔のそれぞれのパーツごとに関数化し、プログラムの調整をしやすいようにしました。そうすることで、メイン関数の中をかなり簡略化することができました。次回は、今回学んだことや反省点を活かし、ロボットを自分の思い通りに動かせるように、作成していきたいと思いました。