ロボットにペンを持たせて、相棒の似顔絵を描かせるプログラムを作成する。
ロボット本体は基本のドライブベースを使用しました。
最初はペンをロボットの正面にワイパーのように付けていましたが、それだと
・ペンをうまく固定できない。
・ペンを紙につける時に余計な線ができてしまう。
という問題があったので
のように横に持たせる形に変更しました。
固定している部分は、軸を使い補強してあります。
また持たせるペンは最初軽さ重視でシャープペン・鉛筆を使っていましたが、それでは筆圧をかけることが難しいため、筆圧が必要ないマジックペンを使用することにしました。
元の似顔絵を [輪郭][右の前髪][左の前髪][頭][目][口]の6つの部分に分け、前の部分を書き終えた後、次の部分へ移動しその部分を書いていく形にしました。
#define PEN_TIME 18 //ペンを上げ下げする時間はすべて同じなので関数で固定。 task main()
輪郭のイメージ
{ 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);
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);
右の前髪のイメージ
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);
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);
左の前髪のイメージ
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);
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);
頭部のイメージ
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);
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);
目のイメージ
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);
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);
口のイメージ
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); }
似顔絵を[輪郭][眼鏡][髪]の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); }
大枠ができた後の調整にとても苦労しました。特に前半を変えると後半の位置も変わってしまうので変更した部分の後のものはすべて変えなければなりませんでした。 ペンをロボの中心から逸れた所に付けたため、ペンの軌跡を考えることも難しかったです。-(ふじ)
ペンの固定が簡単な構造のため、しっかりと固定することができず実際に似顔絵を描く時かなりのブレが出来てしまい、うまくペンが紙に着かないこともありました。-(ふじ)
コメントをどうぞ
良かった点
改善点