视频链接(含中文字幕):(中英强推!)2024斯坦福最值得学习的【机器人学导论】通俗易懂秒上手!CS223A-Introduction To Robotics
空间表示与坐标变换
主要分为两个部分,一是定点在不同坐标系下坐标的变换,二是点在同一坐标系下坐标的变换。
坐标系变换
考虑将坐标系的变换分成两个部分:旋转与平移。

BAR=[AX^BAY^BAZ^B]
其中 AX^B 是 B 坐标系的 X 轴在 A 坐标系下的坐标。
AP=BARBP
由于 BAR 是一个正交矩阵,所以 ABR=BAR−1=BART。

AP=BARBP+APBORG
构建矩阵 BAT 如下:
BAT=[BAR000APBORG1]
可得
[AP1]=BAT[BP1]
由于 BAT 是一个齐次矩阵,所以可以连续左乘来表示一系列变换。
另外,BAT 的逆矩阵为:
BAT−1=ABT=[BART000−BARTAPBORG1]
位置变换
位置变换同样分为旋转与平移两部分。

AP2=AP1+AQ
为了统一表达,我们尝试将平移变换也表示为矩阵乘法的形式,构建矩阵 DQ(q) 如下:
DQ(q)=100001000010qxqyqz1
其中 [qx,qy,qz]T 是 AQ 的坐标。

为了方便,我们仅考虑绕某一坐标轴旋转的情况,其他更普遍的情况可以通过绕三个坐标轴的旋转来实现。
绕 X、Y、Z 轴旋转的矩阵分别为:
RX(θ)=10000cosθsinθ00−sinθcosθ00001
RY(θ)=cosθ0−sinθ00100sinθ0cosθ00001
RZ(θ)=cosθsinθ00−sinθcosθ0000100001
最终的位置变换矩阵可以通过平移和旋转矩阵的乘积来表示,以绕 Z 轴旋转为例:
T=DQ(q)RZ(θ)=cosθsinθ00−sinθcosθ000010qxqyqz1
[AP21]=T[AP11]
朝向表示
有关欧拉角表示朝向导致的万向锁问题和四元数的详细介绍,可参考这两篇文章:四元数与三维旋转和 Bonus: Gimbal Lock,这里仅做简单说明。
用欧拉角等绕坐标轴旋转的方法表示朝向时,存在万向锁问题,即当某个旋转角度达到特定值时,两个旋转轴会重合,导致失去一个自由度,无法区分两个旋转轴的旋转,具体表现为无法通过旋转矩阵求出所有的欧拉角。
比如,当绕 Y 轴旋转角度 β=90∘ 时,
BARXYZ(γ,β,α)=00−1cosαsinγ−sinαcosγsinαsinγ+cosαcosγ0cosαcosγ+sinαsinγsinαcosγ−cosαsinγ0
此时通过给出的旋转矩阵,无法求得 α 和 γ 的值,其他的旋转方式也是同样,而使用四元数表示朝向时则不会出现上述情况。
四元数的表示方式为:坐标系绕单位向量 (kx,ky,kz) 旋转角度 θ,其四个参数分别为:
ϵ1ϵ2ϵ3ϵ4=kxsin2θ,=kysin2θ,=kzsin2θ,=cos2θ
旋转矩阵为:
Rϵ=1−2ϵ22−2ϵ322ϵ1ϵ2+2ϵ3ϵ42ϵ1ϵ3−2ϵ2ϵ42ϵ1ϵ2−2ϵ3ϵ41−2ϵ12−2ϵ322ϵ2ϵ3+2ϵ1ϵ42ϵ1ϵ3+2ϵ2ϵ42ϵ2ϵ3−2ϵ1ϵ41−2ϵ12−2ϵ22
若给定旋转矩阵,则四元数的参数可以通过以下公式求得:
ϵ1ϵ2ϵ3ϵ4=4ϵ4r32−r23,=4ϵ4r13−r31,=4ϵ4r21−r12,=211+r11+r22+r33
正运动学
正运动学是指已知机器人各个关节的参数,求解机器人末端执行器的位置和朝向的过程。
D-H 表示法

首先对机械臂的关节进行建系,对于每个关节 i,取 Z^i 轴与关节轴线重合,X^i 轴垂直于 Z^i 和 Z^i+1 轴,原点位于 Z^i 和 X^i 轴的交点处,Y^i 轴满足右手定则。
D-H 表示法中,每个关节 i 的参数包括:
- ai:Z^i 与 Z^i+1 轴沿 X^i 轴的平移距离
- αi:Z^i 与 Z^i+1 轴绕 X^i 轴的旋转角度
- di:X^i−1 与 X^i 轴沿 Z^i 轴的平移距离
- θi:X^i−1 与 X^i 轴绕 Z^i 轴的旋转角度
这里针对几种特殊情况作出补充:
- 当 Z^i 和 Z^i+1 轴平行时,X^i 轴可以任意选取一个垂直于 Z^i 和 Z^i+1 轴的位置,通常我们选取使 di 为 0 的位置
- 当 Z^i 和 Z^i+1 轴重合时,X^i 轴可以任意选取一个垂直于 Z^i 轴的位置和方向,通常我们选取使 di 和 θi 都为 0 的 X^i 轴
- 当 Z^i 和 Z^i+1 轴垂直时,X^i 轴选取 Z^i 和 Z^i+1 轴的公垂线。公垂线有两个方向,可以随意选取,通常我们选取使 ai 为正的方向
- 对于最后一个关节,由于 没有 Z^n+1 轴,所以 X^n 轴可以任意选取一个垂直于 Z^n 轴的位置和方向,通常我们选取使 dn+1 和 θn+1 都为 0 的 X^n 轴。
简单来说,有多种选取方式时,尽量选取使 D-H 参数中 0 尽量多的的方式,这样可以简化后续的计算。
其中,对于转动关节,di 是常数,θi 是变量;对于移动关节,di 是变量,θi 是常数。
特别定义第 0 个坐标系与第 n+1 个坐标系分别为基坐标系和末端执行器坐标系,它们分别与第 1 个关节和第 n 个关节的关节变量为 0 时的坐标系重合,由此可得第 1 和第 n 个关节的 D-H 参数(以转动关节为例,此时 θi 为关节变量):
a0=0,α0=0,d1=0,θ1=θ
an=0,αn=0,dn+1=0,θn+1=θ
根据上述参数,可以构建每个关节变换到前一关节的变换矩阵 ii−1T:先让坐标系沿 Z^i 轴平移 di 得到坐标系 P,再绕 Z^i 轴旋转 θi 得到坐标系 Q,接着沿 X^i 轴平移 ai 得到坐标系 R,最后绕 X^i 轴旋转 αi,这一过程可以表示为矩阵乘法:
i−1P=Ri−1TQRTPQTiPTiP

各个中间变换矩阵就不列出来了,总之最终可以得到:
ii−1T=cosθisinθicosαi−1sinθisinαi−10−sinθicosθicosαi−1cosθisinαi−100−sinαi−1cosαi−10ai−1−disinαi−1dicosαi−11
通过连续左乘每个关节的变换矩阵,就可以得到末端执行器坐标系相对于基坐标系的变换矩阵。
另外,对于类似球关节这类具有多个自由度的关节,可以将其分解为多个转动关节来处理,这些转动关节的 X 轴的选取尽量与下一级的 X 轴平行或重合,不行就选一个符合右手定则的方向,D-H 参数中的平移部分为 0,旋转部分为相应的旋转角度。
雅可比矩阵
首先我们需要明确一点:在数学上,“雅可比矩阵”仅仅指的是一个向量函数对另一个向量的一阶偏导数矩阵,而不是一个特指的矩阵。所以在这一部分的分析中我们可能会看到有好几个不同意义的矩阵都叫雅可比矩阵,这是没有问题的,但是在机器人学中,我们通常情况下所说的雅可比矩阵是指末端执行器坐标系的速度与关节速度之间的关系矩阵。
另外,为了表述方便,将关节变量统一为 qi=ϵˉiθi+ϵidi,其中 ϵˉi=1−ϵi,若关节 i 是转动关节,则 ϵi=0,qi=θi;若关节 i 是移动关节,则 ϵi=1,qi=di,下面的内容中如果出现 ϵ 和 ϵˉ,含义相同。
微分运动
在正运动学里面,我们已经得到了末端执行器坐标系相对于基坐标系的变换矩阵 n+10T,通过这个矩阵我们建立起了末端执行器坐标系与基坐标系之间的位置和朝向的关系,现在我们考虑,如果关节发生微小的变化,那么末端执行器的坐标系会发生什么样的变化,即,我们想要建立起 δq 与 δx 之间的关系。
一个非常自然的想法是,既然我们可以用 n+10T 来表示末端执行器坐标系与基坐标系之间的位置和朝向的关系,那么,我们将这个矩阵重新写成一个向量,然后求这个向量对关节变量 q 的雅可比矩阵,就可以得到 δq 与 δx 之间的关系了。
然而,这样存在几个问题:
- 刚体在三维空间中实际只有 6 个自由度,但是我们却用了 12 个参数来表示其运动,这其中有许多冗余信息,使得整个雅可比矩阵变得非常庞大,计算起来非常麻烦。
- 我们使用的这 12 个参数并不是唯一能够表示末端执行器位置与朝向的方式,这就导致了我们求得的雅可比矩阵并不是一个特指的矩阵,而是一个依赖于我们选择的参数化方式的矩阵,比如,我们也可以选择一个 7×1 的向量来表示末端执行器的位置和朝向,其中前 3 个参数表示位置,后 4 个参数表示朝向的四元数,这样我们求得的雅可比矩阵就会与之前的雅可比矩阵完全不同。
因此,我们需要找到一种更简洁、更直接的方式来表示末端执行器的运动,这样我们就可以得到一个更小、更特指的雅可比矩阵。
基本雅可比矩阵
一个简单的想法是:直接使用线速度与角速度来表示末端执行器的运动不就行了吗。
还真是,所以接下来我们推导一下将 q˙ 映射到末端执行器速度与角速度的雅可比矩阵。

考虑两相邻关节坐标系速度的递推关系,对于线速度 vi+1 而言,它由三部分组成,一部分是坐标系 i 的线速度,一部分是由于坐标系 i 绕 Z 轴旋转引起的线速度,最后一部分是坐标系 i+1 自身的线速度(平移关节),即:
vi+1=vi+ωi×Pi+1+d˙i+1Zi+1
对于角速度 ωi+1 而言,它由两部分组成,一部分是坐标系 i 的角速度,另一部分是坐标系 i+1 自身的角速度(转动关节),即:
ωi+1=ωi+θ˙i+1Zi+1
由于线速度与角速度矢量都是方向矢量,因此转换坐标系时不用考虑平移的问题,直接左乘旋转矩阵即可。我们将上述关系式的坐标系转换一下得到:
i+1vi+1i+1ωi+1=ii+1R(ivi+iωi×Pi+1)+d˙i+1i+1Zi+1=ii+1Riωi+θ˙i+1i+1Zi+1
初始条件:0ω0=0,0v0=0,通过瞪眼法数学推导可以得到:
0ωn0vn=i=1∑nθ˙i0Zi=i=1∑nθ˙i0Zi×Pi,n+i=1∑nd˙i0Zi
用之前提到的统一的关节变量 qi 来表示上述关系式:
0ωn0vn=i=1∑n(ϵˉi0Zi)q˙i=i=1∑n[ϵi0Zi+ϵˉi(0Zi×Pi,n)]q˙i
由此,我们就得到了最后一个关节坐标系的线速度与角速度与关节速度之间的关系矩阵:
J=[ϵ10Z1+ϵˉ1(0Z1×P1,n)ϵˉ10Z1ϵ20Z2+ϵˉ2(0Z2×P2,n)ϵˉ20Z2⋯⋯ϵn0Zn+ϵˉn(0Zn×Pn,n)ϵˉn0Zn]
然而,这个雅可比矩阵的计算看上去就很困难,尤其是前三行线速度对应的部分,有没有什么简单一点的方法来计算呢?
有的,兄弟,有的。
尽管我们并不能通过对欧拉角等直接求导来计算角速度,但是我们可以直接对位移向量的分量求偏导来计算线速度啊,因此,我们可以直接把第一行改为对从坐标系 0 到坐标系 n 的位移向量 P0,n 求 q 的偏导。同时,第二行我们也可以改成含有旋转矩阵的形式,因为之前我们求 n+10T 时已经得到了旋转矩阵,这里也就可以直接拿过来用。
令 Z=[001]T,则雅可比矩阵可表示为:
J=[∂q1∂P0,nϵˉ110RZ∂q2∂P0,nϵˉ220RZ⋯⋯∂qn∂P0,nϵˉnn0RZ]
得到了最后一个关节坐标系的雅可比矩阵之后,我们还差最后一步,从最后一个关节坐标系推到末端执行器坐标系。
由于末端执行器自身不进行旋转或者平移,因此可以得到:
nvenωe=nvn−Pn,e×nωn=nωn
将叉乘转换为矩阵乘法的形式,就可以得到:
[nvenωe]=[I0−nP^n,eI][nvnnωn]
其中 P^n,e=0Pn,e,z−Pn,e,y−Pn,e,z0Pn,e,xPn,e,y−Pn,e,x0,P^n,ex=Pn,e×x。
转换到基坐标系下,就可以得到:
[0ve0ωe]=[I0−n0RnP^n,en0RTI][0vn0ωn]
也就是说:
Je=[I0−n0RnP^n,en0RTI]Jn
关于 −n0RnP^n,en0RT 项,它其实是 −0P^n,e 的坐标变换形式。
因为 0P×0ω=n0R(nP×nω)=n0R(nP^0nR0ω)=n0RnP^n0RT0ω,所以 0P^=n0RnP^n0RT。
这样我们就得到了关节速度与末端执行器线速度和角速度之间的雅可比矩阵,这时再考虑关节角速度与最开始说的末端执行器位置与朝向之间的关系,我们发现好像只需要再在速度左边再乘一个转换矩阵就可以了。
举个例子,从速度向量映射到用笛卡尔坐标系表示位置,用欧拉角表示朝向的向量的矩阵是:
X=(x,y,z),xR=(α,β,γ)
EP(X)=100010001,ER(xR)=−sinβsinαcosβcosαsinβsinαsinβcosαcosβsinα−sinβcosα100
[X˙x˙R]=[EP(X)00ER(xR)][vω]
像这样,当我们需要使用不同的位置和朝向表示方法时,只需要使用对应的转换矩阵就可以了,而这个转换矩阵是固定的,这也降低了求解雅可比矩阵的复杂度。
另外可以看到,当 β=kπ 时,ER(xR) 中的一些元素值会变成无穷大,这也是欧拉角万向锁问题的具体体现之一。
运动学奇异点
运动学奇异点是指雅可比矩阵的行列式为零,或者说不满秩的点,此时末端执行器在某些方向上的运动无法通过关节的运动来实现,也就是丢失了自由度,常引发关节速度突变、停滞或路径失控的现象。
例如,将你的手臂想象成一个有两个转动关节(肩膀和手肘)的机械臂,当你的手臂完全伸直,也就是第二个关节的旋转角度为 0 时,你的手臂就丧失了在手臂方向的运动能力,也就是说你不能把手伸得更长了。
以这个机械臂为例。

其雅可比矩阵为(仅考虑 x,y 时):
J=[−l1sinθ1−l2sin(θ1+θ2)l1cosθ1+l2cos(θ1+θ2)−l2sin(θ1+θ2)l2cos(θ1+θ2)]
其奇异点为 θ2=kπ
考虑对这个雅可比矩阵求逆,得到:
J−1=l1l2sinθ21[l2cos(θ1+θ2)−l1cosθ1−l2cos(θ1+θ2)−l2sin(θ1+θ2)l1sinθ1+l2sin(θ1+θ2)]
当 θ2=kπ 时,sinθ2=0,J−1 不存在,同时,当 θ2≈kπ 时,sinθ2≈0,J−1 的元素值会变得非常大,这时使用 q˙=J−1v 求解产生一定速度所需要的关节速度会导致关节速度急剧增大,引发一系列问题。
静力
雅可比矩阵不仅可以表示末端执行器的速度与关节速度之间的关系,还可以表示末端执行器的力与关节力矩之间的关系,这里先直接给出结论。
τ=JTF
接下来用虚功原理推导一下,理论上来说在这个课程里面 Khatib 教授用了三种方法来推导,但是我懒得写另外两种了,反正最后的结果是一样的,就选一种我个人最喜欢的方法推一推就行了。
令 τ=τ1⋮τn 为关节力矩向量,F=FxFyFz 为末端执行器产生的力。假设机械臂产生了一个微小的位移 δx,由于这个系统没有能量损失,所以末端执行器产生的力做的功应该等于关节力矩做的功,即:
τTδq=FTδx
而众所周知 δx=Jδq,代入上式得:
τTδq=FTJδq
因此:
τT=FTJ
左右同时取转置即可得到:
τ=JTF
轨迹规划
在实际应用中,我们通常需要让机器人按照特定的路径运动,这就涉及到轨迹规划的问题。轨迹规划的目标是生成一个满足特定约束条件的路径,使得机器人能够按照这个路径运动。
一般而言,当我们提到轨迹规划时,很容易想到的是让末端执行器在空间中通过一条给定的路径从起点到达终点的过程,然而,在笛卡尔坐标系下进行轨迹规划可能会存在一些问题,最典型的问题在于我们无法保证规划的路径是可行的,比如下面这些情况:



此外,在笛卡尔坐标系下进行轨迹规划还存在复杂度过大等问题,总之,在实际应用中,我们通常会选择在关节空间内进行轨迹规划,来避免以上问题,不过,在分析过程中,我们可以先用一个统一的变量 u 来表示可能用到的变量,比如关节角度,笛卡尔坐标之类的。
轨迹规划最简单的方法当然是直接用线段连接起点和终点,然而这种方法规划出的轨迹的速度会出现突变,尤其是存在一系列中间点时,而突变的速度意味着无穷大的加速度,这显然是不现实的,所以我们需要一些更平滑的轨迹规划方法来生成满足加速度约束的轨迹。
下面简单介绍两种用于轨迹规划的方法。
三次多项式
当只存在起点和终点时,我们希望规划出的路径满足如下条件:
u(0)u(t)u˙(0)u˙(t)=u0=uf=0=0
即从起点出发,到终点停止,且初始和终止速度都为零。

我们使用一个三次多项式来拟合这个轨迹:
u(t)=a0+a1t+a2t2+a3t3
由上面的约束条件可以解得:
a0a1a2a3=u0=0=t23(uf−u0)=t3−2(uf−u0)
当存在中间点时,我们可以对相邻的两个中间点进行同样的拟合,但是由于我们大部分情况下不希望机械臂走走停停,而是希望它能尽量平滑地通过这些路径点,所以路径点处的速度不一定为 0,这时可以解得三次多项式的参数为:
a0a1a2a3=u0=u˙0=t23(uf−u0)−t2u˙0+u˙f=t3−2(uf−u0)+t2u˙0+u˙f
至于中间点的速度如何取得,这里简单介绍三种方法:
- 指定在该点处机械臂在笛卡尔坐标系下的线速度和角速度,再通过雅可比矩阵求得关节速度。
- 使用某些启发式算法让程序自己计算中间点的速度,比如:假设用线段将相邻中间点连起来,若某点前后两条线段斜率正负相反,则该点速度取为 0,否则取为前后两条线段斜率的平均值。
- 采用使中间点处加速度连续的方法让程序自己计算,设置限制条件 u˙1(t)=u˙2(0),u¨1(t)=u¨2(0) 即可。
当然这种方法还可以拓展,由于三次多项式只有四个参数,所以我们最多只能设置四个不相关的约束条件,如果我们需要设置更多的约束条件,比如说加速度为零,或者说在某个时间点处的速度为某个特定值,那就可以使用更高次的多项式来拟合,这里就不展开说了,方法是类似的。
与抛物线拟合的线性函数
另一种想法是,既然线性函数在各个路径点处存在速度突变的问题,那我们在这些点处用平滑的二次函数拟合一下不就好了吗。

(这个图是从讲义中截下来的,有一点小错误,需要假设 t0=0)
不妨假设两端的二次函数具有相同的持续时间,这样它们的加速度也就是相同的。
由方程
21u¨tb2+u¨tb(t−2tb)+21u¨tb2=uf−u0
解得:
tb=2t−2u¨u¨2t2−4(uf−u0)u¨
其中 u¨ 是前后两段二次函数的加速度。

当存在中间点时,公式如下:
- 第一段轨迹:
u¨1t1u˙12t12=sgn(u2−u1)∣u¨1∣=td12−td122−u¨12(u2−u1)=td12−21t1u2−u1=td12−t1−21t2
- 中间轨迹:
u¨ktku˙jktjk=sgn(u˙kl−u˙jk)∣u¨k∣=u¨ku˙kl−u˙jk=tdjkuk−uj=tdjk−21tj−21tk
- 最后一段轨迹:
u¨ntnu˙(n−1)nt(n−1)n=sgn(un−1−un)∣u¨n∣=td(n−1)n−td(n−1)n2−u¨n2(un−un−1)=td(n−1)n−21tnun−un−1=td(n−1)n−21tn−1−tn
通常只需要指定各关节的位置 ui,相邻两轨迹点之间的时间 tdij,以及每个轨迹点处的加速度 ∣u¨i∣ 即可。
另外,由上面那张图可以看出,这种方法拟合的轨迹并没有实际经过那些中间点,大部分情况下这是没有问题的,因为很多时候我们给轨迹设置中间点只是为了避开某些障碍,经不经过中间点其实无伤大雅,不过如果一定要实际经过某个中间点的话也有办法,那就是在这个中间点两边设置两个伪中间点:

实时轨迹规划
由上面的两种方法生成的轨迹结果都是 u 关于时间的函数,在实时运行时,轨迹生成器利用该函数不断计算出 u,u˙ 和 u¨,并将信息传给控制系统。
对三次多项式来说,计算过程非常简单,只需要把 t 代入事先已经求得参数的多项式中即可算出 u,u˙ 和 u¨,在到达轨迹终点时,需要将 t 重置为 0,继续计算下一段轨迹。
对带抛物线拟合的线性函数来说情况就比较复杂了,需要先根据 t 判断当前是处于直线部分还是二次函数部分。处于直线部分时,计算如下:
uu˙u¨=uj+u˙jkt=u˙jk=0
处于二次函数部分时,计算如下:
tinbuu˙u¨=t−(21tj+tjk)=uj+u˙jk(t−tinb)+21u¨ktinb2=u˙jk+u¨ktinb=u¨k
在进入一个新的直线部分时,需要将 t 重置为 21tk。