#author("2020-02-09T17:28:26+09:00","yamaji","yamaji") #author("2020-02-09T17:30:14+09:00","yamaji","yamaji") 目次 #contents *課題1 [#zee55005] [[2019b/Mission1]]を参照 *ロボットの説明 [#wad19d56] 左右のタイヤとペンの上げ下げに各1つのモータを使用した自走式のロボットを作った。最初はマジックハンド型のロボットやx,y軸型のロボットを作ろうとしたが難しく、良いアイデアが出なかったので構造上簡単そうな自走式のロボットに変更した。 まず、全体像はこちら。 #ref(2019b/Member/yamaji/Mission1/zenntai.JPG,50%,ロボット全体像) ロボットの安定性を上げるため、左右の車輪の幅を大きくとり、重心はなるべく低く、かつ後ろに行き過ぎないようにした。さらに、外見に長いラインを取り入れることでスリムに見えるようにし、一見したときスポーツカーを連想させるような見た目に仕上げた。 **ペンの持ち手 [#pd74ecc0] #ref(2019b/Member/yamaji/Mission1/pen.JPG,50%,ペンの持ち手) ペンは写真に写っているゴムで固定し、モータを動かすことで上げ下げを可能にした。 また、ロボットが回転する時にペンの位置がずれないようにペン先が左右のタイヤの中心(回転の軸)に来るようにした。 **コードの仕様 [#s4aef569] #ref(2019b/Member/yamaji/Mission1/kodo.png,50%,コードの仕様) コードのつけやすさも重要なポイントであると思い、誰がやっても簡単につけられるようにした。 *作成途中の問題 [#v8787693] ロボットは完成し、プログラムを書き、実際に紙に似顔絵を書き始めたところで大きな問題が3つ発生した。 **1つ目 [#qcfce143] 同じプログラムなのにロボットを走らせるたびに絵が変わるという事態が起きた。 #ref(2019b/Member/yamaji/Mission1/tigai.JPG,50%,顔の輪郭の幅の違い) (黒線は手書き) いろいろ考え試行錯誤してみたところ原因は紙と床の摩擦の違いにあるという結論に至った。そのため、タイヤが常に紙の上にあるように紙を9枚つなげ、大きな紙とし、その上でロボットを走らせるようにした。すると、この問題は完全ではないが大きく緩和された。 **2つ目 [#w6522fd4] 1つ目の問題をクリアし、作成を続けていると、今度はロボットが指定した角度通りにその場で回転しないという問題が生じた。そのため回転する時のタイヤの動きを見てみると、左右のモータのパワーが違っていて片方が強く片方が弱いため、回転軸が変わってしまっていた。そこでRotateMotorExという指示をやめ、OnFwdを使って少しずつ時間を調整することで思い通りの角度に回転するようにした。 **3つ目 [#t2fbfe56] 発表日の前日、プログラムを完成させようといつものように何度か試行していたとき、NXTロボットにlow batteryと表示されたため、電池を変え、一度今までのプログラムを動かしてみた。すると電池交換前までとは全く違う非常にパワフルな動きになり、それに伴い似顔絵もめちゃくちゃになってしまった。そこで、絵にならないよりはひどくても絵になる方が良いと思い、今までのプログラムを諦め、かなり質の悪い似顔絵を書くことに決めた。 *プログラムの説明 [#l0e57711] **サブルーチン [#cab5aed8] sub go_right(int l,int r,int t) { OnFwd(OUT_C,l);OnFwd(OUT_B,r);Wait(t); } sub vertical(int l,int r,int t) { OnFwd(OUT_C,l);OnFwd(OUT_B,r);Wait(t); } sub A_up() { RotateMotor(OUT_A,20,20); } sub A_down() { RotateMotor(OUT_A,20,-20); } A_upとA_downはペンの上げ下げをする。go_rightとverticalは内容的には右に曲がるプログラムで、全く同じものだがメインプログラムを見たときに90度垂直(vertical)に曲がるように指定したところが分かりやすくなるように差別化した。 **定義 [#t42b3814] float GetDegree(float d) { const float diameter=5.45; const float pi=3.1415; float deg=d/(diameter*pi)*360.0; return deg; } GetDegreeは進みたい距離dに対するタイヤの回転角度を計算し、結果を返す。 **メインプログラム [#gb4b08ad] task main() { int degree8=GetDegree(8.0); int degree2=GetDegree(2.0); int degree3=GetDegree(3.0); int degree4=GetDegree(4.0); int degree5=GetDegree(5.0); int degree6=GetDegree(6.0); int degree13=GetDegree(13.0); Wait(1000); RotateMotor(OUT_BC,30,degree13); //髪の毛の斜め線の部分を描く go_right(25,0,8300); //顔のあごの部分の曲線を描く RotateMotor(OUT_BC,30,degree8); //顔の左側面の直線を描く go_right(25,0,7000); //頭頂部の曲線を描く RotateMotor(OUT_BC,30,degree6); //顔の右側面の直線を描く A_up(); //ペンを上げる RotateMotor(OUT_BC,-30,degree4); //4cm戻る RotateMotor(OUT_BC,-30,degree4); //4cm後退 vertical(20,-20,1800); //90度旋回する RotateMotor(OUT_BC,30,degree2); //2cm進む RotateMotor(OUT_BC,30,degree2); //2cm前進 A_down(); //ペンを下げる RotateMotor(OUT_BC,30,degree3); //左目を描く A_up(); RotateMotor(OUT_BC,30,degree4); //4cm進む RotateMotor(OUT_BC,30,degree4); //4cm前進 A_down(); RotateMotor(OUT_BC,30,degree3); //右目を描く A_up(); RotateMotor(OUT_BC,-30,degree5); //5cm戻る RotateMotor(OUT_BC,-30,degree5); //5cm後退 vertical(-20,20,1800); //90度旋回する A_down(); RotateMotor(OUT_BC,30,degree3); //鼻を描く A_up(); RotateMotor(OUT_BC,30,degree4); //4cm進む RotateMotor(OUT_BC,30,degree4); //4cm前進 vertical(20,-20,1800); //90度旋回する RotateMotor(OUT_BC,-30,degree2); //2cm戻る RotateMotor(OUT_BC,-30,degree2); //2cm後退 A_down(); RotateMotor(OUT_BC,30,degree4); //口を描く A_up(); } 始めにint型で定義されたdegreeは直進したい距離をRotateMotorに入れて使うために用意した。 *まとめ [#w02582a6] **描いた似顔絵 [#ndd8d4be] #ref(2019b/Member/yamaji/Mission1/nigaoe.png,50%,ペアの似顔絵) ペアの子の特徴的な髪型を表すため、髪の毛の斜め線だけは最後までこだわった。 **反省・振り返り [#w90ef1b3] いろいろな問題にぶつかってはペアの子と協力して分析、解明し解決してきたのは良かったが、それだけ時間をかけた分、最後にプログラムを変えるとなったとき、やや投げやりになってしまった。また、そのためとても単純なプログラムになり、似顔絵も似ているとは言えないものになってしまった。