チームメイトの似顔絵を描くロボットの製作
授業で最初に作った車輪に2つのモーターを使う構造では、顔の輪郭とパーツにずれが生じやすいと考えられた。よって、ペンの縦移動と横移動を完全に個別化することでずれが起こりにくい構造を取り入れた。前後に移動する車輪部に1つ、横に移動する部分に1つモーターを使った。また、ペンのアップダウンにもモーターを一つ使うため合計で3つのモーターを使うことになった。しかし、ロボット全体では前後にしか動くことはできないので曲線を引くことはできない。ただ、横移動と縦移動を組み合わせることで斜めの動きは再現することができる。また、きれいに斜めの線を描くときは縦移動のためのタイヤと横移動のための歯車で大きさが違うため、うまいことプログラムで調整しなくてはならない。
横移動のための構造は、3つの歯を持つ歯車とペンをつけたはしごとを噛み合わせることで回転運動を横移動の運動に変換するものだ。また、上下左右をある程度固定することによってまっすぐ線を引けるようにした。この構造の欠点は、歯車とはしごの噛み合わせによって回転量が同じでも実際に横に移動する長さに違いが生じてしまう点である。ただ、形はずれないので回転量を調整することである程度長さをそろえることはできる。
このロボットのおまけの工夫として、充電のための構造がある。本来はしごやモーターが邪魔をして充電ケーブルをつなげることはできないが、固定を2つ外すことで一つの固定を支点としてモーターを回転できるような仕組みにした。この仕組みのおかげで充電ケーブルをつなぎやすく、作業を中断するときロボットをばらすことなく充電できた。
まず、必要なものをインポートしてわかりやすい変数に置き換える。
from ev3dev2.motor import LargeMotor, OUTPUT_D, SpeedPercent from ev3dev2.motor import LargeMotor, OUTPUT_A, SpeedPercent from ev3dev2.motor import MediumMotor, OUTPUT_B, SpeedPercent from ev3dev2.motor import MoveTank, OUTPUT_A, OUTPUT_D MD = LargeMotor(OUTPUT_D) MA = LargeMotor(OUTPUT_A) MB = MediumMotor(OUTPUT_B) MAD = MoveTank(OUTPUT_A, OUTPUT_D)
ここでは、OUTPUTの記号でわかりやすいように変数を定義した。MDは縦移動、MAは横移動、MBはペンのアップダウン、MADは縦移動と横移動を組み合わせた斜め移動に用いる。
MA.on_for_degrees(20, -500) MD.on_for_degrees(10, -60) MAD.on_for_seconds(20, -5, 1) MA.on_for_degrees(20, 180) MAD.on_for_seconds(20, 5, 1) MD.on_for_degrees(20, 60) MB.on_for_degrees(5, -30)
横移動にはしごを用いているので、はしご一段につき120度と考えれば制御しやすいためdegreesを使った。ロボットの構造上、斜め移動をするときは縦移動と横移動で回転角に対し進む長さに圧倒的な差があるので、secondsを使いスピードに差をつけることできれいな顎になるよう調整した。
MA.on_for_degrees(20, -200) MD.on_for_degrees(20, -25) MB.on_for_degrees(5, 30) MA.on_for_degrees(20, -180) MD.on_for_degrees(20, -20) MA.on_for_degrees(20, 240) MD.on_for_degrees(20, 10) MB.on_for_degrees(5, -30) MA.on_for_degrees(20, -300) MD.on_for_degrees(20, 10) MB.on_for_degrees(5, 30) MA.on_for_degrees(20, -180) MD.on_for_degrees(20, -20) MA.on_for_degrees(20, 240) MD.on_for_degrees(20, 10) MB.on_for_degrees(5, -30)
はじめfor文を使おうと思ったが、2つめのめがねを描くとき1つめのめがねに対し縦に少しずれてしまったためその調整が必要になったため断念した。また、「ロボットについて」で前述したようにめがねを描くときに、左右逆の向きに進むと長さに差が生じるため、回転角に差をつけ調整した。
MA.on_for_degrees(20, -200) MD.on_for_degrees(20, -40) MB.on_for_degrees(5, 30) MA.on_for_degrees(20, 300) MB.on_for_degrees(5, -30)
口の位置を調整した後、直線の口を描いた。
MA.on_for_degrees(20, 110) MD.on_for_degrees(20,40) MA.on_for_degrees(20, -290) MB.on_for_degrees(5, 30) MA.on_for_degrees(20, -60) MB.on_for_degrees(5, -30)
なぜ口を描いてからめがねをつないだかというと、その方が調整しやすかったからである。めがねを描き終えた後だと、ペンの位置とつなげたい位置が近いため細かな調整が要求される。口を描いた後だと位置がある程度離れているため、大雑把な調整が可能になった。
MA.on_for_degrees(20, -200) MD.on_for_degrees(20, 30) MB.on_for_degrees(5, 30) for i in range(4): MAD.on_for_seconds(20, -5, 0.3) MAD.on_for_seconds(20, 5, 0.3) MB.on_for_degrees(5, -30)
髪の毛を描くに当たってはfor文を用いた。ギザギザさせるには繰り返しで斜めを行ったり来たりすればよいと考えたためである。
ある程度クオリティーのある似顔絵を描くことができたと思う。私としては満足できるできとなった。
ロボットの構造上、横移動のときプログラム内の数字と実際の線の長さが一致せず、数字に差をつけることで調整しなくてはならなかった点である。正確性を持ったロボットを作ることができればプログラムを書く時間を短縮することができただろう。