手术机器人手臂 OpenGL 的运动

Posted

技术标签:

【中文标题】手术机器人手臂 OpenGL 的运动【英文标题】:Movement of a surgical robot's arm OpenGL 【发布时间】:2013-05-12 12:49:15 【问题描述】:

我有一个关于手术机器人手臂在 OpenGL 中的运动的问题。

我们的手臂由 7 块组成,它们被认为是手臂的关节,它们负责弯曲和扭转手臂。我们以这种方式绘制手臂:首先我们创建负责像“上下”移动肩膀的元素,然后我们使用 Translatef “移动”到我们绘制下一个元素的点,负责扭转肩膀(我们使用 Rotatef 控制运动,以此类推下一个关节(肘部、手腕)。

关键是要创造一个可以做出类似人类动作的手臂。我们的机制有效,但现在我们的导师要我们用手臂末端画一条线。我们将负责绘制和移动手臂的代码放在 push 和 pop 矩阵之间,所以它就像真实的一样,我的意思是当我们移动灵魂时,手臂中的任何其他元素也会移动。

有很多元素在移动、旋转,我们有几个旋转矩阵附加到我们可以控制的不同元素上,现在我们不知道如何精确地找到手臂末端的新位置空间,以便能够将新点添加到线条。有人可以帮忙吗?

    glGetFloatv(GL_MODELVIEW_MATRIX,mvm2);

     x=mvm2[12];
     y=mvm2[13];
     z=mvm2[14];

     glPointSize(5.0f);
     glColor3f(1.0f, 0.0f, 0.0f);

     glBegin(GL_POINTS);
     glVertex3f(x,y,z);
     glEnd();

当我使用手表检查 x、y、z 值是什么时,我得到 (0,-1.16-12e,17.222222),这是不可能的,因为我的手臂长度约为 9.0(在 z 轴上)。我认为只有模型视图矩阵的最后一列很重要,我不必将它乘以顶点的局部坐标,因为它们是 (0,0,0),因为我在这里完成了绘制。

【问题讨论】:

使用拼写检查会很好。您是否应该使用固定功能管道,例如glTranslate? 我们在项目中只使用基本的 OpenGL,没有着色器。为此,我们假设将矩阵相乘并从 glGetFloatv 中获取一些信息。 我已经编辑了我的答案。 【参考方案1】:

我们不知道如何在空间中精确地找到手臂末端的新位置,以便能够向线条添加新点。

您可以通过自己执行矩阵数学和转换来做到这一点。

(来自评论)

为此,我们假设将矩阵相乘并从 glGetFloatv 中获取一些信息

请不要这样做。如果您应该自己构建预转换的线带几何图形,则尤其如此。 OpenGL 不是一个矩阵数学库,使用 OpenGL 的固定函数管道矩阵函数绝对没有任何好处。但它有很多缺点。最好使用真正的矩阵数学库。

从技术上讲,您的机械臂由许多相连的段组成,其中每个段通过变换层次结构中向上段的变换组合进行变换。

M_i = M_i-1 · (R_i · T_i)

其中 R_i 和 T_i 分别是每个段的旋转和平移。因此,对于每个线段,您需要单独的变换矩阵来检索线段的点。

由于您将每个线段的原点放置在前一个线段的尖端,因此您可以使用线段的变换矩阵来变换齐次点 (0,0,0,1),该矩阵具有恰好是第 4 个的好特性变换矩阵的列。

这留给您创建转换矩阵链的任务。用 OpenGL 做这件事很乏味。为此使用真正的数学库。如果你的导师坚持让你使用OpenGL固定函数管道,请让他给你看当前OpenGL版本(OpenGL-3及更高版本)规范中的函数参考;他找不到它们,因为所有矩阵数学函数都已从现代 OpenGL 中完全删除。

对于数学库,我可以推荐GLM、Eigen(带有 OpenGL 额外模块)和linmath.h(自我广告)。使用这些库中的每一个构建转换层次结构都很简单,因为您可以轻松创建每个中间矩阵的副本。

【讨论】:

感谢您的回答。这些信息对我来说是全新的,我不知道甚至存在不同的方法。我们在我们的项目中基于 Rotatef/Translatef 函数,因为它是由实验室导师建议并在我们的讲座中展示的。那么,我们应该完全放弃使用这些函数并用数学计算代替它们吗?重建一切将花费我们很长时间......是否可以保留现在所做的事情并使用您的方法仅找到点的位置来构建线带? @Aga:是的,这是可能的,但并不明智,因为您最终会得到两个执行相同计算但使用不同方法的代码路径。使用真正的数学库执行数学运算并使用 glLoadMatrix 加载矩阵要灵活得多;一旦切换到着色器,就可以直接调用 glUniformMatrix。从使用固定函数矩阵函数转移到合理的数学系统要困难得多。所以我会咬紧牙关,做一次工作就完成了。【参考方案2】:

如果您应该使用glGetFloatv,那么这指的是使用GL_MODELVIEW_MATRIX 参数调用它,它返回当前模型视图矩阵。然后,您可以使用此矩阵将点从手的坐标系转换到世界空间 CS。

但是,调用glGetFloatv 是不好的做法,因为它可能会导致渲染性能降低。我认为您应该与您的导师讨论过时甚至已弃用的功能,也许他可以让教授更新材料。

编辑:您检索翻译的代码是正确的。但是,您不能使用相同的模型视图矩阵来绘制点。在绘制它之前,您必须使用glLoadIdentity 或通过弹出来重置模型视图矩阵。

【讨论】:

这是我试图解决我的问题的方式,但我不是在手的末端(我完成绘图的地方)收到点,而是在空间的其他地方。我很确定矩阵和获取它的元素没有问题,但可能以前的一些转换对结果有影响。我尝试使用 glLoadIdentity();在 glPushMatrix() 之后;但这并没有帮助,甚至使情况变得更糟,因为现在屏幕上什么都没有。 我做了,我是新手,不知道为什么贴在上面。 您发布了答案。您应该单击问题的编辑链接,然后在此处添加代码。然后,您可以删除答案。由于我不懂波兰语,也许你可以只发布你试图将点转换为世界空间的部分。 没错,我什至尝试过这样做,但由于某种原因,第一次没有成功。现在一切正常,感谢您的帮助!

以上是关于手术机器人手臂 OpenGL 的运动的主要内容,如果未能解决你的问题,请参考以下文章

如何用MATLAB画机器人手臂一个关节的速度曲线

手术机器人软硬件设计方案

旋转前后的 OpenGL 平移

ROS系统MoveIt玩转双臂机器人系列--浅议机器人运动学与D-H建模

VTK中的装配体(vtkAssembly)

opengl c ++中的180到-180运动?