很抱歉这个糟糕的标题,我真的不知道如何描述它简而言之…
我的场景是,对于机器人应用程序,我们需要一个实时循环来控制电机每1ms一次。同时,我们可能想要做一些不具有实时性要求的事情,如路径规划、图像处理、目标识别等。此外,来自非实时任务的一些结果将被发送到实时电机控制回路以控制机器人。
对于实时部分,我使用带有RT-Preempt Patch的Ubuntu。因此,我可以在while循环中运行实时控制循环,就像示例代码here一样。
然而,我不知道非实时部分。在我看来,我会在同一进程中新建一个线程,并在该线程中运行非实时任务。
由于我对实时编程非常陌生,我不知道我的设计会有什么问题。此外,我想知道是否有任何范例来设计这样的程序?
-编辑
关于我的应用程序的更多细节。
机器人,更具体地说,是一个机器人手臂。
实时部分,计算了机器人的正运动学、逆运动学和雅可比矩阵。然后用一个简单的PID控制器计算出正确的输出命令。最后,通过EtherCAT向各电机发送电机指令。
例如,对于非实时部分,可以从kinect获取PointCloud流,进行一些预处理,计算场景中对象的姿态,确定机械臂良好的抓取姿态,最后将每个电机的目标发送到实时部分,以便机械臂真正移动到目标并抓取对象。整个过程可能需要10秒左右。但同时,实时环路应保持运行状态,并发送适当的力指令或位置指令,使机械臂保持原来的姿态不动。
对于这两个部分之间的通信,在大多数情况下,命令是由一种新的算法从非实时部分生成的,并将其发送到实时部分,以使机器人手臂移动。但是,有时非实时部分中的算法需要知道,例如,末端效应器的当前姿势。因此,非实时部分将需要从驻留在实时部分的正向运动学中获取信息。
发布于 2014-08-09 20:07:22
正如@Basile Starynkevitch强调的那样,如何将整个系统划分为实时和常规部分是非常重要的。
在RT-Linux中实现时,系统中有实时需求的部分将被制作成实时线程,在内核中运行。这允许它们在不被抢占的情况下运行,但有一个巨大的缺点:在用户空间中没有人们期望的保护。实时线程崩溃意味着系统已经崩溃。出于这个原因(以及其他原因),您应该尽可能地限制实时组件。
系统的非实时组件将作为常规Linux进程运行。它们可以与你想要的任何昂贵的计划算法一起运行,实时线程将抢占它们并根据需要运行。棘手的部分是通信,为此提供了两种机制:FIFO和共享内存。
FIFO是最简单的,并且允许单向通信(如果您想要双向通信,请使用两个)。它们是字符设备,您不必担心读/写重叠。更多信息请参见tldp.org。
对于传递大量数据,共享内存更可取。有了它,两个进程就可以将同一部分映射到内存中。但你必须在进程/线程之间进行协调,以确保一个进程/线程不会在另一个进程/线程写入过程中读取数据,反之亦然。当其中一方是实时线程时,这实际上会稍微容易一些,因为您知道实时线程不会被抢占。更多信息请参见drdobbs.com。
您还需要注意优先级反转(例如,当高优先级线程必须等待低优先级线程释放共享资源时)。
https://stackoverflow.com/questions/25187252
复制相似问题