假设我有一个机械臂,在 3D 空间中的点 A、B、C、D 处都有关节。设 D 为末端执行器(最底层的子代),A 为最顶层的父代。令 T 为空间中任意位置的目标点。目的是使末端执行器在顶层(父母)中以最小的旋转到达目标。
我最初的想法是:
1) 将手臂 C 旋转角度 TCD。2) 然后将手臂 B 旋转新角度 TBD。3) 然后将手臂 A 旋转新角度 TAD。
但是在第 2 步之后,末端执行器似乎指向远离目标。我做错了什么,我该如何解决?
假设我有一个机械臂,在 3D 空间中的点 A、B、C、D 处都有关节。设 D 为末端执行器(最底层的子代),A 为最顶层的父代。令 T 为空间中任意位置的目标点。目的是使末端执行器在顶层(父母)中以最小的旋转到达目标。
我最初的想法是:
1) 将手臂 C 旋转角度 TCD。2) 然后将手臂 B 旋转新角度 TBD。3) 然后将手臂 A 旋转新角度 TAD。
但是在第 2 步之后,末端执行器似乎指向远离目标。我做错了什么,我该如何解决?
在我开始使用一些更高级的方法之前,我是这样做的:
pe=desired_new_position;
for (i=0;i<number_of_actuators;i++)
{
// choose better direction
p=direct_kinematics(); d =|p-pe|; // actual step
actuator(i)--; p=direct_kinematics(); d0=|p-pe|; // previous step
actuator(i)+=2; p=direct_kinematics(); d1=|p-pe|; // next step
actuator(i)--; dir=0; d0=d;
if ((d0<d)&&(d0<d1)) dir=-1;
else if ((d1<d)&&(d1<d0)) dir=+1;
else continue;
for (;;)
{
actuator(i)+=dir; p=direct_kinematics(); d =|p-pe|;
if (d>d0) { actuator(i)-=dir; break; }
if (actuator(i) on the edge limit) break;
}
}
[笔记]
您可以通过某个步骤而不是 1 将其修改为 inc/dec 执行器位置
如果差异超过零,则停止,然后以较小的步长重新开始,直到step == 1
这将提高性能,但对于大多数应用程序来说就step=1
足够了,因为新位置通常靠近最后一个位置。
请注意,这可能会卡在本地最小值/最大值中
如果输出卡住(效应器位置不变),则随机化执行器并重试。这种情况的发生取决于运动学复杂性和您要使用的路径类型
如果手臂在顶部驱动比在底部驱动更多
然后尝试反转 i-for 循环
如果你必须控制效应器正常
那么您必须从 CCD 中排除其旋转轴并将其设置在 CCD 之前
很难直接编写代码,但是您可以从优化的角度解决这个问题(并且可以隐含许多最先进的方法来解决这个问题,可以在互联网上轻松找到)。设 x' 和 y' 是固定的最上面的 A,而 x'' 和 y'' 是目标。那么这个问题可以形式化如下,
其中 gamma_i 是每个关节的旋转权重(您可以简单地让 gamma_i=1),而 alpha_i 是旋转值。您的优化目标是在某些约束条件下获得父母的最小轮换。x', y', x'', y'' 是常数,其他是变量。可以添加其他不等式来限制旋转角度。
方程 f(x',y',x_1,y_1,alpha_1)=0 表示,随着 A 旋转 alpha_1,点 B 可以重新定位到 x_1,y_1。如果你可以指定旋转的细节(例如f是线性的,那么可以实现单纯形法,但似乎f是二次的)。
对不起我的英语不好,希望这可以帮助:p