2011-07-18 6 views
2

私は2台のコンピュータ間にUDP接続を作成しました。 コンピュータAは4ミリ秒ごとに送信する必要があります。コンピュータBにパケットを送り、ロボットアームをどこにどのように移動させるかをBに伝える。 Bのコンピュータはアーム位置の速度と加速度と荷物と位置の間の誤差を返信します...Pythonを使用した確定的な時間ソケット接続の作成

Aコンピュータはうまく動作しますが、見えないCコードプログラムがありますが、ロボットのために私はPythonコードを受け入れるだけで働いています。 私は、マルチスレッドプログラムを使ってBコンピュータでそうしようとしてきました.1つのスレッドがエラーと位置を返す唯一の機能を持っています。

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

もしI decsecを使用します。 milisecondsではなく、プログラムはエラーを返さない。

私が見つけた2番目と最後の問題は、タイミングがかなり決定的ではないということです。この小さなコードを実行して終了する、時間を節約したイベントをPythonで作る方法はありますか?

私は多くの問題を抱えていますが、私はこの質問に誰かが答えてくれれば幸いです。

皆様、ありがとうございます! stackoverflowと使用するすべての人々は素晴らしいです!

+1

あなたのIDを英語に翻訳した方が役に立ちます。 –

答えて

2

time.sleepに負の引数を渡すと、errno 22が返されます。

self.acabaとself.empiezaの値は何ですか? 2つのコール間の経過時間が4msを超えると、これは失敗します。

定期的なコールバックの取得は、お使いのOSによって異なります。あなたはSIGALRMを使ってUnixシステムでそれを得ることができます。詳細については、http://docs.python.org/library/signal.htmlを参照してください。しかし、信号とスレッドはうまく混ざりません。

また、マルチスレッドコードでよく統合されたstdlibからschedモジュールを見ることもできます。

+0

両方の値をチェックします。実行時間が4ミリ秒を超えることがあります。通常、実行には0.00047秒かかりますが、確定的ではありません。 私も信号をチェックします。 ありがとうございました! – Jubeor

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

あなたのプログラムが終わっ使用する場合、それはあなたのカーネルは、少なくとも1000はまた、あなたのプログラムが正常にあなたの「リアルタイム」のスレッドをスケジュールするのに十分なアイドルCPUを去ることを確認してくださいHZを使用してコンパイルされていない限り、安定した4msのに到達するのは難しいかもしれ、言います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` 

、それは、それが正しい周波数を持つことになりますです:あなたはタイミングのソースを持っていない場合、あなたはこのような何かを行うことができますジッタがあるかもしれません。

関連する問題