我试图写一个蟒蛇的代码,用于控制一个非常特殊的设备,它是一个杠杆(它的末端有一个旋转编码器)和一些LED。本质上,一个拉杠杆到一个特定的位置范围,当正确的完成,一个LED将打开指示你是在目标位置。杠杆可能被移动在一定范围内的编码器计数,你仍将成功地完成一次试验。我的问题是,什么是记录杠杆位置数据的最佳方法,同时能够检查杠杆是否在正确的位置范围内?
我已经为这个程序的一个更简单的版本编写了软件,它只是使用一个开关而不是一个旋转编码器作为杠杆。编码器的优点是,我可以得到非常精确的测量杠杆位置,从而有更多的数据!我能想到记录数据的方法,唯一的问题是它会很慢。我正在考虑使用嵌套的时间循环,循环将检查和记录杠杆的位置,但是我担心这可能会有一个很低的采样率。
我也在考虑使用线程来实现这个目标,但是我不知道如何使用线程,因为我以前从未使用过它们。
我已经有了与编码器本身接口的软件和硬件,我能够获得非常好的杠杆位置数据,但是我希望能够记录尽可能多的这些数据点,同时仍然能够检查杠杆是否在正确的位置范围内。
如果您能向我展示一个简单的代码来完成这个任务,我将非常感激,并且我应该能够将它实现到我的代码中。
下面是一个简单的示例,说明我目前正在考虑如何编写代码:
minCorrectPos = 100
maxCorrectPos = 200
timeToHoldLever = 5.0 #Seconds
while True:
currentPos = encoder.readEncoderPos() #Function returns int
writeToFile(str(currentPos)) #Records the data pos of the lever. I want this to happen as often as physically possible so as to lose the least amount of data.
if currentPos < minCorrectPos or currentPos > maxCorrectPos:
print 'Lever is out of range, wrong trial'
writeData(timestamp)
if time.time()-t_trialBegin > timeToHoldLever:
print 'Lever has been held for enough time within correct range of positions. Rewarding person.'
break
#...
#Potentially checking for more things, like status of subject, whether he or she is still touching the lever, etc.我不喜欢上面的代码的原因是因为我担心我会丢失数据,因为raspberry pi可能无法足够快地轮询杠杆的位置,因为正在进行的while循环(慢采样率)。这就是为什么我认为线程可能是解决这个问题的正确方法,因为我将有一个单独的线程专门运行,专门记录杠杆位置给定的对象的名称拉杠杆。可悲的是,我需要帮助我编写那种类型的代码。
发布于 2014-05-31 03:16:58
我建议使用multiprocessing模块而不是线程,因为全局解释器锁(GIL)可以防止Python并发执行线程,即使有多个内核。multiprocessing模块避免了这一限制。
下面是一个小示例,展示了如何通过使用currentPos在父进程和子进程之间发送currentPos来使子进程专用于将multiprocessing.Pipe写入文件。
import multiprocessing as mp
def writeToFile(conn):
with open(filename, "a") as f: # Just leave the file open for performance reasons.
while True:
currentPos = conn.recv()
f.write("{}\n".format(currentPos))
if __name__ == "__main__":
parent_conn, child_conn = mp.Pipe()
p = mp.Process(target=writeToFile, args=(child_conn,))
p.start()
while True:
currentPos = encoder.readEncoderPos()
parent_conn.send(currentPos)
if currentPos < minCorrectPos or currentPos > maxCorrectPos:
print 'Lever is out of range, wrong trial'
writeData(timestamp)
if time.time()-t_trialBegin > timeToHoldLever:
print 'Lever has been held for enough time within correct range of positions. Rewarding pe'
break请注意,尽管我之前曾说过Python不能很好地处理线程,但与这个特定示例中的multiprocessing相比,它们的性能可能非常好。这是因为子进程主要是执行I/O操作,这允许释放GIL。您可以使用threading模块尝试类似的实现,并比较性能。
另外,您可能希望writeToFile只在接收到每个N个currentPos值之后才实际执行currentPos。文件I/O很慢,所以进行更少、更大的写入可能会对您更好。
https://stackoverflow.com/questions/23965936
复制相似问题