*目次 [#t9f4de6f]
#contents

*課題について [#xb343d49]
自分の似顔絵をロボットを使って描く。今回使用した似顔絵は以下の通り。~
#ref(2016a/Member/maccha/Mission1/IMG_3643.JPG,50%,顔)
詳しくは[[こちら:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMission1]]

*ロボットの構造 [#a448bee7]
**本体 [#gc99a673]
#ref(2016a/Member/maccha/Mission1/IMG_3619.JPG,50%,ロボット)
 ベースは、本体の左右に一つずつ搭載したモーター(A,C)による四輪車。本体後部にペンの上げ下げを行う部分を搭載した。
**ペン可動部分について [#k2df9f53]
#ref(2016a/Member/maccha/Mission1/IMG_3624.JPG,50%,Pen)
#ref(2016a/Member/maccha/Mission1/IMG_3623.JPG,50%,Pen2)
#ref(2016a/Member/maccha/Mission1/IMG_3638.JPG,50%,Pen3)
 上の画像のように、ペンを2つのタイヤではさみ、画像の右側にあるモーター(B)を動かすことでタイヤを回しペンを上げ下げさせる構造になっている。なおタイヤの上にあるグレーのパーツでペンの前後への動きを制限している。


*プログラムの説明 [#af7ed590]
 基本となるのは、前進、後退、旋回、ペンの上げ下げの4つの動作である。
**顔の書き順 [#o10cae64]
#ref(2016a/Member/maccha/Mission1/IMG_3645.JPG,80%,Face)
 まず顔の右上からスタートし、1〜5の順に直線を描く。次に5が描き終わったところで右に旋回し6→6'→6"→6"'(6と同じ)の順に三角形を描き、同様に7、8と三角形を描きスタートに戻る。その後右に旋回し直進(9)、10で右に旋回、10→10'→10"と進み左に旋回し直進(11)、また左に旋回し12→12'へ直進。そして左に旋回し直進(13)、左に旋回し直進し、再び左に旋回して直進(13')、その後13"→13"'→13""と進み終了。
**プログラムの詳細 [#pb5b828f]
***基本動作 [#n526ee98]
 まず、前進、後退、ペンの上げ下げ、旋回の基本動作について定義する
-前進
 #define go_forward(t) OnFwd(OUT_AC);Wait(t);Off(OUT_AC);
-後退
 #define go_backward(t) OnRev(OUT_AC); Wait(t); Off(OUT_AC);
-ペンを上げる
 #define up OnRev(OUT_B);Wait(10);Off(OUT_B);
-ペンを下げる
 #define down OnFwd(OUT_B);Wait(10);Off(OUT_B);
 なお、旋回に際しては回転軸が本体の中心になるため、旋回後のペン先の位置が旋回前の終点からずれるため、旋回前に後退、旋回後に前進するようにしている。
#ref(2016a/Member/maccha/Mission1/IMG_3646.JPG,50%,Penguin)
その際の前進、後退の時間は次のように定義する。
 #define forward_TIME   58
 #define forward_TIME_i   70
 #define backward_TIME   48

-旋回(120°)  (※行変更の際の記号が¥となっている)
 #define TURN_TIMEi   138
 #define forward_TIME_i   70
 #define backward_TIME   48
 #define turn_right_i OnRev(OUT_AC);Wait(backward_TIME);        \
                      OnRev(OUT_C); OnFwd(OUT_A);Wait(TURN_TIMEi);  \
                      go_forward(forward_TIME_i);down;Off(OUT_ABC);   //120°

-旋回(90°,右)
 #define TURN_TIMEii   102
 #define turn_right_ii up;OnRev(OUT_AC);Wait(backward_TIME);          \
                       OnRev(OUT_C); OnFwd(OUT_A);Wait(TURN_TIMEii);  \
                       go_forward(forward_TIME);down;Off(OUT_ABC);    //90°

-旋回(90°,左)
 #define TURN_TIMEii_L 110
 #define turn_left_ii up;OnRev(OUT_AC);Wait(backward_TIME);            \
                      OnRev(OUT_A); OnFwd(OUT_C);Wait(TURN_TIMEii_L);  \
                      go_forward(forward_TIME);down;Off(OUT_ABC);      //90°
※旋回の左右で時間が異なるが、これはモーターの性能によるものだと思われる。

-旋回(45°)
 #define TURN_TIMEiii   49
 #define turn_right_iii up;OnRev(OUT_AC);Wait(backward_TIME);           \
                        OnRev(OUT_C); OnFwd(OUT_A);Wait(TURN_TIMEiii);  \
                        go_forward(forward_TIME);down;Off(OUT_ABC);     //45°

***パーツごと [#j1a961c8]
 パーツごとにプログラムを組んだため、パーツごとにある程度定義した。

-輪郭~
書き順の1〜5である。旋回する角度はすべて45°で設定してある。
 #define ago(t) turn_right_iii; go_forward(t);       //曲がって(45°)直進
tを各辺で調節して、ago(t)を5回繰り返す。

-髪~
書き順の6〜8である。まず5の終点から90°右に旋回し、三角形を描く。~
90°旋回し、直進するプログラムを定義する。

 #define ago_i(t) turn_right_ii; go_forward(t);      //曲がって(90°右)直進

  三角形の一辺を描くプログラム定義する。

 #define kami(t) go_forward(t); up;go_forward(2); turn_right_i;

  これを三回繰り返すことで三角形を描く。三角形を描いた後に一辺だけなぞり次の三角形に移る。(例:6"'は6をなぞっている。)~
  以上をまとめて

 ago_i(5);                       //90°回転後、髪へ
 repeat(3){
           repeat(2){
                      kami(36);
                     }
           kami(38);
           go_forward(37);
          }

-メガネ~
書き順の9〜13""である。まず8"'の終点から90°右へ旋回し(9)、10〜13""でメガネを描く。~
メガネを描く部分のみで定義した。
 #define megane ago_i(30);up;go_forward(25);down;go_forward(10);up;go_forward(25);down;go_forward(30);    \
                up; megane_turn_L; go_backward(8); megane_turn_L; go_forward(25); down; go_forward(25);   \
                up; go_forward(12); down; go_forward(25); up;                                             \
                go_backward(10); megane_turn_L;go_backward(15);down; go_forward(15); up; megane_turn_L;   \
                megane_turn_L; down; go_forward(15); up; megane_turn_L;                                   \
                go_backward(35); megane_turn_L; down; go_forward(15); up; megane_turn_L;                  \
                megane_turn_L; down; go_forward(15);

 #define megane_turn_L OnRev(OUT_AC);Wait(backward_TIME);               \
                       OnRev(OUT_A); OnFwd(OUT_C);Wait(TURN_TIMEii_L);  \
                       go_forward(forward_TIME); Off(OUT_AC);
  megane_turn_Lは、90°左へ旋回後、ペンを動かさず直進するために定義した。~
  (megane_turn_Lは、90°左へ旋回後、ペンを動かさず直進するために定義した。)~
  つまり、メガネの上辺部を直線で描き、その後輪郭をなぞってメガネの下辺部を直進で描く、そして12'の終点で左に90°旋回し上辺と下辺をつなぐ、ということである。

**プログラム全容 [#o51d0032]
 #define TURN_TIMEi   138
 #define TURN_TIMEii   102
 #define TURN_TIMEii_L 110
 #define TURN_TIMEiii   49
 #define forward_TIME   58
 #define forward_TIME_i   70
 #define backward_TIME   48
 
 #define up OnRev(OUT_B);Wait(10);Off(OUT_B);
 #define down OnFwd(OUT_B);Wait(10);Off(OUT_B);
 #define go_forward(t) OnFwd(OUT_AC);Wait(t);Off(OUT_AC);
 #define go_backward(t) OnRev(OUT_AC); Wait(t); Off(OUT_AC);
 
 #define turn_right_i OnRev(OUT_AC);Wait(backward_TIME);        \
                      OnRev(OUT_C); OnFwd(OUT_A);Wait(TURN_TIMEi);  \
                      go_forward(forward_TIME_i);down;Off(OUT_ABC);   //120°
 
 #define turn_right_ii up;OnRev(OUT_AC);Wait(backward_TIME);          \
                       OnRev(OUT_C); OnFwd(OUT_A);Wait(TURN_TIMEii);  \
                       go_forward(forward_TIME);down;Off(OUT_ABC);    //90°
 
 #define turn_left_ii up;OnRev(OUT_AC);Wait(backward_TIME);            \
                      OnRev(OUT_A); OnFwd(OUT_C);Wait(TURN_TIMEii_L);  \
                      go_forward(forward_TIME);down;Off(OUT_ABC);      //90°
 
 #define turn_right_iii up;OnRev(OUT_AC);Wait(backward_TIME);           \
                        OnRev(OUT_C); OnFwd(OUT_A);Wait(TURN_TIMEiii);  \
                        go_forward(forward_TIME);down;Off(OUT_ABC);     //45°
 
 #define ago(t) turn_right_iii; go_forward(t);       //曲がって(45°)直進
 #define ago_i(t) turn_right_ii; go_forward(t);      //曲がって(90°右)直進
 #define kami(t) go_forward(t); up;go_forward(2); turn_right_i;
 #define megane ago_i(30);up;go_forward(25);down;go_forward(10);up;go_forward(25);down;go_forward(30);    \
                up; megane_turn_L; go_backward(8); megane_turn_L; go_forward(25); down; go_forward(25);   \
                up; go_forward(12); down; go_forward(25); up;                                             \
                go_backward(10); megane_turn_L;go_backward(15);down; go_forward(15); up; megane_turn_L;   \
                megane_turn_L; down; go_forward(15); up; megane_turn_L;                                   \
                go_backward(35); megane_turn_L; down; go_forward(15); up; megane_turn_L;                  \
                megane_turn_L; down; go_forward(15);
 #define megane_turn_L OnRev(OUT_AC);Wait(backward_TIME);               \
                       OnRev(OUT_A); OnFwd(OUT_C);Wait(TURN_TIMEii_L);  \
                       go_forward(forward_TIME); Off(OUT_AC);
 
  task main()
 {
     OnFwd(OUT_B);
     Wait(3);
     Off(OUT_B);
     go_forward(80);
     ago(32);
     ago(60);
     ago(32);
     ago(84);                             //輪郭終了
     ago_i(5);                            //90度回転後、髪
     repeat(3){
                repeat(2){
                            kami(36);
                         }
                kami(38);
                go_forward(37);
              }
     ago_i(50);
     megane;
 }
※一番最初に少しペンを紙に押し付けるようにした。

*反省・感想 [#eee0f4d0]
 今回最も大きな障害だったのが、電池残量によりモーターの回転度合が変わることだった。これにより調整がかなり面倒なものとなり、何度も心が折れそうになった。~

 良かった点としては、旋回によるペン先のズレを完璧に修正できていたこと、また簡単でシンプルな機構でロボットが作れたところだろう。~

 反省点としては、"megane"が煩雑になってしまったこと、またペンの上げ下げによる力でブロックが浮いてしまうことに対し、ピンを使って対応できなかったこと、そして左右のモーター(A,C)による角度等のズレが積み重なって大きくなることに対応できなかったことが挙げられる。特にモーターによるズレは大きな問題で、輪郭、髪はなんとか理想通りに描けるが、メガネがどうしても斜めになってしまうことが多々あった。~

 今回の課題を通して、ロボットの構造やプログラムを考える一通りの経験ができた。また多くの改善点が見つかったため、次回以降改善に努めたい。

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS