给定六轴铰接式机械手将工具固定在其末端执行器上,如果我具有所需的工具位置和工具方向,则逆运动学方程式中将有1个正确的解决方案,以使机器人到达该位置。 >(或者根据关节的范围,最多可以有16种不同的解决方案)



但是,如果机器人拿着笔这样的东西,我想让机器人用该笔在目标上标记一个特定点,那么我不在乎笔的方向,只要它垂直于标记的表面即可。

因此,运动学方程将具有无限多种解决方案。

如何从这些解决方案中选择最接近当前配置的联合配置:需要最少移动量的联合配置?
(或根据其他一些类似标准最佳的关节配置,例如,所有关节角度距离其最大值和最大角度最少?)

#1 楼

首先,我们需要定义最佳。由于您没有说出什么是最佳选择,因此大多数人会选择二次表达式。例如,假设您当前的关节角度由矢量$ \ vec {\ alpha} $给出。我们可以考虑将所需的运动减至最小-错误$ \ vec {x} = \ vec {\ alpha}-\ vec {\ alpha} _ {start} $,您可以定义成本函数$ J = \ vec {x } ^ TQ \ vec {x} $用于某个矩阵$ Q $。我们通常使用对角矩阵,但是任何正定矩阵都可以。

在具有两个关节角的简化示例中,如果关节$ a $具有更便宜的电机(也许更靠近末端执行器) ,我们的成本函数可能为

$ J = \ left [\ begin {matrix} x_a \\ x_b \ end {matrix} \ right] \ left [\ begin {matrix} 1&0 \\ 0&2 \\\ end {matrix} \ right] \ left [\ begin {matrix} x_a&x_b \ end {matrix} \ right] $,即。关节$ b $的运动成本是关节$ a $的两倍。

现在,运动方程是矩阵公式,在Denavit-Hartenberg表示中可能是:

$ \ prod {T_i} = \ left [\ begin {matrix} 1&0&0&x \\ 0&1&0&y \\ 0&0&1&z \\ 0&0&0&0&1 \ end {matrix} \ right] $,其中右侧代表位置$(x,y, z)$和方向(当前设置为零旋转),给定关节角度。

由于我们不在乎方向,只在意位置,因此我们可以截断最后一个的前三列转换矩阵,以及第一个转换矩阵的最后一行。我们可以等效地将此公式表示为:

$ \ left [\ begin {matrix} 1&0&0&0 \\ 0&1&0&0 \\ 0&0&1&0 \ end {matrix} \ right] \ prod {T_i} \ left [\ begin {matrix} 0 \\ 0 \\ 0 \\ 1 \ end {matrix} \ right] = \ left [\ begin {matrix} x \\ y \\ z \ end {matrix} \ right] $

乘以左侧,我们得到三个方程。如果参数是线性的,则很容易求解。如果所有执行器都是线性执行器,就是这种情况。在这种情况下,问题实际上是二次程序。我们可以重新排列左侧以获得等式:

$ K \ vec {x} = \ left [\ begin {matrix} x \\ y \\ z \ end {matrix} \ right] $,对于某些矩阵$ K $。

二次程序是一个问题,可以用以下形式表示:


最小化$ J = \ frac {1} {2} \ vec {x} ^ TQ \ vec {x} + \ vec {c} ^ T \ vec {x} $

以$ A \ vec {x为准} \ leq \ vec {b} $,$ E \ vec {x} = \ vec {d} $


要解决此问题,您可以使用多种算法,例如,内部点,活动集,...。只要找到一个合适的库,它就会为您解决。

非线性方程组更难求解。这称为非线性编程,但是如果您有旋转关节,它就是您所拥有的。

基本上,您具有矩阵函数,而不是矩阵方程。


在$ \ vec {h}(x)= 0 $,$ \ vec {g}(x)\ leq 0 $的情况下,将$ f(x)$最​​小化(如有必要,请重新安排以使RHS约束为零)


用于解决此问题的算法甚至更为复杂,但包括内部点,顺序二次规划(SQP),活动集,信任区反射算法。显然,关于这些算法如何工作的解释非常冗长,我将其排除在此答案范围之外。可以说,仅用于二次编程的算法内容本身就可以是一门完整的课程。

您应该找到一个解决问题的库,这将需要很长时间编码高效的实现,高效的实现一次可以处理100个(或更多)变量。例如,如果您使用MATLAB,则可以从“优化工具箱”中找到有关如何使用函数fmincon的文档。

要在线解决该问题,您可能需要C ++或其他本机实现,例如NLopt。请注意,这可能不是微控制器可以快速解决的问题,并且许多库可能还具有其他依赖关系,这些依赖关系在微控制器上不易使用(因为它们是供计算机使用的)。


如果您不担心效率,只是想自己编写一些代码,那么假设您可以调用一个函数来解决运动学逆问题,则只需执行梯度下降法即可。例如,任意选择一个随机的起始方向,解决反问题,然后检查成本函数。然后,您可以使用扰动分析来检查如何改变方向。例如,如果您检查当前方向周围的相似方向(即立方网格中的8个点),则可以得到成本函数在各个方向上的变化的二阶近似值。

二阶近似(由于它是多元的-定向为3维,所以称为Hessian矩阵),您可以找到成本函数的梯度的零交叉点(即预测的局部最小值)。

使用新的预测方向,只需再次将其放置在逆求解器中,然后重复进行直到精度足够为止。

请注意,这可能不太有效,因为逆运动学问题本身必须迭代求解(因此您反复使用本身需要一段时间才能求解的函数)。此外,所涉及的代码可能还不如成熟的优化算法,但是它仍然是相当可观的,并且对时间的投入并不小。


使用这两种方法(作为非线性程序形式求解或使用函数迭代求解反问题),如果存在多个局部极小值,则求解可能不是最佳的。在这种情况下,您可以尝试使用各种方法来找到全局最小值。即使使用非线性编程求解器,也应使用初始值(例如,关节角度)为它播种。您可以使用各种方式生成的种子重复运行任一方法:


随机重启(随机生成)
基于网格的

或其他自定义方法。

但是请注意,如果有很多最小值,则没有什么好方法可以保证找到全局最小值。您只能提高机会。

#2 楼

由于问题是关于工业机器人的,因此我们可能没有机器人的动力学模型,因此我假设我们正在寻找仅优化运动学准则的解决方案。

机器人机器人具有逆运动学的封闭形式解决方案,但不幸的是,末端执行器具有额外的旋转自由度,这意味着机器人具有7个自由度。但是,由于这仅仅是一个自由度,因此它并没有像人们想象的那么重要。

对于这种几乎非冗余的机器人,一个常见的技巧是锁定额外的自由度并解决分析剩余的关节值。假设我们为6自由度机器人编写了一个封闭形式的IK解算器,该解算器平均返回$ 0.05 $ ms的解。通过从$ 1 $迭代到$ 360 $,您可以找到在大约$ 18 $ ms内离散化笔角$ 1 ^ \ circ $的最佳解决方案,考虑到该应用程序可能绰绰有余。

如果大多数时候笔只移动一点(例如画线时),另一个加快搜索速度的技巧是使用数字IK,例如伪逆方法:

让$ q_1 $为机器人的当前配置,让$ J $为机器人的Jacobian,让$ \ Delta x $为目标相对于当前末端执行器变换的位移。对$ \ Delta q $求解$ \ Delta x = J \,\ Delta q $并计算新配置$ q_2 = q_1 + \ Delta q $。我在这里跳过的细节,但解决方案$ \三角洲q $应尽量减少$ \ | \三角洲q \ | $的正确所选指标

这是为7做自由度机械手,并再次应。只需要几分之一毫秒。尽管$ q_2 $可能不是有效的配置(联合值可能超出范围)并且可能不是准确的IK解决方案(不过,您可以采取更多的伪逆步骤),但在大多数情况下,这是一个不错的起点使用封闭形式的求解器进行搜索。

#3 楼

有一个很好的封闭形式。假设我们不在乎$ r_z $是什么(即我们不在乎如何更改它)。

$$
\ mathbf {J} ^ {-1} \ dot {\ mathbf {X}} =
\ dot {\ mathbf {\ Theta}} =
\ begin {bmatrix}
\ vec {j_ {1}}和\ vec { j_ {2}}&\ vec {j_ {3}}&\ vec {j_ {4}}&\ vec {j_ {5}}&\ vec {j_ {6}}
\ end {bmatrix}
\开始{bmatrix}
\ dot {x} \\
\ dot {y} \\
\ dot {z} \\
\ dot {r_x } \\
\ dot {r_y} \\
\ dot {r_z}
\ end {bmatrix}
=
\ begin {bmatrix}
\ dot {\ theta_1} \\
\ dot {\ theta_2} \\
\ dot {\ theta_3} \\
\ dot {\ theta_4} \\
\ dot {\ theta_5} \\
\ dot {\ theta_6} \\
\ end {bmatrix}
$$
其中$ \ vec {j_ {i}} $是$ \ mathbf {J} ^ {-1} $的$ i ^ {th} $列。
我们可以将$ \ dot {\ mathbf {\ Theta}} $分解为依赖于$ \的部分点{r_z} $和不包含的部分。
$$
\ dot {\ mathbf {\ Theta}} =
\ dot {\ mathbf {\ Theta}} _ { \ dot {x} \ dots \ dot {r_y}} + \ dot {\ mathbf {\ Theta}} _ {\ dot {r_z}}
\\
\ dot {\ mathbf {\ Theta }} _ {\ dot {r_z}} =
\ vec {j_ {6}}
\ dot {r _z}
$$
因此,现在游戏已经成为了,让我们最小化
$$
(\ dot {\ mathbf {\ Theta}} _ {\ dot {x} \点\ dot {r_y}} + \ dot {\ mathbf {\ Theta}} _ {\ dot {r_z}})^ T
D(\ dot {\ mathbf {\ Theta}} _ {\ dot { x} \ dots \ dot {r_y}} + \ dot {\ mathbf {\ Theta}} _ {\ dot {r_z}})
$$
对于某些对角矩阵$ D $,如ronalchn所说以上。我将使用$ A = \ dot {\ mathbf {\ Theta}} _ {\ dot {x} \ dots \ dot {r_y}} $和$ B = \ dot {\ mathbf {\ Theta}} _ {\ dot {r_z} ^ *} $以便于查看。

我们可以将其扩展为
$$
A ^ TDA + 2B ^ TDA + B ^ TDB \ \
\ text {or} \\
A ^ TDA + 2 \ dot {r_z} \ vec {j_ {6}} ^ TDA + \ dot {r_z} ^ 2 \ vec {j_ {6} } ^ TD \ vec {j_ {6}}
$$

现在我们有一个简单的方程可以区分$ \ dot {r_z} $。我们找到关于$ \ dot {r_z} $的导数并将其设置为$ 0 $。
$$
2 \ vec {j_ {6}} ^ TDA + 2 \ dot {r_z} \ vec {j_ {6}} ^ TD \ vec {j_ {6}} = 0 \\
\ dot {r_z} = \ frac {-\ vec {j_6} ^ TDA} {\ vec {j_6} ^ TD \ vec {j_6}}
$$
这样可以最小化两个姿势之间的关节角度“距离”。