#contents *ロボットの全体像 [#eacb7d78] 前回の人の顔を描くロボットをベースにして、ライントレースロボットを作る。~ ~ 前回の顔を描くロボットの図(センサー系の取り外しがやりやすいように、接続する部分を工夫してあった。)~ #ref(./ロボットの全体像.JPG) ~ ↓~ ~ 今回のロボットの図~ #ref(./1.jpg,サイズ,画像の説明) ~ タッチセンサを用いたロボットも課題になっているので、前回と同様、機構のつけたり外したりのしやすさを重視する。~ ~ また、できるだけライントレースの白黒の見分けが正確になるように、ライトセンサーを紙面に近づけるように工夫した。~ ~ ライトセンサーを接写した図~ #ref(./2.jpg) ~ ライトセンサーと紙面の距離は約1cmである。あまり近すぎず、かつ、十分に白黒を判断可能な距離であると判断した。~ ~ *今回達成するべき課題 [#cba4a907] #ref(./課題.png) A地点からB地点へ (一人目) A地点 → P直進 → Q直進 → Q直進 → R左折 → B地点 3人で構成された班であったので、それぞれのメンバーで達成するべきコースを振り分けた~ ~ 自分はAコースを担当することになったので、Aコースについて記述していく~ ~ *ロボットを動かす基本の考え方 [#d777e0bf] ロボットにライントレースをさせるにあたって必要となる動作を考える。~ ~ 今回必要となる主な動作は~ ~ ・白を感知したら左にハンドルを切る ・黒を感知したら右にハンドルを切る ~ これらの動作の組み合わせで、白と黒の境界線をじぐざぐに進むことが可能となる。~ ~ また、その他細かいプログラムをすることで、課題を完成させる。~ ~ *プログラム本体[#j96e677b] 今回は、交差点の回数がわかっているので~ ~ ・交差点でのモーターの動き~ ・ライントレース ~ ~ の動作をサブルーチンとする~ ~ このときの定義文は以下のとおりである~ ~ 交差点でのモーターの動き def cross(t,dl,dr): mr.run_forever(duty_cycle_sp=dr) ml.run_forever(duty_cycle_sp=dl) time.sleep(t/1000) ml.stop() mr.stop() ~ ライントレース(このプログラムで白、黒の境界をジグザグに進むことができる) def line(): t0 = time.time() while time.time() - t0 < 0.35: if cs.value () > 50 : mr.run_forever(duty_cycle_sp=-30) ml.run_forever(duty_cycle_sp=60) t0 = time.time() else: mr.run_forever(duty_cycle_sp=60) ml.run_forever(duty_cycle_sp=-30) ~ ライントレースについてのみ上記のプログラムの若干の説明を加える~ ~ 上記のプログラムでは、~ t0 = time.time() while time.time() - t0 < 0.35: によってこのプログラムが更新されない限り、0.35秒で終了することを示す~ ~ if cs.value () > 50 : mr.run_forever(duty_cycle_sp=-30) ml.run_forever(duty_cycle_sp=60) t0 = time.time() ~このif文を用いて、黒になったとき(cs.valueが50以上になったとき)右に曲がったうえで、プログラムを最初からやり直す~ ~ else: mr.run_forever(duty_cycle_sp=60) ml.run_forever(duty_cycle_sp=-30) このelse文を用いて、黒になっていないとき(cs.valueが49以下であるとき)左に曲がったうえでプログラムの更新がされない~ ~ すなわち、黒の状態が0.35秒以上続いた場合、左に曲がりながらプログラムが停止して次に書いてあるプログラムに移行することができる。~ ~ この二つの関数の組み合わせで、代入する数値を微調整することで課題2のクリアを目指した。 ~ *一個目のプログラム [#q01674c3] チーム内でそれぞれのメンバーでコースを割り振り、自分はAコースのクリアを目指した ここで、一回目に課題をクリアすることのできたプログラムを掲載する #!/usr/bin/python import ev3dev.ev3 as ev3 import time ml = ev3.LargeMotor('outA') mr = ev3.LargeMotor('outB') cs = ev3.ColorSensor('in1') def line(): t0 = time.time() while time.time() - t0 < 0.35: if cs.value () > 50 : mr.run_forever(duty_cycle_sp=-30) ml.run_forever(duty_cycle_sp=60) t0 = time.time() else: mr.run_forever(duty_cycle_sp=60) ml.run_forever(duty_cycle_sp=-30) def cross(t,dl,dr): mr.run_forever(duty_cycle_sp=dr) ml.run_forever(duty_cycle_sp=dl) time.sleep(t/1000) ml.stop() mr.stop() mr.stop() ml.stop() line() cross(1000,0,0) cross(1000,17,-17) cross(1000,13,13) line() cross(1000,0,0) cross(1000,17,-17) cross(1000,13,13) line() cross(1000,0,0) cross(1000,17,-17) cross(1000,13,13) line() cross(1000,0,0) cross(1000,17,-17) cross(1000,13,13) line() cross(1000,0,0) cross(1000,17,-17) cross(1000,-30,30) line() cross(1000,0,0) cross(1000,17,-17) cross(1000,13,13) ~ 今回の自分のスコアとして、Aコース達成に1分10秒かかった~ ~ プログラムの説明として、「line」によってライントレースを行い、~ ~ 「cross」によって交差点で一秒間止まって、角度をまっすぐに修正したり右に曲げたりしている~ ~ このプログラムを用いれば、Aコースは指定された手順通りクリアすることはできる~ ~ しかし、このプログラムでは「cross」の文で一回一回何をしているのかがわかりにくいという難点がある~ ~ よって、サブルーチンを増やすことでよりプログラムを簡略化してみようと考えた~ *サブルーチンの工夫によるプログラムの簡略化 [#d5711b90] まず、1秒間止まるのにわざわざ「cross」を用いるのは区別がつかなくなるので一秒間止まるためのサブルーチンを作った。~ def wait(): mr.run_forever(duty_cycle_sp=0) ml.run_forever(duty_cycle_sp=0) time.sleep(1) これによって、ライントレースが終了した後「wait()」を書き込むだけで1秒間止まることが可能となると考えた~ ~ ~ ~ また、すべて左に曲がって止まるようなプログラムとなっているので、すべての交差点で左に曲がった状態で止まることになる~ ~ そこで、毎回の交差点で「turn」というサブルーチンを設け、「cross」で一回一回回転数を指定しなくてもよいようにしようとした~ ~ 以下が「turn」のプログラムである~ def turn(): mr.run_forever(duty_cycle_sp=17) ml.run_forever(duty_cycle_sp=-17) time.sleep(1) ~ これらのサブルーチンを用いて改良したプログラムを以下に掲載する ml = ev3.LargeMotor('outA') mr = ev3.LargeMotor('outB') cs = ev3.ColorSensor('in1') def line(): t0 = time.time() while time.time() - t0 < 0.35: if cs.value () > 50 : mr.run_forever(duty_cycle_sp=-30) ml.run_forever(duty_cycle_sp=60) t0 = time.time() else: mr.run_forever(duty_cycle_sp=60) ml.run_forever(duty_cycle_sp=-30) def cross(t,dl,dr): mr.run_forever(duty_cycle_sp=dr) ml.run_forever(duty_cycle_sp=dl) time.sleep(t/1000) ml.stop() mr.stop() def wait(): mr.run_forever(duty_cycle_sp=0) ml.run_forever(duty_cycle_sp=0) time.sleep(1) def turn(): mr.run_forever(duty_cycle_sp=17) ml.run_forever(duty_cycle_sp=-17) time.sleep(1) mr.stop() ml.stop() line() wait() turn() cross(1000,13,13) line() wait() turn() cross(1000,13,13) line() wait() turn() cross(1000,13,13) line() wait() turn() cross(1000,13,13) line() wait() turn() cross(1000,-30,30) line() wait() turn() cross(1000,13,13) 以上のサブルーチンを用いてプログラムを作成したが、おそらく「wait」のサブルーチンで、前項のサブルーチンを延々継続してしまっているような挙動を見せてうまくいくことはなかった~ ~ 原因としては、プログラムの順序と必要な記号、文についての把握が足りていなかったと思われる~ *交差点で音声を出す [#h918806f] EV3は英語を話すことができる~ ~ よってそれを利用して交差点で右折なら「right」左折なら「left」直進なら「straight」、ゴールについたときに「goal」と発するようにプログラムした~ ~ EV3に話させるための関数は oto = ev3.Sound() で定義して oto.speak('').wait() と入力したのち、「’’」の中に好きな単語を入力する~ ~ これを用いて先ほどのプログラムを実行させて成功した~ ~ すべてを掲載すると長くなるので割愛する~ ~ なお、ベースのプログラムはサブルーチンを改良する前のプログラムを用いたので動作に問題はなかった~ ~ *Mission2のまとめ [#k0cbbaf5] 今回は、ITピアサポートに聞きに行ったおかげもあって、課題をすんなりクリアすることができたと思う しかし、課題の内容としてプログラムが少しわかりにくかったという難点がある 今後への反省として、プログラムをわかりやすくするために文の構造をしっかりと把握し 一つのサブルーチンで3個ぐらいの動作をまとめてやってくれるプログラムを作りたいと思う