[[2008a/MemberOnly/進行状況A]]
#contents
* 課題1 お絵かきロボット [#j380847a]
ロボットにペンを持たせて、相棒の似顔絵を描かせるプログラムを作成する。
**ロボット本体 [#qbe7bb47]
ロボット本体は基本のドライブベースを使用しました。
***ロボにペンを持たせる [#e57de92b]
最初はペンをロボットの正面にワイパーのように付けていましたが、それだと~
・ペンをうまく固定できない。~
・ペンを紙につける時に余計な線ができてしまう。~
という問題があったので~
#ref(全体像.jpg)~
のように横に持たせる形に変更しました。~
固定している部分は、軸を使い補強してあります。
#ref(橋渡し.jpg)
#ref(横から.jpg)
#ref(前から.jpg)
~
また持たせるペンは最初軽さ重視でシャープペン・鉛筆を使っていましたが、それでは筆圧をかけることが難しいため、筆圧が必要ないマジックペンを使用することにしました。
**プログラム [#z6ea1388]
***ふじのプログラム [#t306f4ae]
元の似顔絵を [輪郭][右の前髪][左の前髪][頭][目][口]の6つの部分に分け、前の部分を書き終えた後、次の部分へ移動しその部分を書いていく形にしました。
#define PEN_TIME 18 //ペンを上げ下げする時間はすべて同じなので関数で固定。
task main()
#br
輪郭のイメージ
#ref(輪郭.jpg)
{ OnFwd(OUT_B); //ペンを置く
Wait(15);
Off(OUT_B);
OnFwd(OUT_A+OUT_C); //輪郭部分開始
Wait(130);
Off(OUT_C);
repeat(350)
{ OnFwd(OUT_A);
Wait(7/6);
OnFwd(OUT_C);
Wait(1/4);
Off(OUT_A+OUT_C);
}
//ペンを上げたところに置くための調整
OnRev(OUT_B); //ペンを上げる
Wait(PEN_TIME);
Off(OUT_B);
OnFwd(OUT_A+OUT_C); //位置調整のため前進
Wait(80);
Off(OUT_A+OUT_C);
OnFwd(OUT_A); //向き変更
OnRev(OUT_C);
Wait(30);
Off(OUT_A+OUT_C);
OnRev(OUT_A+OUT_C); //位置調整のため前進
Wait(60);
Off(OUT_A+OUT_C);
OnFwd(OUT_B); //ペンを置く
Wait(PEN_TIME);
Off(OUT_B);
OnFwd(OUT_A+OUT_C);
Wait(80);
Off(OUT_A+OUT_C); //輪郭部分終了
OnRev(OUT_B); //ペンを上げる
Wait(PEN_TIME);
Off(OUT_B);
#br
OnFwd(OUT_A+OUT_C); //位置調整のため前進
Wait(50);
Off(OUT_A+OUT_C);
OnFwd(OUT_A); //向き変更
OnRev(OUT_C);
Wait(20);
Off(OUT_A+OUT_C);
OnFwd(OUT_A+OUT_C); //位置調整のため前進
Wait(120);
Off(OUT_A+OUT_C);
#br
右の前髪のイメージ
#ref(右の前髪.jpg)
OnFwd(OUT_B); //ペンを置く
Wait(PEN_TIME);
Off(OUT_B);
repeat (30){ //右の前髪部分開始
OnRev(OUT_A+OUT_C);
Wait(3);
Off(OUT_A);
Wait(1);
}
Off(OUT_C);
OnRev(OUT_B); //ペンを上げる
Wait(PEN_TIME);
Off(OUT_B);
#br
repeat (30){ //右の前髪開始位置に戻る
OnFwd(OUT_A+OUT_C);
Wait(3);
Off(OUT_A);
Wait(1);}
Off(OUT_C);
OnFwd(OUT_A+OUT_C); //位置調整のため前進
Wait(60);
Off(OUT_A+OUT_C);
OnFwd(OUT_A); //向き変更
OnRev(OUT_C);
Wait(115);
Off(OUT_A+OUT_C);
OnFwd(OUT_A+OUT_C); //位置調整のため前進
Wait(40);
Off(OUT_A+OUT_C);
#br
左の前髪のイメージ
#ref(左の前髪.jpg)
OnFwd(OUT_B); //ペンを置く
Wait(PEN_TIME);
Off(OUT_B);
repeat(25){ //左の前髪部分開始
OnFwd(OUT_A+OUT_C);
Wait(3);
Off(OUT_A);
Wait(1); }
Off(OUT_C); //左の前髪部分終了
OnRev(OUT_B); //ペンを上げる
Wait(PEN_TIME);
Off(OUT_B);
#br
OnFwd(OUT_A+OUT_C); //位置調整のため前進
Wait(100);
Off(OUT_A+OUT_C);
OnFwd(OUT_A); //向き変更
OnRev(OUT_C);
Wait(80);
Off(OUT_A+OUT_C);
OnFwd(OUT_A+OUT_C); //位置調整のため前進
Wait(100);
Off(OUT_A+OUT_C);
#br
頭部のイメージ
#ref(頭.jpg)
OnFwd(OUT_B); //ペンを置く
Wait(PEN_TIME);
Off(OUT_B);
OnRev(OUT_A+OUT_C); //頭部開始
Wait(70);
Off(OUT_A+OUT_C);
repeat(370){
OnRev(OUT_A);
Wait(1);
OnRev(OUT_C);
Wait(3/2);
Off(OUT_A+OUT_C); }
repeat(80){
OnRev(OUT_A+OUT_C);
Wait(2);
Off(OUT_C);
Wait(3);
Off(OUT_A); }
Off(OUT_A);
OnRev(OUT_A+OUT_C);
Wait(40);
Off(OUT_A+OUT_C);
OnRev(OUT_B); //ペンを上げる
Wait(PEN_TIME);
Off(OUT_B);
#br
OnFwd(OUT_A+OUT_C); //位置調整のため前進
Wait(190);
Off(OUT_A+OUT_C);
OnFwd(OUT_A); // 向き変更
OnRev(OUT_C);
Wait(110);
Off(OUT_A+OUT_C);
OnFwd(OUT_A+OUT_C); //位置調整のため前進
Wait (180);
Off(OUT_A+OUT_C);
OnFwd(OUT_A); //向き変更
OnRev(OUT_C);
Wait(50);
Off(OUT_A+OUT_C);
OnFwd(OUT_A+OUT_C); //位置調整のため前進
Wait(20);
Off(OUT_A+OUT_C);
#br
目のイメージ
#ref(目.jpg)
OnFwd(OUT_B); //ペンを置く
Wait(PEN_TIME);
Off(OUT_B);
OnFwd(OUT_A+OUT_C); //右目
Wait(40);
Off(OUT_A+OUT_C);
OnRev(OUT_B); //ペンを上げる
Wait(PEN_TIME);
Off(OUT_B);
OnFwd(OUT_A+OUT_C); // 位置調整のため前進
Wait(40);
Off(OUT_A+OUT_C);
OnFwd(OUT_B); //ペンを置く
Wait(PEN_TIME);
Off(OUT_B);
OnFwd(OUT_A+OUT_C); //左目
Wait(40);
Off(OUT_A+OUT_C);
OnRev(OUT_B); //ペンを上げる
Wait(PEN_TIME);
Off(OUT_B);
#br
OnFwd(OUT_A); // 向き変更
OnRev(OUT_C);
Wait(100);
Off(OUT_A+OUT_C);
OnFwd(OUT_A+OUT_C); //位置調整のため前進
Wait(130);
Off(OUT_A+OUT_C);
#br
口のイメージ
#ref(口.jpg)
OnFwd(OUT_B); //ペンを置く
Wait(PEN_TIME);
Off(OUT_B);
OnFwd(OUT_C); // 口
OnRev(OUT_A);
Wait(80);
Off(OUT_A+OUT_C);
OnRev(OUT_B); //ペンを上げる
Wait(PEN_TIME);
Off(OUT_B);
}
#br
***りぃのプログラム [#i899ff42]
似顔絵を[輪郭][眼鏡][髪]の3つの部分に分けました。
簡単にするために回転をすべて90°にしました。
90°の回転はその場で回転させるだけではペン先の位置が変わってしまうので、回転の前後に前進(または後退)させてペン先の位置が変わらないようにしました。
90°右回転
OnRev(OUT_B);//ペンを上げる
Wait(15);
Off(OUT_B);
OnFwd(OUT_A+OUT_C);//位置調整
Wait(115);
Off(OUT_A+OUT_C);
OnFwd(OUT_A);//90°回転
OnRev(OUT_C);
Wait(107);
Off(OUT_A+OUT_C);
OnFwd(OUT_A+OUT_C);//位置調整
Wait(45);
Off(OUT_A+OUT_C);
OnFwd(OUT_B);//ペンを下げる
Wait(15);
Off(OUT_B);
90°左回転
OnRev(OUT_B);//ペンを上げる
Wait(15);
Off(OUT_B);
OnRev(OUT_A+OUT_C);//位置調整
Wait(35);
Off(OUT_A+OUT_C);
OnFwd(OUT_C);//90°回転
OnRev(OUT_A);
Wait(108);
Off(OUT_A+OUT_C);
OnRev(OUT_A+OUT_C);//位置調整
Wait(110);
Off(OUT_A+OUT_C);
OnFwd(OUT_B);//ペンを下げる
Wait(15);
Off(OUT_B);
90°右回転を「turn_right」、左回転を「turn_left」とサブルーチンで定義しました。
完成したプログラムは以下のものです。
task main()
{
OnFwd(OUT_C);//輪郭
Wait(820);
Off(OUT_C);
turn_left();
OnFwd(OUT_A+OUT_C);//眼鏡
Wait(100);
Off(OUT_A+OUT_C);
repeat(3){
turn_left();
OnFwd(OUT_A+OUT_C);
Wait(40);
Off(OUT_A+OUT_C);
}
turn_left();
OnFwd(OUT_A+OUT_C);
Wait(100);
Off(OUT_A+OUT_C);
repeat(3){
turn_left();
OnFwd(OUT_A+OUT_C);
Wait(40);
Off(OUT_A+OUT_C);
}
turn_left();
OnFwd(OUT_A+OUT_C);
Wait(100);
Off(OUT_A+OUT_C);
turn_right();
OnFwd(OUT_A+OUT_C);//髪
Wait(30);
Off(OUT_A+OUT_C);
turn_right();
OnFwd(OUT_A+OUT_C);
Wait(150);
Off(OUT_A+OUT_C);
turn_right();
OnFwd(OUT_A+OUT_C);
Wait(30);
Off(OUT_A+OUT_C);
}
#br
**苦労した点 [#eabddb62]
大枠ができた後の調整にとても苦労しました。特に前半を変えると後半の位置も変わってしまうので変更した部分の後のものはすべて変えなければなりませんでした。
ペンをロボの中心から逸れた所に付けたため、ペンの軌跡を考えることも難しかったです。-(ふじ)
**感想 [#ba212163]
ペンの固定が簡単な構造のため、しっかりと固定することができず実際に似顔絵を描く時かなりのブレが出来てしまい、うまくペンが紙に着かないこともありました。-(ふじ)
**コメント [#fce851b9]
コメントをどうぞ
- repeat をうまく使っていろいろな曲率の弧を描いていますね。さらにrepeat の中で変数を使って少しずつWaitの時間を変化させれば、曲率が少しずつ変化するような曲線も描けます。 -- [[松本]] &new{2008-05-23 (金) 09:35:17};
- kEVLHXMkBEZUWqkuD -- [[pslqivqa]] &new{2008-06-10 (火) 03:38:37};
#comment
良かった点
+ロボットやプログラムが詳しく説明されています。
+うまく曲線を書けています。
改善点
+プログラムに関数やサブルーチンを用いると、きれいなプログラムになるし、今後にもつながります。例えば、今回はペンの上げ下げに使えます。
+汎用性を追求したり、未解決点に注目して解説するとさらにレベルの高いレポートになると思います。