我正在尝试在2D手臂(由三根带关节组成)上实施反向运动学。我能够将最低的手臂旋转到所需的位置。现在,我有一些问题:
如何使上臂与第三臂一起移动,使臂的终点到达所需的点。我是否需要为两者使用旋转矩阵?如果有,可以有人给我一些示例或帮助,还有其他任何可能吗?没有旋转矩阵的方法吗?
最低臂只向一个方向移动。我试过谷歌它们,他们说两个向量的交叉产品给出了手臂的方向,但这是为3D。我正在使用2D和两个2D矢量的交叉积给出一个标量。那么,我该如何确定其方向???
Plz家伙会感激任何帮助....
提前致谢 维克拉姆
答案 0 :(得分:7)
我会试一试,但是因为我的机器人技术已经过去了二十年,所以要把它带上一粒盐。
我学习它的方式,每个关节都由它自己的旋转矩阵描述,相对于它当前的位置和方向定义。然后通过将旋转矩阵组合在一起来计算整个臂的终点的坐标。
这实现了您正在寻找的效果:您只能移动一个关节(更改其方向),并自动跟随所有其他关节。
你在这里找到矩阵的可能性不大 - 实际上,如果使用齐次坐标,所有联合计算(旋转和平移)都可以用矩阵乘法建模。优点是可以用单个矩阵(加上手臂的原点)来描述全臂位置。
使用此变换矩阵,您可以解决逆运动学问题:由于变换矩阵'元素将取决于关节的角度,您可以将整个计算'endpoint = startpoint x transformation'视为一个方程组,并且已知起点和终点,您可以解决此系统以确定未知角度。这里的困难在于方程式可能无法解决,或者存在多种解决方案。
我不太明白你的第二个问题 - 你在寻找什么?
答案 1 :(得分:6)
旋转可以用它的角度或complex number of the unit circle来代替旋转矩阵,但实际上它是一样的。更重要的是,您需要T
代表t1 * t2 * t3
,以便您可以编写atan2
之类的内容来计算第三个链接的位置和方向。
使用from gameobjects.vector2 import Vector2 as V
from matrix33 import Matrix33 as T
from math import sin, cos, atan2, pi
import random
计算rigid body transformations。
如下面的Python示例所示,这两件事足以构建一个小的IK解算器。
matrix33
angle between the vectors库没有2D转换,因此您必须自己编写gameobjects.matrix44
。它的界面就像angle
。
定义从一个关节到下一个关节的转换的正向运动学函数。我们假设关节旋转joint
,然后是固定变换def fk_joint(joint, angle): return T.rotation(angle) * joint
:
tool == fk(joints, q)
该工具的转换为joints
,其中q
为固定转换,def fk(joints, q):
prev = T.identity()
for i, joint in enumerate(joints):
prev = prev * fk_joint(joint, q[i])
return prev
为关节角度:
T.identity()
如果手臂的基部有偏移,请替换q
转换。
OP正在通过循环坐标下降来解决位置的IK问题。我们的想法是通过一次调整一个关节变量来使工具更接近目标位置。设prev
为关节的角度,def ccd_step(q, prev, tool, goal):
a = tool.get_position() - prev.get_position()
b = goal - prev.get_position()
return q + atan2(b.get_y(), b.get_x()) - atan2(a.get_y(), a.get_x())
为关节基部的变换。应该将关节旋转到工具的矢量和目标位置之间的角度:
def ccd_sweep(joints, tool, q, goal):
prev = T.identity()
for i, joint in enumerate(joints):
next = prev * fk_joint(joint, q[i])
q[i] = ccd_step(q[i], prev, tool, goal)
prev = prev * fk_joint(joint, q[i])
tool = prev * next.get_inverse() * tool
return prev
遍历关节并更新关节值的每次更改时的工具配置:
fk()
请注意,ccd_sweep()
和fk_joint()
与3D相同;您只需重写ccd_step()
和n
。
构建一个具有cnt
个相同链接的手臂,并从随机手臂配置q
开始运行CCD扫描的def ccd_demo(n, cnt):
q = [random.uniform(-pi, pi) for i in range(n)]
joints = [T.translation(0, 1)] * n
tool = fk(joints, q)
goal = V(0.9, 0.75) # Some arbitrary goal.
print "i Error"
for i in range(cnt):
tool = ccd_sweep(joints, tool, q, goal)
error = (tool.get_position() - goal).get_length()
print "%d %e" % (i, error)
次迭代:
>>> ccd_demo(3, 7)
i Error
0 1.671521e-03
1 8.849190e-05
2 4.704854e-06
3 2.500868e-07
4 1.329354e-08
5 7.066271e-10
6 3.756145e-11
>>> ccd_demo(20, 7)
i Error
0 1.504538e-01
1 1.189107e-04
2 8.508951e-08
3 6.089372e-11
4 4.485040e-14
5 2.601336e-15
6 2.504777e-15
我们可以尝试解算器并比较不同数量链接的收敛速度:
{{1}}
答案 2 :(得分:3)
在机器人技术中,我们通常使用DH参数来进行正向和反向运动。 Wikipedia有一个很好的介绍。
答案 3 :(得分:3)
DH(Denavit-Hartenberg)符号是解决方案的一部分。它可以帮助您收集一组简洁的值来描述机器人的机制,例如链接长度和关节类型。
从那里开始计算正向运动学变得更容易。首先要考虑的是如何将坐标框架从一个位置转换到另一个坐标框架。例如,给定您的机器人(或其DH表),您必须应用于一个坐标系(例如世界)的旋转和平移集是什么,以了解点(或矢量)的位置。机器人的手腕坐标系。
正如您可能已经知道的那样,齐次变换矩阵对于此类变换非常有用。它们是封装旋转和平移的4x4矩阵。这些矩阵的另一个非常有用的特性是,如果你有两个坐标框架由一些旋转和平移链接和定义,如果你将两个矩阵相乘,那么你只需要将你的转换目标乘以该乘法的乘积。
因此DH表将帮助您构建该矩阵。
反向运动虽然有点复杂,但取决于您的应用。复杂性源于针对同一问题提供多种解决方案。 DOF的数量越多,解决方案的数量就越多。
想想你的手臂。在你周围捏一些坚实的东西。您可以将手臂移动到空间中的多个位置,并保持收缩矢量不变。解决逆运动学问题涉及决定选择哪种解决方案。