#author("2019-11-22T13:51:58+09:00","kurisuke","kurisuke") #author("2019-11-22T13:53:55+09:00","kurisuke","kurisuke") [[2019b/Member]] 目次 #contents *課題1 [#ldb3275f] チームメイトの似顔絵を自動で描くロボットを製作せよ。似顔絵はA4の紙に収まる大きさにすること。 **今回のポイント [#s04e08cc] チームメイトの顔の特徴である丸顔と細目が際立つようなプログラムを書けるかどうか。 *ロボットの説明 [#s6bb2e6f] **全体の構造 [#e7fe3ca4] 比較的簡単にプログラムを書けるということで、xyz軸を用いたロボットを製作した。 下の写真がロボットの全体であり、赤線のようにxyz軸をとった。 &ref(2019b/Member/kurisuke/Mission1/S__4702236_LI.jpg,50%,ロボットの全体図); **�.撻鵑鮟腸�に動かす(x軸y軸方向)機構 [#q0249d7e] x軸y軸に動かす機構は同じように製作した。下の写真のような機構を作った。仕組みとしては、機関車の車輪を思い浮かべてもらうとわかりやすと思う。 &ref(2019b/Member/kurisuke/Mission1/S__4702232_LI.jpg,25%,xy軸の機構); **��ペンを上に動かす(z軸方向)機構 [#m273ff41] ペンは下の写真のように取り付けた。ここでは、ペンと紙の間の摩擦を減らすためにペン先を紙すれすれに取り付けることに注意した。 &ref(2019b/Member/kurisuke/Mission1/S__4702233.jpg,25%,ペンの取り付け方); &ref(2019b/Member/kurisuke/Mission1/S__4702235 (2)_LI.jpg,50%,ペンを上げ下げする機構); ペンの上げ下げの仕組みとしては、モーターで棒を降ろすことで(��)ペンを取り付けたもう一つの棒を押し上げて一緒にペンも上がる(��)という簡単な仕組みにした。 *プログラムの説明 [#hc0fec57] これが、今回使用したプログラムです。 #define SPEED 10 #define P 40 #define I 40 #define D 90 #define gf(x,y,z) gt(x-log_x,y-log_y,z);log_x=x;log_y=y; //(行き先の座標 , 繰り返し の回 数) #define pu OnFwd(OUT_A,20);Wait(500);Off(OUT_A); //ペンを上げる #define pd OnFwd(OUT_A,-SPEED);Wait(300);Off(OUT_A);Wait(600); //ペンを下げる #define gh gf(0,0,1); //ホームポジション (0,0) に戻る sub gt(float x,float y,float z) //(行き先の座標 , 繰り返しの回数) { const float axis = 100.0; //軸 const int rep = z; //繰り返し回数 const float rotation = 180.0; //軸を端から端まで動かすのに必要な角度 const float correction = 0.5; //補正 float angle_x = ((rotation/axis)*x)/rep + sign(x)*correction; float angle_y = ((rotation/axis)*y)/rep + sign(y)*correction; repeat(rep) { //RotateMotor(OUT_B,SPEED,angle_x); RotateMotorPID(OUT_B,SPEED,angle_x,P,I,D); //RotateMotor(OUT_C,SPEED,angle_y); RotateMotorPID(OUT_C,SPEED,angle_y,P,I,D); } Wait(400); } task main() { ResetTachoCount(OUT_BC); float log_x = 0; float log_y = 0; //輪郭 pu; gf(40.0,100.0,2); pd; gf(0.0,50.0,30); gf(30.0,0.0,30); gf(100.0,50.0,30); gf(10.0,100.0,30); pu; //目 gf(15.0,45.0,2); pd; gf(30.0,45.0,1); pu; gf(50.0,45.0,1); pd; gf(70.0,45.0,1); pu; //鼻 gf(30.0,35.0,2); pd; gf(25.0,25.0,10); gf(35.0,28.0,1); pu; //口 gf(15.0,15.0,2); pd; gf(40.0,15.0,2); pu; gh; } これから、詳しく見ていく。 **ペンを動かすプログラム [#a9aeac64] x軸y軸を100等分して動かすことにした。そして、関数“log”を用いることによって、ペンが前にいた座標を記憶するようになった。このことで、移動したい座標をgtの()の中に書くとその点まで移動できるようになった。 rep(repeat)を計算に入れることで斜めの線を階段のように細かく書けるようにした。そのことで、repの値を大きくすることで直線を滑らかな曲線にすることが可能になった。 モーターが動き出してペンが移動するまでの間をプログラム内に補正を入れることで誤差を減らした。 #define SPEED 10 #define P 40 #define I 40 #define D 90 #define gf(x,y,z) gt(x-log_x,y-log_y,z);log_x=x;log_y=y; //(行き先の座標 , 繰り返しの回 数) #define gh gf(0,0,1); //ホームポジション (0,0) に戻る sub gt(float x,float y,float z) //(行き先の座標 , 繰り返しの回数) { const float axis = 100.0; //軸 const int rep = z; //繰り返し回数 const float rotation = 180.0; //軸を端から端まで動かすのに必要な角度 const float correction = 0.5; //補正 float angle_x = ((rotation/axis)*x)/rep + sign(x)*correction; float angle_y = ((rotation/axis)*y)/rep + sign(y)*correction; repeat(rep) { //RotateMotor(OUT_B,SPEED,angle_x); RotateMotorPID(OUT_B,SPEED,angle_x,P,I,D); //RotateMotor(OUT_C,SPEED,angle_y); RotateMotorPID(OUT_C,SPEED,angle_y,P,I,D); } Wait(400); } **ペンの上げ下げを行うプログラム [#n64bb548] #define pu OnFwd(OUT_A,20);Wait(500);Off(OUT_A); //ペンを上げる #define pd OnFwd(OUT_A,-SPEED);Wait(300);Off(OUT_A);Wait(600); //ペンを下げる 何回も使うので、マクロを使用して簡略化した。 pu: put up pd: put down という意味でつけた。 **工夫したプログラム [#jd8ffa5d] //輪郭 pu; gf(40.0,100.0,2); pd; gf(0.0,50.0,30); gf(30.0,0.0,30); gf(100.0,50.0,30); gf(10.0,100.0,30); pu; このプログラムでは、repの値を30と大きくすることで、滑らかな曲線を描き、しっかりした円になるように座標の調整をした。 *完成した似顔絵 [#m072fd5e] これが完成した似顔絵である(発表会での似顔絵より試運転時のほうがうまく書けたのでそちらを載せた)。丸顔と細目をうまく表現できた。しかし、髪の毛までは表現するのが難しかった。 &ref(2019b/Member/kurisuke/Mission1/S__4890653.jpg,35%,完成した似顔絵); *課題1の反省と感想 [#o3317c5d] 初めてのロボット作りで悩むことが多々あったが、しっかりと期限内に作り終えることができた。反省点としては、どうしても0度・180度付近と90度付近ではモーターの動く速さが異なり、そのズレを考慮しながらプログラムを組むのが大変だった。後から一人のチームメイトが、モーターの回転角度でペンを動かすプログラムより、三角関数でプログラムを書いたほうがより正確にペンを動かせたのではないかという考え思いついたが、私も同じ考えである。