我正在为我的大学正在参加比赛的机器人编写代码。我目前正在尝试使用反射传感器构建一些车轮编码器。我意识到我可能需要使用线程来实现这一点,因为机器人需要同时监视左右编码器。下面的代码是我到目前为止的代码:
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
确定来自反射传感器的值是否已经改变。 “旋转”方法通过不断检查车轮已经转过多少度,并在车辆到达终点时减速,将车轮转过一定角度。当我运行程序时,我希望两个轮子都开始转动,然后当它们经过2次旋转时减速并停止。目前,当我运行程序时,一个轮子开始转动并减速并停止,然后是另一个轮子。在我看来,'旋转'方法不是在一个线程中运行,就像'run'方法一样。是只有'run'方法下的代码在一个线程中运行,还是整个类?
如果有帮助,我一直在关注本教程:http://www.devshed.com/c/a/Python/Basic-Threading-in-Python/1/
另外,我想知道为什么只能用Encoder(0,0).start()
启动一个线程。为什么不必使用类创建对象(例如Thread = Encoder(0,0).start()
来创建新线程?
很抱歉,如果我使用的终端版本没有达到标准,你可能会说我对线程和编程很新。
答案 0 :(得分:1)
Encoder(0,0).start()
是对启动线程的方法的调用。反过来,此方法会调用run
实现,该实现不使用rotations
方法。如果你想这样做,那么你必须在run
的while循环中调用它。
使用Thread = Encoder(0,0).start()
存储从该调用中检索到的值(无为),但要获取它,您需要先启动新线程。
答案 1 :(得分:0)
run方法是执行的线程。
如果你想在该线程中发生其他事情,你必须从Encoder.run()
调用它。
哦,Encoder(0,0).start()
创建一个对象。仅仅因为你没有将该对象绑定到局部变量并不意味着它不存在。如果它不存在,则无法调用其start
方法。
你必须非常小心它的生命周期,没有一个局部变量让它保持活力。
答案 2 :(得分: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)
请注意,编码器本身不是一个线程 - 它是一个“有”关系,而不是“是一个”关系