[[2019a/Member]]

*目次 [#lcf68c24]
#contents

*課題2 [#ld3c6b79]

**課題内容 [#y676ebe3]
黒線に沿い、コースを進み途中の地点でピンポン球を掴みゴールにシュートする課題
**コース  [#tb5feb88]
大まかなコースの説明をする。&br;
A→B→C→D(一時停止あり)→E→F→G(一時停止あり)→H→I→J→K→L(ピンポン玉)→K→M(一時停止あり)→シュート→Aである。

&ref(ko-su3.png);

*制作したロボット  [#u9789d22]

機体は動かしやすいようにシンプルな機構

&ref(aa.jpg);&br;

ボールを捉えやすいようにアームを真ん中へ

&ref(aaa.jpg);&br;

差が減るようにセンサーも真ん中へ

&ref(aaaa.jpg);

*プログラム [#n9756d1c]

**始めの定義 [#ca90c30d]

ev3devのpythonライブラリ、sleep関数諸々を導入するところから始める。カラーセンサーmode = 'COL-REFLECT'では明るいほど高い値を出す。0〜100までの値である。mLは左のラージモーター、mRは右のラージモーターに対応する。mmはミディアムモーターで今回はボールを回収、放出の役割を果たす。

 #!/usr/bin/env python3
 from ev3dev.ev3 import *
 from time import sleep
 mL = LargeMotor('outA')
 mR = LargeMotor('outB')
 mm = MediumMotor('outC')
 cs = ColorSensor('in2')
 cs.mode = 'COL-REFLECT'

ロボットを動かす定義をしていく、l()は左前に進み、r()は右前に進む。time_spを小さくすることでなるべく脱線しないように配慮。f(a)は前進、b()は後退。こちらはtime_spを少し大きくしspeed_spを小さくすることでラインの値を変に読まないように配慮。
 def r():
     mL.run_timed(time_sp=1,speed_sp=550,stop_action='brake')
     mR.run_timed(time_sp=1,speed_sp=60,stop_action='brake')
 def l():
     mL.run_timed(time_sp=1,speed_sp=60,stop_action='brake')
     mR.run_timed(time_sp=1,speed_sp=550,stop_action='brake')
 def f(a):
     mL.run_timed(time_sp=10+a,speed_sp=150,stop_action='brake')
     mR.run_timed(time_sp=10+a,speed_sp=150,stop_action='brake')
 def b():
     mL.run_timed(time_sp=20,speed_sp=-50,stop_action='brake')
     mR.run_timed(time_sp=20,speed_sp=-50,stop_action='brake')
magaru(m,n,o,p)は90度回転して元の位置に戻る、というものである。magaru(1,0,0,1)で右回転、magaru(0,1,1,0)で左回転する。ziyuu(x,y,X,Y)を定義しとくことにより後々のプログラムを簡潔にする。armage()はアームをあげてボールを回収、armsage()ではアームをさげてボールを射出。
 def magaru(m,n,o,p):
     mL.run_timed(time_sp=400,speed_sp=1000*m,stop_action='brake')
     mR.run_timed(time_sp=400,speed_sp=1000*n,stop_action='brake')
     sleep(1)
     mL.run_timed(time_sp=350+o*100,speed_sp=-350,stop_action='brake')
     mR.run_timed(time_sp=350+p*100,speed_sp=-350,stop_action='brake')
     sleep(1)
 def ziyuu(x,y,X,Y):
     mL.run_timed(time_sp=x,speed_sp=y,stop_action='brake')
     mR.run_timed(time_sp=X,speed_sp=Y,stop_action='brake')
 def armage():
     mm.run_to_abs_pos(position_sp=80,speed_sp=100,stop_action="hold")
     sleep(0.1)
 def armsage():
     mm.run_to_abs_pos(position_sp=-80,speed_sp=100,stop_action="hold")
     sleep(0.1)

**ライントレース [#of609929]
ライントレースに使ったプログラムを説明する。&br;
&ref(図 1.png);
&ref(図 2.png);
~print (cs.value())でカラーセンサーの値を調べたところ赤丸1では70以上、赤丸2では50ほど、赤丸3では10以下であることが分かった。図1ではcs.value()の値が50ほどで前進させ、図2はcs.value()の値が20以下の時右前に進ませて、図3では60以上の時左前に進ませる。図4ではcs.value()の値が70以上で後退させる。なおこの基準ではかなりの範囲でかぶっているので、elifを使うことでその問題を解決した。これによりおおまかな値で定義し、より正確にラインをたどれるようにした。なお最初にst=cs.value()と書き、whileの中にne=cs.value()を入れ、whileの最後にst=neと書くことで前回計測したcs.value()を保持することが出来た。これにより図5では連続的、つまり2回黒を計測するとL字や十字路と判断するようにした。
~print (cs.value())でカラーセンサーの値を調べたところ赤丸1では70以上、赤丸2では50ほど、赤丸3では10以下であることが分かった。図1ではcs.value()の値が50ほどで前進させ、図2はcs.value()の値が20以下の時右前に進ませて、図3では60以上の時左前に進ませる。図4ではcs.value()の値が70以上で後退させる。なおこの基準ではかなりの範囲でかぶっているので、elifを使うことでその問題を解決した。これによりおおまかな値で定義し、より正確にラインをたどれるようにした。

なお最初にst=cs.value()と書き、whileの中にne=cs.value()を入れ、whileの最後にst=neと書くことで前回計測したcs.value()を保持することが出来た。これにより図5では連続的、つまり2回黒を計測するとL字や十字路と判断するようにした。この2回計測させる、ということが1番の工夫である、1度ではカーブ時などに勘違いしてL字や十字路だと思い誤作動を起こすが二回黒のかなり低い値、st<10 and ne<10にしておくことで誤作動が激減した。

ganbaru()関数は最初にs=0を置き、黒二回計測、つまり交差点or”「 ” この形の時にsに1を加える、if,elif,elseを使い、ライントレースを制御、sが2以上になればwhileから抜けだし動作終了。細かいライントレースに用いる。(主にゴール前)

ganbare()関数は基本的にはganbaru()関数と同じで、BからIに移動させるためtの限界値はaと設定し、長めにライントレース、つまり交差点or”「 ” の形を何度も計測し動作し続けるものとなっている。これを実現するために siraberu()関数を定義し組み込んである、これは後述する。


 def ganbaru():
         s=0
         st=cs.value()
         while s <= 1:
             ne=cs.value()
             if st>70 or ne>70:
                 b()
             elif st<10 and ne<10:
                 s=s+1
                 sleep(1)
             elif ne>60:
                 l()
             elif ne<20:
                 r()
             else:
                 f(0)
             st=ne
 
 
 def ganbare(a):
         t=0
         st=cs.value()
         while t <= a:
             ne=cs.value()
             if st>70 or ne>70:
                 b()
             elif st<10 and ne<10:
                 siraberu()
                 sleep(3)
                 t=t+1
             elif ne>60:
                 l()
             elif ne<20:
                 r()
             else:
                 f(0)
             st=ne


siraberu()関数を説明する。

&ref(図111.png);

図のように黒を二度観測、つまり交差点or”「 ” の形、Tにあたれば、まず右前に移動し左右に首を揺らし、二つ目の赤の地点と矢印の地点、左、右のcs.value()を観測する、それぞれ順番にss0、ss1、ss2と定義する。そして一旦元の位置に戻り、ss0、ss1、ss2の値によって行動を分岐させる。

図のように交差点であれば左は黒を観測し右は何も観測しない、この場合はD地点でおこる、すなわち前進させる必要がある。elseで対応させ、 f(300)前進。簡単に説明したのが下図である。

&ref(図あうあう.png);
&ref(ううう図.png);

なお出っ張りがない部分は円のところもあり、誤作動がないようこまかく調整した。if ss0 > 65 and ss1 > 70 and ss2 > 65;においてmagaru(1,0,0,1)、つまり90度旋回する様になっている。

これらによって交差点or”「 ” の形、Tに完全に対応させた。
 def siraberu():
      mR.run_timed(time_sp=400,speed_sp=200,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=100,stop_action='brake')
      sleep(0.4)
      ss0=cs.value()
      sleep(0.5)
      mR.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
      sleep(0.4)
      ss1=cs.value()
      sleep(0.5)
      mR.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
      sleep(0.4)
      mR.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
      sleep(0.4)
      ss2=cs.value()
      sleep(0.5)
      mR.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
      sleep(0.4)
      mR.run_timed(time_sp=400,speed_sp=-200,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=-100,stop_action='brake')
      sleep(1)
      while True:
          if ss0 > 65 and ss1 > 70 and ss2 > 65:
              sleep(1)
              magaru(1,0,0,1)
              break
 
          else:
              f(300)
              break


**実装プログラム [#qcba070e]
プログラム全文は以下に記載する。
 #!/usr/bin/env python3
 from ev3dev.ev3 import *
 from time import sleep
 mL = LargeMotor('outA')
 mR = LargeMotor('outB')
 mm = MediumMotor('outC')
 cs = ColorSensor('in2')
 cs.mode = 'COL-REFLECT'
 
 
 def r():
     mL.run_timed(time_sp=1,speed_sp=550,stop_action='brake')
     mR.run_timed(time_sp=1,speed_sp=60,stop_action='brake')
 def l():
     mL.run_timed(time_sp=1,speed_sp=60,stop_action='brake')
     mR.run_timed(time_sp=1,speed_sp=550,stop_action='brake')
 def f(a):
     mL.run_timed(time_sp=10+a,speed_sp=150,stop_action='brake')
     mR.run_timed(time_sp=10+a,speed_sp=150,stop_action='brake')
 def b():
     mL.run_timed(time_sp=20,speed_sp=-50,stop_action='brake')
     mR.run_timed(time_sp=20,speed_sp=-50,stop_action='brake')
 def magaru(m,n,o,p):
     mL.run_timed(time_sp=400,speed_sp=1000*m,stop_action='brake')
     mR.run_timed(time_sp=400,speed_sp=1000*n,stop_action='brake')
     sleep(1)
     mL.run_timed(time_sp=350+o*100,speed_sp=-350,stop_action='brake')
     mR.run_timed(time_sp=350+p*100,speed_sp=-350,stop_action='brake')
     sleep(1)
 def ziyuu(x,y,X,Y):
     mL.run_timed(time_sp=x,speed_sp=y,stop_action='brake')
     mR.run_timed(time_sp=X,speed_sp=Y,stop_action='brake')
 def armage():
     mm.run_to_abs_pos(position_sp=80,speed_sp=100,stop_action="hold")
     sleep(0.1)
 def armsage():
     mm.run_to_abs_pos(position_sp=-80,speed_sp=100,stop_action="hold")
     sleep(0.1)
 
 
 def siraberu():
      mR.run_timed(time_sp=400,speed_sp=200,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=100,stop_action='brake')
      sleep(0.4)
      ss0=cs.value()
      sleep(0.5)
      mR.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
      sleep(0.4)
      ss1=cs.value()
      sleep(0.5)
      mR.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
      sleep(0.4)
      mR.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
      sleep(0.4)
      ss2=cs.value()
      sleep(0.5)
      mR.run_timed(time_sp=400,speed_sp=120,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=-120,stop_action='brake')
      sleep(0.4)
      mR.run_timed(time_sp=400,speed_sp=-200,stop_action='brake')
      mL.run_timed(time_sp=400,speed_sp=-100,stop_action='brake')
      sleep(1)
      while True:
          if ss0 > 65 and ss1 > 70 and ss2 > 65:
              sleep(1)
              magaru(1,0,0,1)
              break
 
          else:
              f(300)
              break
 
 def ganbaru():
         s=0
         st=cs.value()
         while s <= 1:
             ne=cs.value()
             if st>70 or ne>70:
                 b()
             elif st<10 and ne<10:
                 s=s+1
                 sleep(1)
             elif ne>60:
                 l()
             elif ne<20:
                 r()
             else:
                 f(0)
             st=ne
 
 
 def ganbare(a):
         t=0
         st=cs.value()
         while t <= a:
             ne=cs.value()
             if st>70 or ne>70:
                 b()
             elif st<10 and ne<10:
                 siraberu()
                 sleep(3)
                 t=t+1
             elif ne>60:
                 l()
             elif ne<20:
                 r()
             else:
                 f(0)
             st=ne
 
導入と先ほど説明した定義である。
 ganbare(6)
 sleep(1)
BからHに移動、ここが最も難所で成功率は高くない。
 ganbaru()
 sleep(1)
HからJに移動
 magaru(1,0,0,1)
 sleep(1)
90度回転
 ganbaru()
 sleep(1)
JからKに移動
 magaru(0,1,1,0)
 sleep(1)
90度回転
 f(50)
 sleep(1)
 
 armage()
玉を回収する、この部分も誤差が大きい時は回収出来ない。
 ganbare(1)
 sleep(1)
 
 armsage()
ゴールまで行き、アームを下ろした。
 
*反省 [#d6316867]

課題達成に必死、自己流の工夫が余りできていない。ロボットの形は機構だったが、プログラムが全く機能しないなどの苦労が多かった。ライントレースが正確になるまでの調整が特に大変。難所の円部分で誤作動する可能性が高いことを解決出来なかった

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