松本での新生活について選択した漢字は「荒」である。
今回製作したロボットはプリンターをイメージし、キャタピラを用いて製作した。特徴としてx軸方向にヘッダを動かすモーターとy軸方向にヘッダを動かすモーターを搭載し、それぞれ独立して動かすことで斜線を描くことができる。また、xy軸で考えることでプログラミングの手間を軽減することができた。
上図のようにヘッダ部分は木組み細工の様な箱型の部品である。次にロボットに実際に取り付けられている図を示す。
仕組みとしては単純で、部品Xを動かすとヘッダはx方向に動くし、部品Yを動かすとヘッダもy方向に動く、といった具合である。また、ヘッダを目標の位置へ移したい場合、まずx方向へAだけ動かした後、Y方向にBだけ動かせばよい。これはベクトルの合成をイメージするとわかりやすい。
今回ペンを上下させるためにウォームギアを用いた。仕組みとしてはモーターに取り付けられた小ギアの回転をウォームギアに伝え、力の方向を上下に変換するというものである。
※後で知ったが、このウォームギアの使用法は想定されていないものらしく、部品を傷める可能性があるので推奨されない。
現在は摩擦を軽減するためにタイヤ使用しているが、改善する前は摩擦が大きく、字が安定しなかった。
#!/usr/bin/python3 # -*- coding: utf-8 -*- import ev3dev.ev3 as ev3 import time my=ev3.LargeMotor("outA") mx=ev3.LargeMotor("outB") m=ev3.MediumMotor("outC")
y軸方向に動かすモータをmy,x軸方向に動かすモーターをmx,ペンを上下させるためのモーターをmと命名する。また、今回はtimeモジュールをインポートしている。
def x_pos(a,b): mx.run_to_rel_pos(position_sp=a,duty_cycle_sp=80,speed_sp=b,stop_action="hold") #posはpositionの略である。 def y_pos(c,d): my.run_to_rel_pos(position_sp=c,duty_cycle_sp=80,speed_sp=d,stop_action="hold") def m_down(): m.run_to_rel_pos(position_sp=70,duty_cycle_sp=30,speed_sp=50,stop_action="hold") def m_up(): m.run_to_rel_pos(position_sp=-70,duty_cycle_sp=30,speed_sp=50,stop_action="hold")
今回は、秒数でモーターを回してヘッダを動かすのではなく、モーターをどれくらいの角度で回すかで制御した。なぜならば、こちらの方法の方が調整しやすく、正確に動かせるであろうと考えたからである。
次に関数の説明に移りたいと思う。x軸方向にどれだけ動かすのかをx_pos(),y軸方向にどれだけ動かすのはy_pos()とした。双方とも引数に(回転角,モーターの回転速度)を要求する。
また、ペンを上へ上げる動きをするものをm_up(),降ろす動きをするものをm_down()とした。これらは、引数を必要とせず、モーターを|70度|回転させる。
矢印の根元からペン先スタート
#1画目(ペンは接地した状態からスタート) x_pos(-120,50) time.sleep(2) #2画目 m_up() #移動開始 time.sleep(2) x_pos(110,50) time.sleep(2) y_pos(-30,50) time.sleep(2) m_down() #実線を描く time.sleep(2) y_pos(70,50) time.sleep(2) #3画目 m_up() #移動開始 time.sleep(2) y_pos(-60,50) time.sleep(2) x_pos(-80,50) time.sleep(2) m_down() #実線を描く time.sleep(2) y_pos(40,50) time.sleep(2) #4画目 m_up() #移動開始 y_pos(20,50) time.sleep(2) x_pos(110,50) time.sleep(2) m_down() #実線を描く time.sleep(2) x_pos(-130,50) time.sleep(2) #5画目 m_up() #移動開始 time.sleep(2) x_pos(70,50) time.sleep(2) m_down() #実線を描く time.sleep(2) y_pos(-40,50) time.sleep(2) 6画目 m_up() #移動開始 time.sleep(2) y_pos(45,50) time.sleep(2) x_pos(40,50) time.sleep(2) m_down() #実線を描く time.sleep(2) y_pos(30,50) time.sleep(2) x_pos(-100,50) time.sleep(3) #7画目 m_up() #移動開始 time.sleep(2) x_pos(90,50) time.sleep(2) m_down() #実線を描く time.sleep(2) y_pos(30,50) time.sleep(2) y_pos(30,50) x_pos(30,50) time.sleep(3) #8画目 m_up() #移動開始 time.sleep(2) x_pos(-80,50) time.sleep(3) y_pos(-70,50) time.sleep(2) m_down() #実線を描く time.sleep(2) y_pos(80,50) time.sleep(2) #9画目 m_up() #移動開始 time.sleep(2) x_pos(-40,50) time.sleep(2) y_pos(-90,50) time.sleep(2) m_down() #実線を描く time.sleep(2) y_pos(90,50) time.sleep(2) x_pos(-20,50) time.sleep(2) y_pos(-50,50) time.sleep(2) m_up() #終了
毎回2秒sleepさせているが、これをしないと前のモーターの動作中に次の動作が始まってしまう。また最初、理論値でプログラミングしようと試みたが、ロボットの精度の問題で、文字がうまく書けなかった。そこで、理論値のプログラムで一旦書いてみて、どのようなずれが生じているのか調べ、理論値のプログラムを雛形にし、数値を変えてみて調整を繰り返すことで問題を解決した。
今回製作したロボットの問題点として、精度が低い、安定しない、という点が挙げられる。なので、うまく書けるときと、うまく書けないときがある。前者を左に、後者を右に示す。
何度かの改良を経て、5回に3回くらいの割合でうまく書けるようになった。
今回の課題で、「モノを制御する」ということは、トライアンドエラーを積み重ねてやっと実現するものだと知った、また考えていた以上に大変である。ということがわかった。また、こういったものの製作、開発は、無駄をそぎ落としていくことが大切だと学んだし、そのためにはもっと余裕をもって作業を進めていくべきだと感じた。それらに加えて、今回レゴブロックの効果的な使用法を学ぶことができた。次回の課題では、今回学んだことを生かしてよりよいものを作りたいと思った。
このロボットの問題点として、「安定しない」というものが挙げられたが、これに対する解決策として「キャタピラの向きを横にしてみたらどうか」という助言を先生から頂いたが、時間が足りず採用を見送ることとなった。そこで後日プログラムこそ書かなかったが、個人的に興味があり本体だけ組み立ててみた。
時間がなく動かすことができなかったが、まだまだキャタピラを横にする以外の改善策が見つかりそうで、このロボットもまだまだ奥が深いと感じた。正直itピアで見たような方式も試してみたかった。