#author("2020-01-13T00:15:01+09:00","numanum","numanum") #author("2020-01-13T00:18:54+09:00","numanum","numanum") [[2019b/Member]] #contents *課題1 [#d3481a74] チームメイトの似顔絵を描くロボットを製作しなさい。 *ロボットの説明 [#y611a10f] **全体構造と方針 [#i5d2f930] 前輪の間、つまり回転の中心に筆を配置して描く構造にした。 また、できるだけ機構を簡単なものにしている。 #ref(IMG_68521.JPG) **モーター、機械本体の配置 [#v2682fd8] ロボットが自ら移動・回転する構造であるため、余計な力が発生しないように上に積み上げていく手段をとっている。しかし、モーターの数が奇数なこともあり、ロボット内に不自然な空間ができており、機械本体の固定が不十分となってしまった。 **筆に関する機構について [#ad08d167] 筆の上げ下げを司っている機構は最も単純で、モーターと直接つながっている。筆が後ろに引きずられないようにつっかえを設置しており、さらに横方向のブレを軽減するため筆先の空間を狭めている。そのため書くときは基本的に紙面に対して垂直に書くことができる。 #ref(IMG_68531.JPG) しかしその弊害で筆がロボットの内側に配置されているため、さらに高さがなければ前方上部に何もおけなくなってしまった。そのためロボットの重心が少し後ろに寄ってしまった ***重心の位置による問題 [#i8cd7fb3] 本来ならタイヤが大きい前方に位置しているのが理想であるため、後輪が一つだと回転の際に倒れてしまう。そのため後輪を二つにし、全体を最も安定な四輪にせざるを得なかった。 #ref(IMG_68541.JPG) さらに、あまり大きな直進などはせず後輪の角度が毎回違うので、次の動きに非常に影響が出る。 *プログラムの説明 [#le4763cc] まずは頻出になるものを定義する。RESTは一回の行動毎に入れるため定義している。 #define SPEED 50 #define STRAIGHT(t) OnFwdSync(OUT_BC,SPEED,0); Wait(t); Off(OUT_BC); #define PEN_UP OnFwd(OUT_A,SPEED); Wait(100); Off(OUT_A); #define PEN_DOWN OnRev(OUT_A,SPEED); Wait(100);Off(OUT_A); #define REST Wait(500); タイヤを軸にして回る際の角度を計算する式を作る。 「タイヤを軸」にして回る際の角度を計算する式を作る。 float GetAngle1(float d) { const float diameter = 5.45; const float length = 11.0; float ang = d*length*2/diameter; return ang; } 今度はその場で筆を中心に回転する角度を計算する式を作る。 今度はその場で「筆を軸」に回転する角度を計算する式を作る。 float GetAngle2(float k) { const diameter = 5.45; const length = 11.0; float ang = length*k/diameter; return ang; } ここからメインのプログラムになる。 task main() { int angle = GetAngle1(90.0); int angle1 = GetAngle2(90.0); int angle2 = GetAngle2(120.0); //角度の設定 repeat(2){ //左上から輪郭を描く RotateMotor(OUT_C,SPEED,angle); STRAIGHT(300); RotateMotor(OUT_C,SPEED,angle); STRAIGHT(500); //一度目で頭、二度目で下顎 } RotateMotorEx(OUT_BC,SPEED,angle1,100,true,true); REST; STRAIGHT(1100); //前髪を直線で描く REST; PEN_UP; //次の描き始めまで筆を上げる REST; RotateMotorEx(OUT_BC,SPEED,angle2,100,true,true); //この部分は回転角を120°に設定 REST; STRAIGHT(400); REST; RotateMotorEx(OUT_BC,SPEED,angle1,100,true,true); PEN_DOWN; //眼鏡の描き始めに移動 repeat(2){ STRAIGHT(300); REST; RotateMotorEx(OUT_BC,SPEED,angle1,100,true,true); REST; OnFwd(OUT_B,70); OnFwd(OUT_C,-35); Wait(2150); Off(OUT_BC); //眼鏡の円を反時計回りで描く REST; PEN_UP; REST; RotateMotorEx(OUT_BC,SPEED,angle1,-100,true,true); REST; STRAIGHT(400); REST; PEN_DOWN; //眼鏡のレンズの右端から左端に、筆を上げて移動 } //一度目で右、二度目で左の眼鏡を描く REST; STRAIGHT(300); //左の輪郭上に戻ってくる PEN_UP; //次の描き始めまで筆を上げる REST; RotateMotorEx(OUT_BC,SPEED,angle1,-100,true,true); STRAIGHT(200); RotateMotor(OUT_B,SPEED,angle); PEN_DOWN; //口の描き始めに移動 REST; STRAIGHT(400); //口を描く PEN_UP; } 最初は使用する角度を羅列しておく。120°は本来使う必要はないが、どうしても90°の設定だと回れない部分があるため加えている。~ 一つ目のrepeatでは顔の輪郭を描き、二つ目のrepeatは相方のアイデンティティである眼鏡を描いている。その中で出てくるOnFwdの部分は、その場で回転でもタイヤを軸に回転でも描けない一回り小さな円を描くためのものだ。 最初は使用する角度を羅列しておく。120°は理論上使う必要はないが、どうしても90°の設定だと回れない部分があるため加えている。~ 一つ目のrepeatでは顔の輪郭を描き、二つ目のrepeatは相方のアイデンティティである眼鏡を描いている。その中で出てくるOnFwdの部分は、その場で回転でもタイヤを軸に回転でも描けない一回り小さな円を描くためのものだ。~ 眼鏡を描いた後は左タイヤを軸に回転させ、口の場所まで移動する。 *お絵かき結果 [#m87b62f1] #ref(IMG_68551.JPG) *反省・感想 [#s856788e] 当初はXY座標系で作ろうとしたがどうしてもできなかったため、お互いにレゴブロックの技術不足を感じた。構造上考えていたよりもうまく動かないことが多かったため、プログラムの面でも細かい調整が必要で毎回同じ軌道を描くことが非常に難しかった。