今回は黒と白の境界線をトレースするロボットを作成した。

*概要 [#j3992d6b]

**ロボット本体 [#ued17a89]
#ref(./IMG_6807.JPG,50%,)
   ↑全体図
#ref(./IMG_6811.jpg,50%,)
�ゝ‖慮緤�に右タイヤ←プログラム内ではmr~
�◆    〆献織ぅ笄�ml~
�5‖涼羆�に地面に向けてカラーセンサーを設置←cs~
�さ‖料以�部分にアームを設置← ma~

*アームの機構について [#s74434b5]
#ref(./IMG_6808.JPG,50%,)

アームの機構について
2つの歯車の間に一つのモーターを設置して動かす。この時、左側の歯車は右回転、右側の歯車は左回転をする。よって、歯車に取り付けられたアームを閉じることができる。

**コース [#jdb5b2d2]
#ref(./2018a-mission2.png,50%)
 1.Aをスタート
 2.Bを直進
 3.Cで一時停止の後、直進
 4.Dで一時停止の後、Xの空き缶をキャッチしてD地点に戻る
 5.DからEに向かい、Eを直進
 6.Fを左折
 7.Gで一時停止の後、左折
 8.Hで一時停止の後、右折
 9.Iで一時停止の後、右折
 10.Lを直進
 11.Kを直進
 12.Jで一時停止の後、空き缶をYに置きてJに戻りBに向かう
 13.Bで一時停止の後、左折
 14.Aで停止

**プログラミング [#jacb52b4]
大きく分けてライントレース、交差点での動き、紙コップをつかんでルートに戻るためのプログラムを作成した。

*ライントレース [#o04ee9f2]
 はじめは黒の線に対して左側の端をジグザグに指定した時間動き、その後黒の上に一定時間いるときに停止するようにしたものを作成した。しかし、特定のエリアで道を見失う確率が非常に高くなってしまった。そこで、右側の端をトレースするプログラムを作成し、この2つを使い分けることで成功率が飛躍的に上がった。
 
 試行錯誤を繰り返している最中にどうしても継続時間がカーブで長くなってしまい、止まってしまった。そこで、ある時間まではひたすらコースを逸れずに同じ色の領域にいても線の境界に無理矢理にでも戻るようにした。
 
cs.value ←カラーセンサーの値を示す。30以下なら黒、30より大きければ白とここでは定義する

左側をトレースするプログラム(tが境界に居続ける時間、sがt秒以降、s秒以上同じ色の領域にいると止まる。)

 def sharpstop_line(t,s):
  t0 = time.time()
  t1 = time.time()
  while t0 - t1 < t: //開始からt秒以下の時
        t0 = time.time()
        if cs.value() <=30: //カラーセンサーの値が30以下であるか判定する
         while cs.value() <=30:
                   ml.run_forever(speed_sp= -25) //30以下であるとき左折
                   mr.run_forever(speed_sp= 100)
        elif cs.value() >30: //カラーセンサーが30より大きいか判定
         while cs.value() >30:
                     ml.run_forever(speed_sp= 100) //その時、右折する
                     mr.run_forever(speed_sp= -25)
  ml.stop() //開始からt秒以上の時一度停止
  mr.stop()
  s0 = time.time()  
  s1 = time.time()
  while s0 - s1 < s: //同じ色にいる時間がs秒以下のとき
       s1 = time.time() 
       if cs.value() <=30:
          while cs.value() <=30:
                   ml.run_forever(speed_sp= 100)
                   mr.run_forever(speed_sp= -25)
                   s0=time.time()
       elif cs.value() >30:
            while cs.value() >30:
                     ml.run_forever(speed_sp= -25)
                     mr.run_forever(speed_sp= 100)
                     s0=time.time()
  ml.reset() //s秒以上同じ領域にいるとき停止する
  mr.reset()
  sleep(1)


右をトレースするプログラム(tが境界に居続ける時間、sがt秒以降、s秒以上同じ色の領域にいると止まる。)

 def rev_sharpstop_line(t,s):
  t0 = time.time()
  t1 = time.time()
  while t0 - t1 < t:
        t0 = time.time()
        if cs.value() <=30:
         while cs.value() <=30:
                   ml.run_forever(speed_sp= 100)
                   mr.run_forever(speed_sp= -25)
        elif cs.value() >30:
         while cs.value() >30:
                     ml.run_forever(speed_sp= -25)
                     mr.run_forever(speed_sp= 100)
  ml.stop()
  mr.stop()
  s0 = time.time()
  s1 = time.time()
  while s0 - s1 < s: 
       s1 = time.time()
       if cs.value() <=30:
          while cs.value() <=30:
                   ml.run_forever(speed_sp= -25)
                   mr.run_forever(speed_sp= 100)
                   s0=time.time()
       elif cs.value() >30:
           while cs.value() >30:
                     ml.run_forever(speed_sp= 100)
                     mr.run_forever(speed_sp= -25)
                     s0=time.time()
  ml.reset()
  mr.reset()
  sleep(1)


**交差点での動作 [#o098497e]
 上記のトレースのためのプログラムは、交差点に入り黒を一定時間以上検知すると停止する。そこから交差点での動作に入り、左旋回、または右旋回した後に直進し、その後またライントレースのプログラムに入ることで交差点の識別を行う。旋回の速度や位置によって失敗することもあったが、試行錯誤を繰り返すうちに安定した。

 def right():#右折
    ml.run_timed(time_sp = 500,speed_sp =100,stop_action ='brake')
    mr.run_timed(time_sp = 500,speed_sp =-100,stop_action ='brake')
    sleep(1)

 def left():#左折
    ml.run_timed(time_sp = 500,speed_sp =-100,stop_action ='brake')
    mr.run_timed(time_sp = 500,speed_sp =100,stop_action ='brake')
    sleep(1)

 def forward():#直進
    ml.run_timed(time_sp = 500,speed_sp =100,stop_action ='brake')
    mr.run_timed(time_sp = 500,speed_sp =100,stop_action ='brake')
    sleep(1)


**紙コップをつかむ動作 [#m9b5e47a]

 def cop_catch():#コップを掴む
 ml.stop()
 mr.stop()
 ma.reset()
 ma.run_timed(time_sp=2000,speed_sp=-100,stop_action='hold')
 sleep(3)

 def cop_throw():#コップを放す
 ml.stop()	
 mr.stop()
 ma.reset()
 ma.run_timed(time_sp=2000,speed_sp=100,stop_action='brake')
 sleep(3)


**全体 [#z2201f13]
 sharpstop_line(0,0.7)#コースの中の1での動作
 sleep(1)
 right()
 right()

 sharpstop_line(34,0.6)#2.3の動作

 cop_catch()#4の動作

 left()#5の動作
 left()
 sharpstop_line(2.5,0.7)

 right()#6の動作
 sharpstop_line(9,0.7)

 left()#7の動作
 sharpstop_line(1.5,0.65)
 sleep(1)

 left()#8の動作
 sharpstop_line(38,0)
 sleep(1)
 right()
 right() 
 rev_sharpstop_line(2,0.75)
 sleep(1)

 rev_sharpstop_line(3,0.75)#9の動作
 sleep(1)
 right()

 rev_sharpstop_line(2,0.75)#10の動作
 left()
 left()

 rev_sharpstop_line(2,0.75)#11の動作
 left()
 left()

 rev_sharpstop_line(2,0.75)#12の動作
 sleep(1)
 left()
 left()
 left()
 left()
 left()
 left()
 cop_throw() 

 left()#13.14の動作
 left()
 left()
 left()
 left()
 left()
 rev_sharpstop_line(4,0.75)
 sleep(1)
 left()
 left()
 left()
 forward()
 rev_sharpstop_line(3,0.75)

right()、left()、forward()の車体の動く大きさを大きめに設定し、また領域内にいる時間も長くした。その結果、コースの途中で止まることが格段に減ったが、その分車体がコースに対して異なる方向をむくようになってしまった。right()などの値が大きく設定することで、進路の修正が用意になった。


*総括 [#h0481704]
 比較的シンプルなプログラムで目標を達成できたと思う。最初は3割ほどの成功率だったが、調整を繰り返す内に9割ほどに近づけた。全体の細かな数値の調整で成功率が上がることもあったが、成功率を大きく上げるには根本的な部分の原因を見つけ解決することが必須だと感じた。

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