使用 Python 建立确定性时间套接字连接

发布于 2024-11-24 21:56:41 字数 1653 浏览 1 评论 0原文

我必须在两台计算机之间创建 UDP 连接。 计算机A必须每4毫秒发送一次。向计算机 B 发送一个数据包,告诉 B 在何处以及如何移动机械臂。 B计算机将发回手臂位置速度和加速度以及委托和位置之间的误差...

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)

第一个问题是 sleep 方法并不存在“(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 和所有使用它的人都很棒!

I've to create an UDP connection between two computers.
The computer A have to send each 4 milisec. a packet to the computer B, telling B where and how to move a robotic arm.
The B computer will send back the arm position velocity and acceleration and the error between the consign and the position...

The A computer works fine, it has C code program that I can't see but it doesn't matter because of the robot i'm working with only accept python code.
I've been trying to do so in the B computer with a multithread program where one thread has the only function of sending back the error and position.

In this little thread where I've tried to determine the time that takes sending a UDP package ( teledirigido.fbk.send(... )) and then making a sleep substracting the time of the code execution from 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)

The first problem is that the sleep method doesn't lie the "(0.004-(self.acaba-self.empieza))" argument, python interpreter says:

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

If I uses decsec. instead of miliseconds the program gives no error.

The second and last problem I found is that the timing is not quite deterministic. Is there any way to make a timed event in python that run this little piece of code and exits?

I've lots of issues, I know, I hope somebody answer this question and also it result useful to other people.

Thanks to everybody! stackoverflow and all the people that uses are fantastic!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

行雁书 2024-12-01 21:56:42
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`

这不会跳过发送数据,但当然可以延迟单个数据,即它将具有正确的频率,但可能会有一些抖动。

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

It may be hard to reach stable 4ms unless your kernel is compiled with HZ at least 1000. Also make sure your program leaves enough idle cpu to schedule your "realtime" thread properly, say if your program uses over 90% cpu, you won't get timely wakeups.

If you get your UDP queries every 4ms reliably, you can base your timing off that. If you don't have a source of timing, you could do something like this:

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`

This will not skip sending data, but of course a single datum could be delayed, that is it will have correct frequency, but may have some jitter.

你的呼吸 2024-12-01 21:56:41

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

self.acaba 和 self.empieza 的值是什么?如果两次调用之间的时间超过 4 毫秒,则会失败。

获得定期回调取决于您的操作系统。您可以在 Unix 系统上使用 SIGALRM 获得该信息。有关更多信息,请参阅 http://docs.python.org/library/signal.html这。但要小心:信号和线程不能很好地混合。

您还可以查看 stdlib 中的 sched 模块,它在多线程代码中集成得很好。

You get errno 22 when you pass a negative argument to time.sleep.

What are the values of self.acaba and self.empieza ? If the time elapsed between the two calls is over 4ms this will fail.

Getting a periodic callback depends on your OS. You can get that on Unix systems with a SIGALRM. See http://docs.python.org/library/signal.html for more on this. Carefull, though: signals and threads don't mix well.

You can also look at the sched module from stdlib which integrates well in multithreaded code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文