松本での新生活を表す漢字一文字を書くロボットとプログラムを書く。
また、漢字は15×15cm以内に入る大きさで、7画以上
私達が使用したロボットはEV3で言語はpythonにした。
テーマの漢字は「泉」
直線、撥ね、払いのすべてが入っていて何とも課題向け。
教室を見渡すと形式は基本的にペンを持った車が動くタイプとペンを持った手のみを動かすタイプの2タイプに分けられるが、私達の班は後者だった。
使用するモーターは3つで、XY方向にペンを動かし、Z方向に上げ下げする。
私はペンの上げ下げの機構は相方のI氏のアイデアで機能性が十分なところまで達したと思いあまり触らなかった。むしろXY平面のブレが許容できないレベルだったため、工夫が求められた。
キャタピラに手を付ける部分が、キャタピラの特徴である柔軟性があだとなって大きく揺れてしまっていたため、留め具を幅を持たせて二か所設置し、横長のパーツをキャタピラと手の間に挟んだ。これによってぶれが大幅に改善された。
#!/usr/bin/python3 # -*- coding:utf-8 -*-
import ev3dev.ev3 as ev3 import time
mX=ev3.LargeMotor('outB') mY=ev3.LargeMotor('outA') mZ=ev3.MediumMotor('outC')
横線
def motorx(positionX): mX.run_to_rel_pos(position_sp=positionX,duty_cycle_sp=60,speed_sp=100,stop_action='hold')
縦線
def motory(positionY): mY.run_to_rel_pos(position_sp=positionY,duty_cycle_sp=60,speed_sp=100,stop_action='hold')
ペンの高さ
def motorz(positionZ): mZ.run_to_rel_pos(position_sp=positionZ,duty_cycle_sp=60,speed_sp=100,stop_action='hold')
斜線
def motorxyz(positionX,positionY,positionZ): speedY=positionY*100/positionX speedZ=positionZ*100/positionX mX.run_to_rel_pos(position_sp=positionX,duty_cycle_sp=60,speed_sp=100,stop_action='hold') mY.run_to_rel_pos(position_sp=positionY,duty_cycle_sp=60,speed_sp=speedY,stop_action='hold') mZ.run_to_rel_pos(position_sp=positionZ,duty_cycle_sp=60,speed_sp=speedZ,stop_action='hold')
ペンの接地
def setz(): mZ.run_to_rel_pos(position_sp=70,duty_cycle_sp=50,speed_sp=100,stop_action='hold')
ペンの持ち上げ
def lift(): mZ.run_to_rel_pos(position_sp=-70,duty_cycle_sp=50,speed_sp=50,stop_action='hold')
motorxyz(100,10,0) time.sleep(2) setz() time.sleep(2)
motorxyz(15,30,-30)#一画目 time.sleep(2) motorz(-40) time.sleep(1) motorx(30) time.sleep(2) setz() time.sleep(2)
motorxyz(-15,60,0)#二画目 time.sleep(2) lift() time.sleep(2) motorxyz(20,-85,0) time.sleep(2) setz() time.sleep(2)
motorx(-110)#三画目横 time.sleep(2)
motorxyz(20,75,0)#三画目縦 time.sleep(3) lift() time.sleep(2) motorxyz(90,-55,0) time.sleep(2) setz() time.sleep(2)
motorx(-105)#四画目 time.sleep(2) lift() time.sleep(2) motorxyz(95,45,0) time.sleep(2) setz() time.sleep(2)
motorx(-100)#五画目 time.sleep(2) lift() time.sleep(2) motorx(63) time.sleep(2) setz() time.sleep(2)
motory(80)#六画目 time.sleep(2)
motorxyz(20,-40,-55)#六画目撥ね time.sleep(2) motorxyz(30,-60,0) time.sleep(2) setz() time.sleep(2)
motorx(-70)#七画目 time.sleep(2)
motorxyz(105,120,-70)#七画目払い time.sleep(3) motorxyz(-150,-125,0) time.sleep(2) setz() time.sleep(2)
motorxyz(70,40,0)#八画目 time.sleep(2)
motorxyz(-80,70,-25)#九画目 time.sleep(2)
motorxyz(-15,5,-35)#九画目払い time.sleep(1) motorz(-10) time.sleep(1) motorxyz(-20,-155,0) time.sleep(2)
def motorxyz(positionX,positionY,positionZ): speedY=positionY*100/positionXspeedZ=positionZ*100/positionX mX.run_to_rel_pos(position_sp=positionX,duty_cycle_sp=60,speed_sp=100,stop_action='hold') mY.run_to_rel_pos(position_sp=positionY,duty_cycle_sp=60,speed_sp=speedY,stop_action='hold') mZ.run_to_rel_pos(position_sp=positionZ,duty_cycle_sp=60,speed_sp=speedZ,stop_action='hold')
という関数の定義の中でspeedY(モーターYの速さ)を100(モーターXの速さの定数)×positionY(モーターYの回転角度)/positionX(モーターXの回転角度)で求めることで、斜めの直線を書けるようにした。モーターZも同様にすることではらいも可能にした。
泉
八画目の払いが歪んだのが残念だが、点や払い、撥ねは概ねきれいに書けている。
ロボットをかなり安定に動くよう組んだが、どうしても厳密に理論値どうりには動かなかった。上に貼ってある結果も何度も調整した後のもので、1行ずつの動作確認がベストというよりマストであることを学んだ。
まだ調整できるところがあるとしたら、八画目の払いでX方向の動作を遅らせることと、
4画目をもう少し上にあげること、
あとは日の部分をもう少し縦に細くすると見栄えが良くなったかもしれない。