我要在两台计算机之间创建UDP连接。 计算机A必须发送每4个milisec。一个包到计算机B,告诉B在哪里以及如何移动机器人手臂。 B计算机将发回手臂位置速度和加速度以及托运和位置之间的误差......
A计算机工作正常,它有C代码程序,我看不到,但它没关系,因为我只使用接受python代码的机器人。 我一直试图在B计算机上使用多线程程序,其中一个线程具有发回错误和位置的唯一功能。
在这个小线程中,我试图确定发送UDP包(teledirigido.fbk.send(...))然后从4 milisec减去代码执行时间的时间。
class enviaDeterministico(threading.Thread):
def __init__(self,teledirigido):
self.teledirigido = teledirigido
# thanks to mordi
threading.Thread.__init__(self)
self.t = timeit.time
def run(self):
while 1:
self.empieza0 = self.t.time()
self.empieza = self.t.time()
self.teledirigido.cond.acquire()
self.teledirigido.fbk.send(self.teledirigido.lectura.enviarAmpliado())
self.acaba = self.t.time()
time.sleep((0.004-(self.acaba-self.empieza)))
self.teledirigido.cond.release()
self.acaba0 = self.t.time()
print 'tiempo entre envios %.6f'% (self.acaba0-self.empieza0)
第一个问题是睡眠方法不是“(0.004-(self.acaba-self.empieza))”参数,python解释器说:
线程Thread-3中的异常:
追踪(最近一次呼叫最后一次):
文件“/usr/lib/python2.6/threading.py”,第532行,__ bootstrap_inner
self.run()
文件“./conclase.py”,第210行,在运行中
time.sleep(0.004-(self.acaba-self.empieza))
IOError:[Errno 22]参数无效
如果我使用decsec。而不是毫秒,程序没有错误。
我发现的第二个也是最后一个问题是时机不是很确定。有没有办法在python中创建一个运行这段代码并退出的定时事件?
我有很多问题,我知道,我希望有人回答这个问题,结果也会对其他人有用。
感谢大家! stackoverflow和所有使用的人都太棒了!
答案 0 :(得分:2)
当你将负参数传递给time.sleep时,你会得到错误22。
self.acaba和self.empieza有什么价值?如果两次呼叫之间经过的时间超过4ms,则会失败。
定期回调取决于您的操作系统。您可以使用SIGALRM在Unix系统上实现。有关详情,请参阅http://docs.python.org/library/signal.html。但要小心:信号和线程混合不好。
您还可以查看stdlib中的sched模块,该模块可以很好地集成在多线程代码中。
答案 1 :(得分:1)
time.sleep(max(0, <your time formula>)) # protect from negative time
除非您的内核使用至少1000的HZ编译,否则可能很难达到稳定的4ms。还要确保您的程序保留足够的空闲cpu以正确安排“实时”线程,比如说您的程序使用超过90%的cpu,你不会及时醒来。
如果您可靠地每4毫秒获得一次UDP查询,那么您可以将时间基准关闭。如果你没有时间来源,你可以这样做:
class Timer(threading.Thread):
def run(self):
started = time.time()
counter = 0
while True:
counter += 1
now = time.time()
if started + counter * 0.040 - now > 0:
time.sleep(started + counter * 0.040 - now)
# send datum number `counter`
这不会跳过发送数据,但当然可以延迟单个数据,即它具有正确的频率,但可能会有一些抖动。