二维刚体变换

欢迎访问我的博客首页


1. 平面旋转


  计算机中通常使用右手三维坐标系,因此,如果给图 1 中的坐标系 x O y xOy xOy 加上 z z z 轴,则 z z z 轴垂直纸面指向读者。 鉴于此,我们把图 1(左) 中绿色坐标系 O a O_a Oa 按箭头旋转到红色坐标系 O b O_b Ob 称为从 z z z 轴负方向看向正方向时的顺时针旋转。
在这里插入图片描述

图 1 平面上的坐标系顺时针旋转(左)与向量顺时针旋转(右)

1.1 使用平面向量基本定理推导旋转


  向量基本定理:任意一个 n 维向量一定可以由 n 个相同维度且线性无关的向量来线性表示。这 n 个向量称为一组基底向量,简称基底。如果这 n 个向量两两正交,称为正交基。如果这 n 个向量都是单位向量,称为单位基底。

  假设坐标系 O a O_a Oa 顺时针旋转 θ \theta θ 变成坐标系 O b O_b Ob,如图 1(左)。坐标系 O a O_a Oa 的单位正交基在坐标系 O a O_a Oa 中的坐标表示是 e x a = ( 1 , 0 ) T e_x^a=(1,0)^T exa=(1,0)T e y a = ( 0 , 1 ) T e_y^a=(0,1)^T eya=(0,1)T。坐标系 O b O_b Ob 的单位正交基在坐标系 O a O_a Oa 中的坐标表示是 e x b = ( c o s θ , s i n θ ) T e_x^b=(cos\theta, sin\theta)^T exb=(cosθ,sinθ)T e y b = ( − s i n θ , c o s θ ) T e_y^b=(-sin\theta, cos\theta)^T eyb=(sinθ,cosθ)T。平面上任意一点 P P P 在两个坐标系中的坐标是 P a P_a Pa P b P_b Pb。由向量基本定理知

[ e x a , e y a ] ⋅ P a = [ e x b , e y b ] ⋅ P b , [e_x^a, e_y^a] \cdot P_a = [e_x^b, e_y^b] \cdot P_b, [exa,eya]Pa=[exb,eyb]Pb,

所以

P a = [ e x a , e y a ] − 1 ⋅ [ e x b , e y b ] ⋅ P b = [ 1 0 0 1 ] − 1 ⋅ [ c o s θ − s i n θ s i n θ c o s θ ] ⋅ P b = [ c o s θ − s i n θ s i n θ c o s θ ] ⋅ P b . (1.1) \begin{aligned} P_a &= [e_x^a, e_y^a]^{-1} \cdot [e_x^b, e_y^b] \cdot P_b \\ &= \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}^{-1} \cdot \begin{bmatrix} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{bmatrix} \cdot P_b \\ &= \begin{bmatrix} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{bmatrix} \cdot P_b. \end{aligned} \tag{1.1} Pa=[exa,eya]1[exb,eyb]Pb=[1001]1[cosθsinθsinθcosθ]Pb=[cosθsinθsinθcosθ]Pb.(1.1)

我们令

R a b 坐标系顺 = [ c o s θ − s i n θ s i n θ c o s θ ] . (1.2) R^{坐标系顺}_{ab} = \begin{bmatrix} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{bmatrix}. \tag{1.2} Rab坐标系顺=[cosθsinθsinθcosθ].(1.2)

  这个 R a b 坐标系顺 R^{坐标系顺}_{ab} Rab坐标系顺 左乘平面上任意一点 P P P 在坐标系 O b O_b Ob 中的坐标,得到 P P P 在坐标系 O a O_a Oa 中的坐标。所以我们称它为坐标系顺时针旋转时 O b O_b Ob 坐标到 O a O_a Oa 坐标的变换。

1.2 使用几何关系推导旋转


  平面坐标系中任一长度为 r r r 的向量 O P a → = ( x a , y a ) \overrightarrow {OP_a} = (x_a, y_a) OPa =(xa,ya) 绕原点顺时针旋转 θ \theta θ 成为向量 O P b → = ( x b , y b ) \overrightarrow {OP_b} = (x_b, y_b) OPb =(xb,yb)。假设向量 O P a → \overrightarrow {OP_a} OPa x x x 轴正方向的夹角是 ϕ \phi ϕ,图 1(右)。则有

{ x a = r c o s ϕ y a = r s i n ϕ x b = r c o s ( ϕ + θ ) = r c o s ϕ c o s θ − r s i n ϕ s i n θ y b = r s i n ( ϕ + θ ) = r s i n ϕ c o s θ + r c o s ϕ s i n θ , (1.3) \left\{\begin{aligned} x_a &= r cos \phi \\ y_a &= r sin \phi \\ x_b &= r cos (\phi + \theta) = r cos \phi cos \theta - r sin \phi sin \theta\\ y_b &= r sin (\phi + \theta) = r sin \phi cos \theta + r cos \phi sin \theta, \end{aligned}\right. \tag{1.3} xayaxbyb=rcosϕ=rsinϕ=rcos(ϕ+θ)=rcosϕcosθrsinϕsinθ=rsin(ϕ+θ)=rsinϕcosθ+rcosϕsinθ,(1.3)

把前两个公式代入后两个公式得

{ x b = x a c o s θ − y a s i n θ y b = y a c o s θ + x a s i n θ . (1.4a) \left\{\begin{aligned} x_b &= x_a cos \theta - y_a sin \theta\\ y_b &= y_a cos \theta + x_a sin \theta \end{aligned}\right.. \tag{1.4a} {xbyb=xacosθyasinθ=yacosθ+xasinθ.(1.4a)

把公式 ( 1.4 a ) (1.4a) (1.4a) 写出矩阵相乘的形式

P b = [ c o s θ − s i n θ s i n θ c o s θ ] P a . (1.4b) P_b = \begin{bmatrix} cos \theta & -sin \theta \\ sin \theta & cos \theta \end{bmatrix} P_a. \tag{1.4b} Pb=[cosθsinθsinθcosθ]Pa.(1.4b)

我们令

R b a 向量顺 = [ c o s θ − s i n θ s i n θ c o s θ ] . (1.5) R^{向量顺}_{ba} = \begin{bmatrix} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{bmatrix}. \tag{1.5} Rba向量顺=[cosθsinθsinθcosθ].(1.5)

  这个 R b a 向量顺 R^{向量顺}_{ba} Rba向量顺 左乘平面上任意一点 P P P 在坐标系 O a O_a Oa 中的坐标,得到 P P P 在坐标系 O b O_b Ob 中的坐标。所以我们称它为向量顺时针旋转时 O a O_a Oa 坐标到 O b O_b Ob 坐标的变换。

1.3 总结


  由公式 ( 1.2 ) (1.2) (1.2) 和公式 ( 1.5 ) (1.5) (1.5) 可知:坐标系顺时针旋转时,把固定向量在旋转后的坐标系中的坐标变换到它在旋转前的坐标系中的坐标的变换,与坐标系不动时,把向量顺时针旋转后的坐标变换回旋转前的坐标的变换,互逆/互为转置。总结:

{ R a b 坐标系顺 = R a b 向量逆 = [ c o s θ − s i n θ s i n θ c o s θ ] R a b 坐标系逆 = R a b 向量顺 = [ c o s θ s i n θ − s i n θ c o s θ ] R a b ∗ = ( R b a ∗ ) − 1 = ( R b a ∗ ) T . (1.6) \left\{\begin{aligned} R^{坐标系顺}_{ab} &= R^{向量逆}_{ab} = \begin{bmatrix} cos \theta & -sin \theta \\ sin \theta & cos \theta \end{bmatrix} \\ R^{坐标系逆}_{ab} &= R^{向量顺}_{ab} = \begin{bmatrix} cos \theta & sin \theta \\ -sin \theta & cos \theta \end{bmatrix} \\ R^*_{ab} &= (R^*_{ba})^{-1} = (R^*_{ba})^T \end{aligned}\right.. \tag{1.6} Rab坐标系顺Rab坐标系逆Rab=Rab向量逆=[cosθsinθsinθcosθ]=Rab向量顺=[cosθsinθsinθcosθ]=(Rba)1=(Rba)T.(1.6)

其中,下标 a b ab ab 表示该变换矩阵把旋转后的坐标 P b P_b Pb 变换到旋转前的坐标 P a P_a Pa,下标 b a ba ba 表示该变换矩阵把旋转前的坐标 P a P_a Pa 变换到旋转后的坐标 P b P_b Pb

  以图 1(左) 为例,坐标系 O b O_b Ob 由坐标系 O a O_a Oa 顺时针旋转 45° 得到。则 O a O_a Oa 中的点 P a ( 1 , 2 ) P_a(1, 2) Pa(1,2) O b O_b Ob 中的坐标

P b = ( R a b 坐标系顺 ) − 1 P a = [ c o s π 4 s i n π 4 − s i n π 4 c o s π 4 ] [ 1 2 ] = [ 3 2 1 2 ] . P_b = (R^{坐标系顺}_{ab})^{-1} P_a = \begin{bmatrix} cos \frac{\pi}{4} & sin \frac{\pi}{4} \\ -sin \frac{\pi}{4} & cos \frac{\pi}{4} \end{bmatrix} \begin{bmatrix} 1 \\ 2 \end{bmatrix} = \begin{bmatrix} \frac{3}{\sqrt{2}} \\ \frac{1}{\sqrt{2}} \end{bmatrix}. Pb=(Rab坐标系顺)1Pa=[cos4πsin4πsin4πcos4π][12]=[2 32 1].

2. 平面刚体变换


  假设坐标系 O a O_a Oa 平移 t ⃗ a b = ( t a b x , t a b y ) T \vec t_{ab} = (t_{ab}^x, t_{ab}^y)^T t ab=(tabx,taby)T 且顺时针旋转 θ a b \theta_{ab} θab 变成坐标系 O b O_b Ob,如图 2(左)。平面上任意一点 P P P 在两个坐标系中的坐标是 P a P_a Pa P b P_b Pb
在这里插入图片描述

图 2 平面刚体变换

2.1 坐标变换


  由公式 1.2 1.2 1.2 知向量 O b P → \overrightarrow{O_bP} ObP 在坐标系 O a O_a Oa 中的坐标是 R a b 坐标系顺 ⋅ P b R^{坐标系顺}_{ab} \cdot P_b Rab坐标系顺Pb。又因为向量 O a O b → \overrightarrow{O_aO_b} OaOb 在坐标系 O a O_a Oa 中的坐标是 t ⃗ a b \vec t_{ab} t ab。所以向量 O a P → \overrightarrow{O_aP} OaP 在坐标系 O a O_a Oa 中的坐标

P a = O a O b → + O b P → = t ⃗ a b + R a b 坐标系顺 ⋅ P b = [ c o s θ a b − s i n θ a b t a b x s i n θ a b c o s θ a b t a b y 0 0 1 ] ⋅ P b = T a b 坐标系顺 ⋅ P b . (2.1) P_a = \overrightarrow{O_aO_b} + \overrightarrow{O_bP} = \vec t_{ab} + R^{坐标系顺}_{ab} \cdot P_b = \begin{bmatrix} cos \theta_{ab} & -sin \theta_{ab} & t_{ab}^x \\ sin \theta_{ab} & cos \theta_{ab} & t_{ab}^y \\ 0 & 0 & 1 \end{bmatrix} \cdot P_b = T^{坐标系顺}_{ab} \cdot P_b. \tag{2.1} Pa=OaOb +ObP =t ab+Rab坐标系顺Pb= cosθabsinθab0sinθabcosθab0tabxtaby1 Pb=Tab坐标系顺Pb.(2.1)

一般情况下,我们默认旋转指的是坐标系顺时针旋转,因此 R a b 坐标系顺 R^{坐标系顺}_{ab} Rab坐标系顺 可以简写为 R a b R_{ab} Rab T a b 坐标系顺 T^{坐标系顺}_{ab} Tab坐标系顺 可以简写成 T a b T_{ab} Tab。其中 R R R 称为旋转矩阵, T T T 因包含旋转和平移而称为变换矩阵。

  下面是 gmapping 实现公式 ( 2.1 ) (2.1) (2.1) 的代码。

Point phit = lp;
phit.x += *r * cos(lp.theta + *angle);
phit.y += *r * sin(lp.theta + *angle);

2.2 方向点


  坐标系 O a O_a Oa 与坐标系 O b O_b Ob 的关系可以用一个带方向的点表示。带方向的点是一个三元数 ξ a b = ( t a b x , t a b y , θ a b ) \xi_{ab} = (t_{ab}^x, t_{ab}^y, \theta_{ab}) ξab=(tabx,taby,θab),分别表示坐标系 O b O_b Ob 的原点在坐标系 O a O_a Oa 中的横坐标、纵坐标、从坐标系 O a O_a Oa 到坐标系 O b O_b Ob 的旋转角度。

  方向点 ξ \xi ξ 可以很容易地转换为变换矩阵 T T T。与变换矩阵相比,使用方向点表示二维变换有很多好处:维度更低,正好等于平面变换的自由度;两个方向点相加仍能表示二维变换,方便使用导数优化,而两个变换矩阵相加的结果不一定是变换矩阵。二维变换中的方向点类似三维变换中的李代数。

  假设坐标系 O b O_b Ob 平移 t ⃗ b c = ( t b c x , t b c y ) T \vec t_{bc} = (t_{bc}^x, t_{bc}^y)^T t bc=(tbcx,tbcy)T 且顺时针旋转 θ b c \theta_{bc} θbc 变成坐标系 O c O_c Oc,如图 2(右)。那么,坐标系 O c O_c Oc 也可以看作由坐标系 O a O_a Oa 平移 t ⃗ a c = t ⃗ a b + R a b ⋅ t ⃗ b c \vec t_{ac} = \vec t_{ab} + R_{ab} \cdot \vec t_{bc} t ac=t ab+Rabt bc 且顺时针旋转 θ a c = θ a b + θ b c \theta_{ac} = \theta_{ab} + \theta_{bc} θac=θab+θbc 而来。因此

ξ a c = [ t a c x t a c y θ a c ] = [ t a b x t a b y θ a b ] + [ c o s θ a b − s i n θ a b 0 s i n θ a b c o s θ a b 0 0 0 1 ] ⋅ [ t b c x t b c y θ b c ] . (2.2) \xi_{ac} = \begin{bmatrix} t_{ac}^x \\ t_{ac}^y \\ \theta_{ac} \end{bmatrix} = \begin{bmatrix} t_{ab}^x \\ t_{ab}^y \\ \theta_{ab} \end{bmatrix} + \begin{bmatrix} cos \theta_{ab} & -sin \theta_{ab} & 0 \\ sin \theta_{ab} & cos \theta_{ab} & 0 \\ 0 & 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} t_{bc}^x \\ t_{bc}^y \\ \theta_{bc} \end{bmatrix}. \tag{2.2} ξac= tacxtacyθac = tabxtabyθab + cosθabsinθab0sinθabcosθab0001 tbcxtbcyθbc .(2.2)

注意, t ⃗ a c = t ⃗ a b + R a b ⋅ t ⃗ b c \vec t_{ac} = \vec t_{ab} + R_{ab} \cdot \vec t_{bc} t ac=t ab+Rabt bc 而不是 t ⃗ a c = t ⃗ a b + t ⃗ b c \vec t_{ac} = \vec t_{ab} + \vec t_{bc} t ac=t ab+t bc。这是因为 t ⃗ b c \vec t_{bc} t bc 是坐标系 O b O_b Ob 中的坐标,需要先使用 R a b R_{ab} Rab 转换成坐标系 O a O_a Oa 中的坐标,再与 t ⃗ a b \vec t_{ab} t ab 相加。

  下面是 gmapping 实现公式 ( 2.2 ) (2.2) (2.2) 的代码。

OrientedPoint lp = p;
lp.x += cos(p.theta) * m_laserPose.x - sin(p.theta) * m_laserPose.y;
lp.y += sin(p.theta) * m_laserPose.x + cos(p.theta) * m_laserPose.y;
lp.theta += m_laserPose.theta;

3. 使用 Eigen


  使用 Eigen 库实现二维欧式变换。

// 顺时针旋转 45 度。Eigen::Rotation2D<double> 等价于 Eigen::Rotation2Dd。
Eigen::Rotation2D<double> R = Eigen::Rotation2Dd(M_PI / 4);
cout << R.angle() << endl;	// 弧度值。
cout << R.matrix() << endl;	// 二阶旋转矩阵。
// 二维单位变换(三阶矩阵)。
Eigen::Isometry2d T;
T.setIdentity();
cout << T.matrix() << endl;
// 二维一般变换(三阶矩阵)。
T.rotate(R);
T.pretranslate(Eigen::Vector2d(2, 1));
cout << T.matrix() << endl;

4. 误差公式


4.1 SBA


4.2 SPA


  相对 SBA,论文《Efficient Sparse Pose Adjustment for 2D mapping》提出了 SPA。假设全局位姿(在世界坐标系中的位姿)是

c = [ t , θ ] = [ x y θ ] . c = [t, \theta] = \begin{bmatrix} x \\ y \\ \theta \end{bmatrix}. c=[t,θ]= xyθ .

其中, ( x , y ) (x, y) (x,y) 表示二维坐标系的平移量, θ \theta θ 表示二维坐标系逆时针旋转的角度。

5. 参考


  1. 二维旋转矩阵,CSDN,2020。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值