2011-07-18 19 views
2

我必须在两台计算机之间创建UDP连接。 电脑A必须发送每4毫秒。一个数据包给计算机B,告诉B在哪里以及如何移动机器人手臂。 B计算机将发回手臂位置速度和加速度以及交货和位置之间的误差...使用Python进行确定性时间套接字连接

A计算机工作正常,它有C代码程序,我看不到但它不'因为我正在使用的机器人只接受Python代码。 我一直在B计算机上用一个多线程程序来做这样的事情,其中​​一个线程只有发回错误和位置的功能。

在这个小小的线程中,我试图确定需要发送一个UDP包(teledirigido.fbk.send(...))的时间,然后让一个睡眠时间从4毫秒减去代码执行时间。

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解释说:

Exception in thread Thread-3:

Traceback (most recent call last):

File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner

self.run() 

File "./conclase.py", line 210, in run

time.sleep(0.004-(self.acaba-self.empieza)) 

IOError: [Errno 22] Invalid argument

如果我使用decsec。程序不会产生错误,而不是毫秒。

我发现的第二个也是最后一个问题是时间不确定。有没有办法在python中运行这段代码并退出?

我有很多问题,我知道,我希望有人回答这个问题,它也会对其他人有用。

感谢大家! stackoverflow和所有使用的人都太棒了!

+1

如果您将您的标识符翻译成英文将是有帮助的。 –

回答

2

当您将负面参数传递给time.sleep时,您会得到errno 22。

self.acaba和self.empieza的价值是什么?如果两次通话之间的时间超过4ms,则将失败。

定期回调取决于您的操作系统。你可以在Unix系统上使用SIGALRM。有关详细信息,请参阅http://docs.python.org/library/signal.html。然而,Carefull:信号和线程混合不好。

您还可以查看stdlib中的调度模块,该模块很好地集成在多线程代码中。

+0

我会检查两者的价值,也许有时运行时间超过4毫秒。 Usualy运行需要0.00047秒,但不是确定性的。 我也会检查信号。 非常感谢! – Jubeor

1
time.sleep(max(0, <your time formula>)) # protect from negative time 

这可能是难以达到稳定4ms的,除非你的内核与HZ编译至少1000另外,还要确保你的程序留下了足够的空闲CPU妥善安排您的“实时”线程,说,如果你的程序使用过90%cpu,你不会得到及时的唤醒。

如果你可以可靠地获得你的UDP查询每4ms,你可以根据你的时间。如果你没有时间的来源,你可以做这样的事情:

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` 

这不会跳过发送数据,但当然单一的数据可能会推迟,这是它都会有正确的频率,但可能会有一些抖动。