目次
#contents

*課題1 [#c7962be7]
これまで住んだことのある都道府県名、市町村名、地区名などの中から2文字以上、かつ合計10画以上のものを選び、それをA4の紙を書くロボットを製作せよ。
* ロボットの説明 [#saf2230c]
** 目的 [#f63ee3a3]
このロボットは、授業で扱ったEV3の車型のロボにペンの昇降機能を持たせたパーツを組み合わせたものである。車型を採用した理由は、左右の車輪を回す角度次第で、直線はもちろん、曲線も書くことができるからである。今回は自分と相方の書く字が大垣と香川であり、双方の字に曲線が含まれているので、キレイな曲線を描くプログラムをする必要があった。
** 外観 [#pa57bff9]
初期の車型から今回不要と思われるパーツは除外した。

縦26.5cm,横14.5cm,高さ18.5cm

&ref(2018b/Member/miyashi/Mission1/s_DSC_0544.JPG,100%,外観);
&ref(2018b/Member/miyashi/Mission1/s_DSC_0550.JPG,100%,側面1);
&ref(2018b/Member/miyashi/Mission1/s_DSC_0552.JPG,100%,側面2);
&ref(2018b/Member/miyashi/Mission1/s_DSC_0553.JPG,100%,上から);
** 昇降機について [#i5b11051]
車の説明は割愛するとして、車に設置したペンの昇降機について説明する。MediumMotorとギア二つを組み合わせて作ったものがこれである。左がペンの上がっている状態、右が下がっている状態である。Motorを回すと駆動歯車と被動歯車についたマジックアームが上下に動く。マジックアームの先端とペンをゴムで固定してある。

&ref(2018b/Member/miyashi/Mission1/s_DSC_0543.JPG,100%,正面からの写真上);
ーMediumMotorを30度回転してペンを降ろす→
&ref(2018b/Member/miyashi/Mission1/s_DSC_0548.JPG,100%,正面からの写真下);

中が空洞になっている長方形のパーツをつけたのは、ペンの上げすぎや下げすぎを防ぐためである。上から下まで、MediumMotorを30度動かすとぴったり移動する。ペンはゴムで固定するつもりだったが、ゴムが思いの外緩かったため、太いマジックペンを使用した。昇降機自体は、車につけた時にかなり不安定だったため、車との接合部分を増やして補強したが、かえってMediumMotorが重くなってしまい十分に動かなかった。そこで、補強の増設はやや不安定な状態でMediumMotorを円滑に動かすことができる状態に妥協した。

* 書く文字と書き順 [#uff5caaf]
書く文字は大垣(岐阜県大垣市)である。本来の字の書き順でなく、今回は以下のような書き順にした。(この画像はロボットで書いた字ではない。)垣に関しては、横棒が多いため、プログラム短縮化のために一度にまとめて横棒を書いた。

&ref(2018b/Member/miyashi/Mission1/s_DSC_0545.JPG,100%,書き順);
* プログラムの説明 [#q8f6b8c4]
** プログラムの前に [#a40b147a]
以下を入力した。
 #!/usr/bin/env python3
 from ev3dev.ev3 import *     
 from time import sleep       #sleep関数をインポート
 ml = LargeMotor('outA')   #左側の車輪を動かすモーターをml
 mr = LargeMotor('outB')   #左側の車輪を動かすモーターをmr
 mm = MediumMotor('outD')   #昇降機に使用するモーターをmm      とした。

** 定義した関数 [#p2fb9c45]
定義した関数は全部で5つ。

モーターをリセットする関数である。適宜、利用するために作った。
 def motor_init():
     ml.reset()
     mr.reset()

ペンの上げ下げの関数である。pen_upはペンを上昇させ、pen_downはペンを下降させる。
 def pen_up():
     mm.run_to_rel_pos(position_sp=30, speed_sp=400, stop_action='hold')
     sleep(2)
 def pen_down():
     mm.run_to_rel_pos(position_sp=-30, speed_sp=400, stop_action='hold')
     sleep(2)

車体の向いている角度を変える関数である。動くスピードが速いと、止まるときにややずれるので、スピードは遅い100で設定した。
 def angle(left,right):
     ml.run_to_rel_pos(position_sp=left, speed_sp=100, stop_action='hold')
     mr.run_to_rel_pos(position_sp=right, speed_sp=100, stop_action='hold')
     sleep(3)

車体を動かすメインの関数である。左右それぞれの回転角度とスピードを細かく操るために、やや面倒ではあるが、4つの変数を用いた。今回のコンセプトである曲線を描くのには4つの変数で表現する必要があった。曲線に限らず、単純な前進や後進もこの関数を使用する。
 def forward(l,r,ls,rs):
     ml.run_to_rel_pos(position_sp=l, speed_sp=ls, stop_action='hold')
     mr.run_to_rel_pos(position_sp=r, speed_sp=rs, stop_action='hold')
     sleep(3)

なお、angleはforwardでも代用可能だが、プログラミングの際、角度だけを変えたい時に一回一回スピードまで入力するのは手間だったため、スピードを固定した関数を定義した。
** それぞれの文字 [#lc8e727b]
*** 大について [#ua0955a3]
 motor_init()
 mm.run_to_rel_pos(position_sp=-35, speed_sp=400, stop_action='hold')  #ペンを下げる。筆圧をかけるために最初のペン下降だけ少し角度を大きく設定し、ペンを紙に確実に設置させる。この角度の動きはここだけのため関数は定義しなかった。
 sleep(2)
 forward(-200,-200,200,200)     #一画目(大の横棒)
 motor_init()
 pen_up()                       
 angle(80,-80)                  #二画目を書くための角度調整。やや右を向く。
 forward(-350,-350,400,400)     #二画目を書くための位置調整。
 motor_init()
 angle(200,0)                   #更にもう一度角度調整。やや右を向く。
 forward(340,340,400,400)       #先ほどに近い位置に戻ってくる。
 motor_init()
 pen_down()                     
 forward(220,100,220,100)       #二画目を書く。左右の回転角度、スピードを調節し、曲線を描いた。
 motor_init()
 forward(70,70,200,200)         #二画目のうちの縦棒部分(大の文字の横棒の上に出ている部分)を描く。
 motor_init()
 pen_up()
 forward(-60,-60,200,200)       #縦棒と横棒の交点まで進む。
 motor_init()
 pen_down()
 forward(-100,-220,100,220)     #三画目を書く。曲線のため先程と同様に角度とスピードを調節した。
 motor_init()
 pen_up()
 forward(100,230,100,230)       #三画目を書く前の位置まで戻る。
 motor_init()
 angle(0,38)                    #車体を紙と並行にする。
*** 垣について [#z9eaf2b4]
 motor_init()
 forward(-400,-400,400,400)     #垣の字を書くために紙の下部まで進む。
 pen_down()
 forward(160,160,100,100)       #四画目を書く。
 pen_up()
 motor_init()
 angle(-195,195)                #五画目を書くための角度調整。angle(-195,195)で直角に曲がる。以後、角度微調整のために195前後の値でangleに設定してある部分もある。
 motor_init()
 forward(-80,-80,100,100)       #垣の中の日の字の縦棒二本の間隔を70開ける。
 angle(193,-193)                #直角よりやや多く曲げる。縦棒とほぼ平行になる。
 motor_init()
 forward(-160,-160,100,100)     #五画目の書き始め位置まで移動。
 pen_down()
 motor_init()
 forward(160,160,100,100)       #五画目を書く。
 pen_up() 
 motor_init()
 forward(-300,-300,100,100)     #六画目を書くための位置移動。進む。
 sleep(2)
 motor_init()                   
 angle(-210,210)                #左にやや直角より多く曲げる。先程、210曲げたので同じ角度回転させて採算を取る。
 sleep(2)
 motor_init()
 forward(210,210,100,100)       #六画目の書き始め位置まで移動。
 sleep(2)
 pen_down()
 motor_init()
 forward(80,80,100,100)         #六画目(横棒)を書く。
 pen_up()
 motor_init()
 angle(200,-200)                #縦棒と並行にする。
 motor_init()
 forward(-80,-80,100,100)       #六画目と七画目の間隔を空けるために50進む。
 motor_init()
 angle(-200,200)                #先程と同様に200回転して採算を取る。
 motor_init()
 forward(-110,-110,100,100)     #日の字の右にある縦棒の先端部分と交わるように書き始め位置を調節。
 motor_init()
 pen_down()
 forward(80,80,100,100)         #二本の縦棒の先端部分を横断するように進みながら七画目を書く。
 motor_init()
 pen_up()
 forward(80,80,100,100)         #七画目と八画目の間隔を80空ける。
 motor_init()
 pen_down()
 forward(80,80,100,100)         #80の長さで八画目を書く。
 motor_init()
 pen_up()
 forward(-120,-120,100,100)     #再び日の部分の横棒を書くために少し戻る。
 angle(200,-200)                #同様に、200回転して縦棒と並行にする。
 motor_init()
 forward(-80,-80,100,100)       #隣り合う横棒である七画目と九画目の間を70空ける。
 motor_init()
 angle(-200,200)                #200回転して採算を取る。
 motor_init()
 forward(-120,-120,100,100)     #右の縦棒の上から九画目を書くために位置を調節する。
 pen_down()
 motor_init()
 forward(80,80,100,100)         #80の長さで九画目を書く。
 pen_up()
 motor_init()
 angle(200,-200)                #再び縦棒と並行にする。
 motor_init()
 forward(-70,-70,100,100)       #九画目と十画目の間隔を70空けるために進む。
 motor_init()
 angle(-200,200)                #同様に、採算を取り、回転する。
 motor_init()
 forward(-50,-50,100,100)       #右の縦棒の上から十画目を書くために位置を調節する。
 pen_down()
 motor_init()
 forward(80,80,100,100)         #80の長さで進み、十画目を書く。
 pen_up()
 motor_init()
 forward(80,80,100,100)         #十画目と十一画目の間隔を80空ける。
 pen_down()
 motor_init()
 forward(80,80,100,100)         #80の長さで十一画目を書く。
 pen_up()
 motor_init()
 forward(-160,-160,100,100)     #日の下にある部分の横棒を書くために少し戻る。
 motor_init()
 angle(200,-200)                #縦棒と並行にする。
 motor_init()
 forward(-80,-80,100,100)       #十画目と十二画目の間隔を空けるために80進む。
 motor_init()
 angle(-200,200)                #同様に、採算を取る。
 motor_init()
 forward(-100,-100,100,100)     #十二画目の書き始め位置の調節。
 pen_down()
 motor_init()
 forward(120,120,100,100)       #十二画目を書く。垣の字を忠実に再現しようとすると、日の下にある横棒はやや長いので従来の80ではなく120進む。
 pen_up()
 motor_init()
 forward(-230,-230,200,200)     #230戻る。これは次の角度調整をした後の垣の土へん部分の横棒(八画目と十一画目)を横断する縦棒(十三画目)の書き始め位置を整えるためである。
 motor_init()
 angle(-195,195)                #直角に回転。
 motor_init()
 pen_down()
 forward(200,200,100,100)       #十三画目を書く。土へんの縦棒の部分であり、横棒二本を横断する。
 motor_init()
 pen_up()            #作業終了。
* 実際に書けた文字 [#pf5a5d07]
**失敗 [#t0959938]
angleやforwardの数値を変えて試行錯誤した結果である。本当はもっと失敗例はあるのだがこれはまだましなものである。いまいち、大垣と読めなくもないような気がするが成功とは言い難い。

&ref(2018b/Member/miyashi/Mission1/fail1.JPG,100%,失敗1);
&ref(2018b/Member/miyashi/Mission1/fail2.JPG,100%,失敗2);
**成功 [#n672b657]
試行した中で最もましな大垣である。この字を書いた時のプログラムが上記と同一のものである。

&ref(2018b/Member/miyashi/Mission1/success.JPG,100%,成功);

どう見ても大垣。

実際に書いた動画があるので以下にURLを貼る。https://www.youtube.com/watch?v=xyQf8yz8pHs
** 本番で書いた文字 [#mcff32fb]
一番の成功とは言い難いが、まだ読めるレベルではある。土へんが失敗してしまった。13画目の縦棒の位置がずれたのは、13画目までの小さなずれが積み重なった結果だと考える。
&ref(2018b/Member/miyashi/Mission1/s_DSC_0566.JPG,100%,本番);
* 考察 [#n6c5e777]
** 欠点 [#t11cf6b2]
同じコマンドを与えても試行ごとに動きが異なり、一回として全く同じ字を書けないという問題がある。異なる動きは、angleでとりわけ発生しやすく、車を直角に曲げようと、angle(195,-195)と入力しても、80〜100度の範囲で曲がり、そこで生まれたばらつきが後に影響した結果、綺麗な字が書けない。試行を重ねるごとに気付いたことは、EV3のバッテリー残量が曲がる角度と関係していることである。残量が多いほど角度は大きくなり、少ないほど小さくなる。よって実際に動く角度は試行を重ねるごとに変化して字も綺麗に書けないため、バッテリー残量に応じてその都度新しく角度を設定し直す必要があり、非常に面倒である。車型を採用したデメリットである。
** 改善案 [#r68dcb17]
先述の欠点が大きく影響したのは、「垣」である。字を書くプロセスで90度向きを変える動きが何回も必要となる。そのときに、やはりずれが少しずつ影響して字が崩れてしまう。車型という構造上、向きを変える動きはangleの動きしかないと思う。なんとかして改善するならば、バッテリー残量がどれくらいの時に回転の角度が何度であるかをそれぞれ調べる必要があるのではないか。そこまで試行する時間が今回はないため断念するしかないのが残念だ。
* 余談 [#ef82db37]
今回、試行を重ねる時に度々、昇降機についたペンが重力によって少し落ちてくることがあった。(初期の状態ではペンが上にあるべき。)少し落ちた状態では文字書きを開始した時に、30度分ペンを下げる動きが必要以上の動きになってしまい、パーツ同士がぶつかり、パーツの負荷が大きくなる問題があった。そこで、以下のプログラムを作り、落ちたペンを必要な角度だけモーターを回して一番上の初期位置まで移動させることを可能にした。
 #!/usr/bin/env python3 from ev3dev.ev3 import *
 from time import sleep
 mm = MediumMotor('outD')
 mm.reset() 
 a = input("motiagerukakudo(30)to(-30)")
 mm.run_to_rel_pos(position_sp=a, speed_sp=100, stop_action='hold')
このコマンドを実行すると、しばらく経ってコマンドプロンプトの画面に

motiagerukakudo(30)to(-30)

と表示される。ここでMediumMotorを回したい角度の分、数値を入力するとその値だけ回転する。一回一回、ペンを上げ下げしたい角度が異なるので、一つのプログラムでその都度、角度を操ることができるこのプログラムは重宝した。
* 感想 [#sdf2b6ac]
今回上手く字が書けなかったのは車型にしたことだ。確かに綺麗な曲線を描くには車型は最適であるが、肝心の直線の管理がずさんになってしまうことに気付くのが早ければ良かった。綺麗な直線を描くには他班のように、キャタピラを使うのが正解だったかもしれない。いづれにしても。今回の課題で基本的なプログラミングを理解することが出来たので、次回はもっと扱いやすいロボットを作って課題に取り組みたいと思う。
*その他 [#jb33a70c]
閲覧回数
総計:&counter(total); 今日:&counter(today); 昨日:&counter(yesterday);

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS