2013-03-21 86 views
1

我正在爲我的大學進入競賽的機器人編寫代碼。我目前正在嘗試使用反射式傳感器來構建一些輪式編碼器。我後來意識到,我可能需要使用線程來實現這一點,因爲機器人需要同時監視左側和右側編碼器。下面的代碼是我到目前爲止:用於機器人上的車輪編碼器的Python線程

from __future__ import division 
import threading 
import time 
from sr import * 
R = Robot() 

class Encoder(threading.Thread): 
    def __init__(self, motor, pin, div=16): 
     self.motor = motor 
     self.pin = pin 
     self.div = div 
     self.count = 0 
     threading.Thread.__init__(self) 

    def run(self): 
     while True: 
      wait_for(R.io[0].input[self.pin].query.d) 
      self.count += 1 

    def rotations(self, angle, start_speed=50): 
     seg = 360/self.div 
     startcount = self.count 
     current_dist = angle #Distance away from target 
     R.motors[self.motor].target = start_speed 
     while current_dist > 360: 
      newcount = self.count - startcount 
      current_dist = angle - newcount*seg 
      R.motors[self.motor].target = 50 
     while abs(current_dist) > seg/2: 
      newcount = self.count - startcount 
      current_dist = angle - newcount*seg 
      current_speed = start_speed * current_dist/360 
      if current_speed < 5: 
       R.motors[self.motor].target = 5 
      else: 
       R.motors[self.motor].target = current_speed 
     R.motors[self.motor].target = 0 

WheelLeft = Encoder(0,0) 
WheelLeft.start() 
WheelRight = Encoder(1,3) 
WheelRight.start() 

WheelRight.rotations(720) 
WheelLeft.rotations(720) 

sr模塊是由南安普頓大學,誰正在競爭。它使我們能夠與機器人的硬件進行交互。

現在,創建的線程似乎允許兩個反射率傳感器分開監測。這一位代碼:R.io[0].input[self.pin].query.d計算出來自反射率傳感器的值是否已經改變。 '旋轉'方法通過不斷檢查車輪已經轉過的程度,並且在車輪到達終點時放慢車輪的轉向速度,從而使車輪轉過一定的角度。當我運行程序時,我希望兩個輪子都開始轉動,然後減速並在經過兩次轉動時停下來。目前,當我運行程序時,一個車輪開始轉動並減速並停止,然後是另一個車輪。在我看來,像'旋轉'方法不在線程中運行,就像'運行'方法一樣。它只是運行在線程中的'run'方法下的代碼,還是它是整個類?

如果有幫助,我一直在關注這個教程:http://www.devshed.com/c/a/Python/Basic-Threading-in-Python/1/

另外,我想知道爲什麼有可能啓動一個線程只能用Encoder(0,0).start()。爲什麼你不必創建一個使用類的對象(例如Thread = Encoder(0,0).start()爲一個新的線程創建?

對不起,如果terminoligy我已經使用不達標,因爲你可能可以告訴我是。很新的線程,和編程一般

回答

1

Encoder(0,0).start()是啓動線程的方法的調用。反過來,這種方法調用你run實現,它不使用rotations方法。如果你想要做的所以,那麼你必須在run的while循環中調用它

隨着Thread = Encoder(0,0).start()你存儲值retri從那個電話(它是None)開始,但是爲了得到它,你需要首先啓動新的線程。

0

運行方法的執行線程。

如果你想在該線程中發生其他事情,你必須從Encoder.run()中調用它。

哦,和Encoder(0,0).start()確實創建一個對象。僅僅因爲你沒有將該對象綁定到局部變量並不意味着它不存在。如果它不存在,則不能調用其方法start

你必須非常小心它的生命週期,儘管沒有一個局部變量保持活着。

0

您可以從SR的Poll類延伸,使得它可以在wait_for使用:

import poll 

class Encoder(poll.Poll): 
    def __init__(self, motor, pin, div=16): 
     self.motor = motor 
     self.pin = pin 
     self.div = div 
     self.count = 0 
     self.target_reached = False 

     # kick off a thread to count the encoder ticks 
     self.counter_thread = threading.Thread(target=self._update_count) 
     self.counter_thread.start() 

    def _update_count(self): 
     while True: 
      wait_for(R.io[0].input[self.pin].query.d) 
      self.count += 1 

    def rotations(self, angle, start_speed=50): 
     if not self.target_reached: 
      raise Exception("Last motion still in progress!") 

     self.target_reached = False 

     # kick off a thread to control the speed 
     self.angle_thread = threading.Thread(
      target=self._update_speeds, 
      args=(angle, start_speed) 
     ) 
     self.angle_thread.start() 

    def _update_speeds(self, angle, start_speed): 
     # control the motor speed as before 
     ... 

     # let things know we're done 
     self.target_reached = True 

    # implement poll methods 
    def eval(self): 
     return (self.target_reached, None) 

,然後讓你做:

wheelLeft = Encoder(0,0) 
wheelRight = Encoder(1,3) 

wheelRight.rotations(720) 
wheelLeft.rotations(720) 

wait_for(wheelRight & wheelLeft) 

注意,編碼器本身不是一個線程 - 這是一個「有一個」的關係,而不是一個「是」的關係