初めに 

  Ev3をnxcで動かそうとして時間を使いつづけた結果、作業開始が発表会前日の午前になってしまった。
  結果、うまくいかない(クロスコンパイラのエラーが解消できない)のでpython2.7でプログラミングをすることになった。環境はwindows10でteratermを使い、EV3にアクセスしnano上でプログラミングをした。どうしてもWifi経由だとラグが大きくて入力に苦労する

課題について

 課題1は “A4の紙に今年の大学生活を表す漢字一文字を書くロボットを製作せよ。7画以上の文字を選ぶこと。”“文字は15cm四方に収まる大きさにすること。”などである。
 多少迷走はしたが、自分は信を描くことになった。

機体について

機体全般について

概観

この機体で重視したのはまず、筆を上げずに超信地旋回したとしても筆が線を描かない(点のままである)ということである。
そのためにまず、駆動輪を機体の真ん中に置き、できるだけ重心を駆動輪の軸上に持ってくることにした。モーターを横置きしたことで写真左側に偏っていた重心を中心に戻すためにモーターの反対側にEV3を設置した。
また、一番の重量物であるEV3本体の真下には車輪などを設置せず浮かせ、EV3の反対側のみにキャスターを設置することで重心のずれによる旋回の中心のずれを防止している。(キャスターほんとに便利)
しかし機体の端に重量物を設置したことで機体が接地物のないEV3側に倒れてしまった。
解決策として反対側にEV3 IRビーコン(EV3 IRセンサーってセットの中に入ってなかった気がするけどEV3 IRビーコンって何に使うのだろう?)を設置してバランスを取ったところEV3の設置してある方向へ進んで急停止しても転ばないがある程度は機体が浮く程度の絶妙なバランスに(割と偶然に)なった。
また、ペンには筆ペンを使用した。ペン先がしなることである程度の誤差を吸収することの期待して採用した。セットの中に輪ゴムは入っていなかったため市販の輪ゴム二本で代用した。

筆の昇降機構について

固定機構

この機構に求められていたのは100回昇降を行ったら100回とも必ず同じ場所に筆先を下すことである。それ以外は求められていない。昇降に時間がかかってても別にいいと考えたため動作がゆっくりである。
写真は最大まで上げた状態である。部品に隠れてしまっていて見えないがこの状態より上に上がることはないようにストッパーがついているし、逆に筆が下がりきった時でも筆が壊れるようなところまでは押し下げないような調整がしてある。(個人的な信仰だが、こういうアームなどを作る時はハードウエアとソフトウエア両方で動作に制限をかけるようにしてる。本番にどちらかをミスしていた時に即終了とならないための対策である。)

ぶれの抑制機構

この機構は、筆のぶれについて、機体の左右方向(写真の前後方向)は黄色のパーツが抑制し、機体の前後方向(写真の左右方向)については下のほうの筆を挟むパーツで抑制するようにしている。(写真はキャップをつけるために緩めてある)
下の、棒についた二つの筆を挟むパーツの位置を微調整することにより筆の位置をある程度調整できるが基本的に写真右側に密着させれば問題はないようにできている。

筆の上下運動機構

上記の筆のぶれの抑制機構を最大限活用するためには筆自体が円運動ではなく上下運動をする必要がある。しかし、もちろんモーターは回転運動しかできない。なので非常に簡単なリンクを組み上下運動を作り出した。一番大きな歯車にピンを刺しそこに部品をつなぐだけの簡単なものである。

筆圧を出すために

EV3のキットでは3つのモーターのうち二つがNXTのようなモーターで、残りの一つがRISのようなモーターである。NXTのようなモーターは駆動に回すのでRISのようなモーターは必然的に筆に使われることが確定した。課題が発表された時点で筆を地面に押しつけ続ける必要があることはわかったし、このモーターを使うこともわかっていたのですぐにウォームギアを使おうと決めた。
授業中に解説されていたことだが、ウォームギヤは非常に強いトルクを発生させることが可能であり、そしてもう一つの特徴としてウォームギヤがかみ合っているほかのギアを回転させることはできても(今回は)逆は不可能であるということである。つまり、ウォームギヤを組み込んだ機構においてはモーターを回転させて押し続ける必要がないのでプログラムが楽であり、モーターに負荷がかからず、モーターで押し続ける機構と異なりモーターが原因のぶれも発生しないといいことずくめである。

分解等について

分解時

機体が走行中に、歪んでしまうとまっすぐ走らなくなってしまうので頑丈に作りたいが、機体を持ち運ぶためには簡単に分解して箱に収められるようにしたい。これを両立させるために機体を左右対称で作った上にユニットごとに簡単に分解できるような機体を作った。具体的にはベースユニット、左右のモーターユニット、筆ユニット、EV3、(左右のモーターをつなぐ棒一本)の実質5ユニットであるが、筆ユニットがなくても頑丈である(筆ユニットは機体強度に貢献しない、いわゆるアタッチメントのようなもの)。なのでこのユニットを取り外しても機体は頑丈で、かつ機体のスペースにも余裕がうまれるのでそのままほかの課題に流用できる。ちなみに、分解状態から筆ユニット以外のユニットで機体を組むのに必要なのは左右対称の配置の1本以外2本一セットになっている14本のピンを刺すことである。

書き順について

下に添付した画像参照(左上から書き始める)
書き順
(オレンジ色の縁取りの矢印がその動きの時の機体の向きを示している)
経路の途中にそれぞれアルファベットを振っており、プログラミングの管理や説明を容易にしている。

プログラム(syu-S_V2.py)について

初めに

(最初のプログラムは二人で作成したが、課題を勘違いしていることを発表会当日の午前中に知ったため、二人で作っていたものとは大分変ってしまっている。)
A4一面に描くものと勘違いしていたため、そのようにプログラムを書いていた。

というよりも、プログラム名からわかることだが最初 州 を書こうとしていたがよく考えたら6画であることに気づき 信 の字に変更した経緯もある。この名残でプログラム名がsyu(州)である、それを自分が調整していたためsyu-S.pyである。
当日にA4サイズではなく15兒擁だと知りそれに合わせて調整したのがsyu-S_V2.pyである。 しかし、後述の工夫があったためほとんど苦労せずにA4サイズのプログラムを15cm四方に変更することができた。

プログラムについて

こまごました前提

極力時間制御を使い、角度制御をするのは機体を旋回させるときのみとした。 調整をしやすくするために関数の引数をできるだけ減らし、また、調整が必要な数字は前もって定義しておいた。
さらに、プログラムを単純化するために直進する時間を4つ(初めは3つ)のみにして、プログラムの単純化を図った。 たまに右旋回と左旋回で一定角度旋回するのに必要な角度が異なっている機体があるので左旋回に固定して調整をすることで手間を減らした。そのため、前進しながら書いたり後退しながら書いたり、右から書いたり左から書いたり忙しく、短縮がしづらいプログラムとなってしまった。
また、機体の停止時に倒れはしなくても揺れることがあるので完全に静止する時間が多くとってある。


プログラムの解説

定数群(これからずっと使う数字はここで定義しておくとここをいじるだけでプログラムの調整ができるので非常に楽)

最初(syu-S.py)ではこの部分な次に様に定義されていた

F = 1 //FULLの略 一番長い人偏の直線部分を書くために定義された
H = 0.5 //HALFの略 言の短い様の横棒4本をかくために定義された
Q = 0.25 //QUARTERの略 口の縦棒を書くために定義された
HQ = 0.125 //HALF&QUARTERの略 言の長い横棒のために定義された
T = 185 //90°旋回時の角度の値 電圧によって微妙に変化する。

これをsyu-S_V2.pyではこう定義している

F = 0.4 
H = 0.5/2  
Q = 0.25/2 
HQ = 0.125/2

T = 175 

F以外の時間は単純に半分にしているだけである。これは半分にすれば15僂房まると判断したためである。しかし、Fの値だけはそうではない。理由は後述。(実はFは使っていない)Tの角度は充電をしたためモーターが元気になったらしく、何回か試走してみての決定。試走5回目、T=180試走6回目、T=170
試走のデータはだいたいとってあるが、きれいに分かれていたので掲載。 左は90°回転するときのモーターの回転角度(T)が180,右は90°回転するときのモーターの回転角度(T)が170°
このような結果が出たためT=175に決定した。

関数群

mw = ev3.MediumMotor('outA') //motor writeの略
mr = ev3.LargeMotor('outB') //motor rightの略
ml = ev3.LargeMotor('outC') //motor leftの略
def st(x,y): //srtraightの略。これはただ直進するための関数であり、xに-100〜100、yに秒数を入力することで前後に動ける。線を書いているときはだいたいこいつが動いている。
    mr.reset() 
        ml.reset() 
        mr.run_forever(duty_cycle_sp=x) 
        ml.run_forever(duty_cycle_sp=x) 
        time.sleep(y) 
        mr.stop(stop_command='brake') 
        ml.stop(stop_command='brake') 
        time.sleep(0.5) 
def wri(x,y):  //writeの略。筆を上下するための関数であり、実は引数無しでもよかったがなんとなく直さずに終わった。ただし、回転角度制御には絶対にしてはならない部分。
    mw.reset() 
    mw.run_forever(duty_cycle_sp=x) 
    time.sleep(y) 
    mw.stop() 
    time.sleep(0.5) 

補足 : 角度制御をここで行ったとする。○○度モーターを回転させろと命令を出すと機体はその角度回転するまでモーターを回そうとする。今回、この機構にはハード的なリミッターを設けてあるうえにウォームギヤを使用しており、非常に強い力を発揮する。もし、筆の最初の位置を間違えていて、さらに回転制御でプログラムを走らせると機体はモーターを一定角度回そうとし続けるため、歯車が壊れたり、最悪EV3本体が破損する。時間制御ならたとえまったくモーターが回っていなくても決まった時間がたてばモーターは停止するため、破損の可能性は少ない。よってこの場合角度制御は使うべきではない。

def cur(x,y,z): //カーブを描くためのプログラムxとy左右それぞれのモーターのパワーを決定することで好きな曲線が書ける。zは描く時間。
    mr.reset() 
    ml.reset() 
    mr.run_forever(duty_cycle_sp=x) 
    ml.run_forever(duty_cycle_sp=y) 
    time.sleep(z) 
    mr.stop(stop_command='brake') 
    ml.stop(stop_command='brake') 
    time.sleep(0.5) 
def turn(x): 左旋回するための関数。xの値を書きかえれば何°の左旋回でも可能である。
    mr.reset() 
    ml.reset() 
    mr.run_to_rel_pos(position_sp=x, duty_cycle_sp=30)     #sp=720 : 360度 
    ml.run_to_rel_pos(position_sp=-x, duty_cycle_sp=30) 
    time.sleep(3) 
    mr.stop(stop_command='brake') 
    ml.stop(stop_command='brake') 
    time.sleep(0.5) 

本文(プログラム内のABCDEFGは書き順の項と一致している。何かがおかしいときの問題範囲の確定がしやすくていい)

#NINBEN //読んで字のごとく、人偏を書くプログラム群である。

wri(90,3) //ペンをおろし
cur(30,40,0.3) //曲線を描き
wri(-90,3) //ペンを上げ
cur(-20,-40,0.15) //縦棒を書き始める位置へ移動し
turn(10) //角度を修正し
st(30,0.1) //位置を修正し
wri(90,3)  //ペンをおろし
st(50,H) //縦棒を書き(本来ここはFだったが調整中にHで問題ないことに気が付き変更、Fを削除し忘れた)
wri(-90,3) //ペンを上げ

ev3.Sound.speak('CHECK POINT! A')#A //周りにA地点に到達したことを知らせ

turn(T) //次への準備をして

#NINBEN OWARI //終わり

ここから口から上の点まで書きあがっていく。

#KUTI 

st(50,Q) 

ev3.Sound.speak('CHECK POINT! B')#B  

wri(90,3) 
st(50,H) 
turn(T) 
st(50,Q) 

ev3.Sound.speak('CHECK POINT! C')#C 

turn(T) 
st(50,H) 
turn(T) 
st(50,Q) 
wri(-90,3)  

ev3.Sound.speak('CHECK POINT! D')#D 

#kuti owari 

同様に口を書き終わった。ここの特色は一筆書きする口を書き終わるまでペンを上げないことである。

#OTHER//これまでと同じようなことをして書いていく

st(-50,Q+HQ) 

ev3.Sound.speak('CHECK POINT! E')#E 

turn(T) 
wri(90,3) 
st(50,H) 
wri(-90,3) 
turn(T) 
st(50,HQ) 

ev3.Sound.speak('CHECK POINT! F')#F 

turn(T) 
wri(90,3) 
st(50,H) 
wri(-90,3) 
turn(T) 
st(-50,HQ) 

ev3.Sound.speak('CHECK POINT! G')#G 

turn(T) 
st(-50,HQ) 
wri(90,3) 
st(50,HQ*2+H) 
wri(-90,3) 

ev3.Sound.speak('CHECK POINT! H')#H  

st(-50,0.15) 
turn(T) 
st(50,HQ) 
wri(90,3) 
st(50,HQ) 
wri(-90,3)
#OWARI//最後の一筆は...何でもないです

結果

結果

電圧の関係で完璧とはいかなかったもののきれいにかけたと思う

雑記

今回の課題の機体は自分が作成したものである。 自分がプログラムした信以外に、この機体を使ってbickyさんが自の字をプログラミングしている。自分が作成した機体が完全に自分の手を離れてプログラミングされるというのは初めての経験であった。
自分が使いやすいようにした仕様のようなものは、ほかの人はそうはとらえないというのは勉強になったし、改善していきたい。


添付ファイル: file6th 170.jpg 98件 [詳細] file5th 180.jpg 116件 [詳細] file本番.jpg 77件 [詳細] file分解図.jpg 83件 [詳細] file筆先.jpg 77件 [詳細] file機体.jpg 83件 [詳細] file書き順.jpg 89件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-11-18 (金) 19:05:57 (1003d)