SLAM十四讲学习总结(二):三维空间刚体运动

1. 向量及其坐标:向量是空间中一点指向另一点的箭头。而向量的坐标,是在指定了一个空间坐标系以后与向量对应的若干实数。



2. 向量坐标:
选定一组基 ( e 1 ⃗ , e 2 ⃗ , e 3 ⃗ ) (\vec{e_1},\vec{e_2},\vec{e_3}) (e1 ,e2 ,e3 ),则向量 a ⃗ \vec{a} a 在这组基下可表示为一个坐标:
a ⃗ = [ e 1 ⃗ , e 2 ⃗ , e 3 ⃗ ] [ a 1 a 2 a 3 ] = a 1 e 1 ⃗ + a 2 e 2 ⃗ + a 3 e 3 ⃗ \vec{a}=[\vec{e_1},\vec{e_2},\vec{e_3}]\begin{bmatrix}a1\\a2\\a3 \end{bmatrix}=a_1\vec{e_1}+a_2\vec{e_2}+a_3\vec{e_3} a =[e1 ,e2 ,e3 ]a1a2a3=a1e1 +a2e2 +a3e3
( a 1 , a 2 , a 3 ) T (a_1,a_2,a_3)^T (a1,a2,a3)T为向量 a ⃗ \vec{a} a 的坐标。坐标取值与向量本身和基都有关系。



3.内积和外积
内积(点乘): a ⋅ b = a T ⋅ b = ∣ a ∣ ∣ b ∣ c o s < a , b > = ∑ i = 1 3 a i b j \boldsymbol{a}\cdot \boldsymbol{b}=\boldsymbol{a^T}\cdot\boldsymbol{b}=|\boldsymbol{a}||\boldsymbol{b}|cos<\boldsymbol{a},\boldsymbol{b}>=\sum_{i=1}^3a_ib_j ab=aTb=abcos<a,b>=i=13aibj
外积(叉乘):
a × b = ∥ e 1 e 2 e 3 a 1 a 2 a 3 b 1 b 2 b 3 ∥ = [ a 2 b 3 − a 3 b 2 a 3 b 1 − a 1 b 3 a 1 b 2 − a 2 b 1 ] = [ 0 − a 3 a 2 a 3 0 − a 1 − a 2 a 1 0 ] b = a ^ b \boldsymbol{a}\times \boldsymbol{b}=\begin{Vmatrix}\boldsymbol{e_1}&\boldsymbol{e_2} &\boldsymbol{e_3}\\a_1&a_2&a_3\\b_1&b_2&b_3\end{Vmatrix}=\begin{bmatrix}a_2b_3-a_3b_2\\a_3b_1-a_1b_3\\a_1b_2-a_2b_1\end{bmatrix}=\begin{bmatrix}0&-a_3&a_2\\a_3&0&-a_1\\-a_2&a_1&0\end{bmatrix}\boldsymbol{b}=\boldsymbol{a}\hat{} \boldsymbol{b} a×b=e1a1b1e2a2b2e3a3b3=a2b3a3b2a3b1a1b3a1b2a2b1=0a3a2a30a1a2a10b=a^b
叉乘的大小为 ∣ a ∣ ∣ b ∣ s i n < a , b > ∣ |\boldsymbol{a}||\boldsymbol{b}|sin<\boldsymbol{a},\boldsymbol{b}>| absin<a,b>,在这里^符号将 a \boldsymbol{a} a写成反对称矩阵,所以叉乘可以看成是矩阵和向量的乘法。




4.坐标系欧式变换
刚体运动:三维空间中两个坐标系之间的转换,一次旋转加一次平移。
欧式变换:同一个向量在各个坐标系下的长度和夹角不会发生改变。

4.1旋转表示
设向量 a \boldsymbol{a} a在第一组单位正交基 ( e 1 , e 2 , e 3 ) (\boldsymbol{e_1},\boldsymbol{e_2},\boldsymbol{e_3}) (e1,e2,e3)下坐标为 [ a 1 , a 2 , a 3 ] T [a_1,a_2,a_3]^T [a1,a2,a3]T,在第二组单位正交基 ( e 1 ′ , e 2 ′ , e 3 ′ ) (\boldsymbol{e_1'},\boldsymbol{e_2'},\boldsymbol{e_3'}) (e1,e2,e3)下的坐标为 [ a 1 ′ , a 2 ′ , a 3 ′ ] T [a_1',a_2',a_3']^T [a1,a2,a3]T,向量在三维空间中的长度和角度固定,故有如下关系:
[ e 1 , e 2 , e 3 ] [ a 1 a 2 a 3 ] = [ e 1 ′ , e 2 ′ , e 3 ′ ] [ a 1 ′ a 2 ′ a 3 ′ ] [\boldsymbol{e_1},\boldsymbol{e_2},\boldsymbol{e_3}]\begin{bmatrix}a_1\\a_2\\a_3\end{bmatrix}=[\boldsymbol{e_1'},\boldsymbol{e_2'},\boldsymbol{e_3'}]\begin{bmatrix}a_1'\\a_2'\\a_3'\end{bmatrix} [e1,e2,e3]a1a2a3=[e1,e2,e3]a1a2a3
两边同时乘 [ e 1 T e 2 T e 3 T ] \begin{bmatrix} \boldsymbol{e_1^T}\\\boldsymbol{e_2^T}\\\boldsymbol{e_3^T}\end{bmatrix} e1Te2Te3T,得到:
[ a 1 a 2 a 3 ] = [ e 1 T e 1 ′ e 1 T e 2 ′ e 1 T e 3 ′ e 2 T e 1 ′ e 2 T e 2 ′ e 2 T e 3 ′ e 3 T e 1 ′ e 3 T e 2 ′ e 3 T e 3 ′ ] [ a 1 ′ a 2 ′ a 3 ′ ] \begin{bmatrix} a_1\\a_2\\a_3 \end{bmatrix}=\begin{bmatrix} \boldsymbol{e_1^T}\boldsymbol{e_1'}&\boldsymbol{e_1^T}\boldsymbol{e_2'}&\boldsymbol{e_1^T}\boldsymbol{e_3'}\\\boldsymbol{e_2^T}\boldsymbol{e_1'}&\boldsymbol{e_2^T}\boldsymbol{e_2'}&\boldsymbol{e_2^T}\boldsymbol{e_3'}\\\boldsymbol{e_3^T}\boldsymbol{e_1'}&\boldsymbol{e_3^T}\boldsymbol{e_2'}&\boldsymbol{e_3^T}\boldsymbol{e_3'}\end{bmatrix} \begin{bmatrix}a_1'\\a_2'\\a_3'\end{bmatrix} a1a2a3=e1Te1e2Te1e3Te1e1Te2e2Te2e3Te2e1Te3e2Te3e3Te3a1a2a3
其中, [ e 1 T e 1 ′ e 1 T e 2 ′ e 1 T e 3 ′ e 2 T e 1 ′ e 2 T e 2 ′ e 2 T e 3 ′ e 3 T e 1 ′ e 3 T e 2 ′ e 3 T e 3 ′ ] \begin{bmatrix} \boldsymbol{e_1^T}\boldsymbol{e_1'}&\boldsymbol{e_1^T}\boldsymbol{e_2'}&\boldsymbol{e_1^T}\boldsymbol{e_3'}\\\boldsymbol{e_2^T}\boldsymbol{e_1'}&\boldsymbol{e_2^T}\boldsymbol{e_2'}&\boldsymbol{e_2^T}\boldsymbol{e_3'}\\\boldsymbol{e_3^T}\boldsymbol{e_1'}&\boldsymbol{e_3^T}\boldsymbol{e_2'}&\boldsymbol{e_3^T}\boldsymbol{e_3'}\end{bmatrix} e1Te1e2Te1e3Te1e1Te2e2Te2e3Te2e1Te3e2Te3e3Te3定义为矩阵 R R R,由两组基的内积组成,被称为旋转矩阵,描述了两个坐标系之间的旋转关系。
由于一组基的各个分量长度都为1,所以该旋转矩阵实际上是各基向量夹角的余弦,所以也称方向余弦矩阵,则坐标系旋转可表示为 a = R a ′ \boldsymbol{a}=\boldsymbol{R}\boldsymbol{a'} a=Ra

旋转矩阵是行列式为1的正交矩阵,行列式为1的正交矩阵都是旋转矩阵。
(注:正交矩阵A即 A T A = A A T = E A^TA=AA^T=E ATA=AAT=E,逆矩阵为自身转置)
旋转矩阵的或者转置代表一次相反的旋转,则:
a ′ = R T a = R − 1 a \boldsymbol{a'}=\boldsymbol{R^T}\boldsymbol{a}=\boldsymbol{R^{-1}}\boldsymbol{a} a=RTa=R1a

将n维旋转矩阵的集合定义如下,即行列式为1的正交矩阵:
S O ( n ) = { R ∈ R n × n ∣ R R T = I , d e t ( R ) = 1 } SO(n)=\lbrace{\boldsymbol{R}\in R^{n \times n}}|\boldsymbol{R}\boldsymbol{R^T}=\boldsymbol{I},det(\boldsymbol{R})=1\rbrace SO(n)={RRn×nRRT=I,det(R)=1}
这里涉及到了的概念,称SO(n)为特殊正交群

4.2平移表示
平移只要将平移向量加到旋转以后的坐标上即可,设平移向量为 t t t,它是一个坐标系的原点指向另一个坐标系原点的向量

综上,用一个旋转矩阵 R R R和一个平移向量 t t t就可以描述一次欧式变换。
设坐标系1、坐标系2,空间中有一向量 a \boldsymbol{ a} a,则坐标系2变换到坐标1可表示成如下形式: a 1 = R 12 a 2 + t 12 \boldsymbol{a_1}=\boldsymbol{R_{12}}\boldsymbol{a_2}+\boldsymbol{t_{12}} a1=R12a2+t12,其中,
旋转矩阵指“坐标系2的向量旋转到坐标系1”,在这里下标的变换关系都是从右至左。
平移向量指坐标系1原点指向坐标系2原点的向量,在坐标系1下取的坐标。注意, t 12 ≠ − t 21 \boldsymbol{t_{12}}\neq -\boldsymbol{t_{21}} t12=t21,尽管从向量层面来说二者确实相反,但所在坐标系不同故不能直接取反。




5.齐次坐标
在三维向量的末尾添加1变为四维向量,称为齐次坐标。这样就可以使每一次欧式变换都写成线性形式,一次欧式变换通过一个变换矩阵T表示,T的形式为:
T = [ R t 0 T 1 ] T=\begin{bmatrix} \boldsymbol{R}&\boldsymbol{t}\\ \boldsymbol{0^T}&1 \end{bmatrix} T=[R0Tt1]

[ a ′ 1 ] = [ R t 0 T 1 ] [ a 1 ] \begin{bmatrix} \boldsymbol{a'}\\1\end{bmatrix}=\begin{bmatrix} \boldsymbol{R}&\boldsymbol{t}\\ \boldsymbol{0^T}&1 \end{bmatrix} \begin{bmatrix} \boldsymbol{a}\\1\end{bmatrix} [a1]=[R0Tt1][a1]

变换矩阵T左上角为旋转矩阵,右上为平移向量,左下为0向量,右下为1,这种矩阵称为特殊欧氏群
S E ( 3 ) = { T = [ R t 0 T 1 ] ∈ R 4 × 4 ∣ R ∈ S O ( 3 ) , t ∈ R 4 × 4 } SE(3)=\lbrace{\boldsymbol{T}=\begin{bmatrix} \boldsymbol{R}&\boldsymbol{t}\\ \boldsymbol{0^T}&1 \end{bmatrix}\in R^{4 \times 4}}|\boldsymbol{R}\in SO(3),\boldsymbol{t}\in R^{4 \times 4}\rbrace SE(3)={T=[R0Tt1]R4×4RSO(3),tR4×4}
该矩阵的逆代表一个反向的变换,如下:
T − 1 = [ R T − R t t 0 T 1 ] \boldsymbol{T^{-1}}=\begin{bmatrix} \boldsymbol{R^T}&-\boldsymbol{R^t}\boldsymbol{t}\\ \boldsymbol{0^T}&1 \end{bmatrix} T1=[RT0TRtt1]




6.旋转向量及其与旋转矩阵转换
任意旋转都可以由一个旋转轴和一个旋转角刻画,所以用一个长度为旋转角度,方向与旋转轴一致旋转向量可以表示旋转。

设旋转角为 θ \theta θ,旋转轴为单位向量 n \boldsymbol{n} n,则旋转可以用 θ n \theta \boldsymbol{n} θn描述。

旋转向量到旋转矩阵的转换——罗德里格斯公式:
R = c o s θ I + ( 1 − c o s θ ) n n T + s i n θ n \boldsymbol{R}=cos\theta \boldsymbol{I}+(1-cos\theta)\boldsymbol{n}\boldsymbol{n^T}+sin\theta\boldsymbol{n} R=cosθI+(1cosθ)nnT+sinθn^

旋转矩阵到旋转向量的转换——矩阵的迹和特征向量:
t r ( R ) = c o s θ t r ( I ) + ( 1 − c o s θ ) t r ( n n T ) + s i n θ t r ( n tr(\boldsymbol{R})=cos\theta tr(\boldsymbol{I})+(1-cos\theta)tr(\boldsymbol{n}\boldsymbol{n^T})+sin\theta tr(n tr(R)=cosθtr(I)+(1cosθ)tr(nnT)+sinθtr(n^) = 3 c o s θ + ( 1 − c o s θ ) = 1 + 2 c o s θ ⟶ =3cos\theta+(1-cos\theta)=1+2cos\theta\longrightarrow =3cosθ+(1cosθ)=1+2cosθ
θ = a r c c o s t r ( R ) − 1 2 \theta=arccos\frac{tr(\boldsymbol{R})-1}{2} θ=arccos2tr(R)1
旋转轴的向量旋转后不改变,则:
R n = n \boldsymbol{R}\boldsymbol{n}=\boldsymbol{n} Rn=n
可通过求R的特征向量后归一化来求解旋转向量的方向向量。



7.欧拉角
将旋转分解为3次绕不同轴的旋转,即3个分离的转角,更具体地还需要分为绕3个固定轴还是绕旋转后的轴

Z、Y、X轴欧拉角——yaw(偏航)-pitch(俯仰)-roll(翻滚)——X轴朝向飞机头正前方——每次都是绕旋转之后的轴接着旋转—— [ r , p , y ] T [r,p,y]^T [r,p,y]T向量表示rpy角

万向锁问题:俯仰角(绕y轴)如果为正负90度时,第一次旋转与第三次旋转使用同一个轴,使得系统丢失一个自由度,所以在工程中很少应用。



8.四元数
三维旋转可以用单位四元数描述,四元数有点像复数,定义如下:
q = q 0 + q 1 i + q 2 j + q 3 k \boldsymbol{q}=q_0+q_1i+q_2j+q_3k q=q0+q1i+q2j+q3k
其中,虚部满足:
{ i 2 = j 2 = k 2 = − 1 i j = k , j i = − k j k = i , k j = − i k i = j , i k = − j \left\{ \begin{array}{c} i^2=j^2=k^2=-1 \\ ij=k,ji=-k \\ jk=i,kj=-i\\ ki=j,ik=-j \end{array} \right. i2=j2=k2=1ij=k,ji=kjk=i,kj=iki=j,ik=j
用标量和向量表达四元数:
q = [ s , v ] T , s = q 0 , v = [ q 1 , q 2 , q 3 ] T \boldsymbol{q}=[s,\boldsymbol{v}]^T,s=q_0, \boldsymbol{v}=[q_1,q_2,q_3]^T q=[s,v]T,s=q0,v=[q1,q2,q3]T
s为实部,v为虚部。

四元数具有加减法、乘法、数乘、求模||q||(乘积的模是模的乘积)、共轭(共轭与本身相乘得到实部为模长平方的实四元数)、 q − 1 = q ∗ / ∣ ∣ q ∣ ∣ 2 , q − 1 q = q q − 1 = 1 \boldsymbol{q^{-1}}=\boldsymbol{q^*}/||\boldsymbol{q}||^2 ,q^{-1}q=qq^{-1}=1 q1=q/q2,q1q=qq1=1,单位四元数共轭和逆相同)。

四元数表示旋转步骤
设点 p = [ x , y , z ] p=[x,y,z] p=[x,y,z],用四元数表示为 p = [ 0 , x , y , z ] T \boldsymbol{p}=[0,x,y,z]^T p=[0,x,y,z]T,经过四元数 q \boldsymbol{q} q的旋转后有如下结果:
p ′ = q p q − 1 \boldsymbol{p'}=\boldsymbol{q}\boldsymbol{p}\boldsymbol{q^{-1}} p=qpq1
将p‘的虚部取出就是旋转之后点的坐标。
四元数与旋转矩阵的转换关系
R = v v T + s 2 I + 2 s ( v × ) \boldsymbol{R}=\boldsymbol{v}\boldsymbol{v^T}+s^2\boldsymbol{I}+2s(\boldsymbol{v\times)} R=vvT+s2I+2s(v×)+ ( v × ) 2 (\boldsymbol{v}\times)^2 (v×)2
四元数与旋转向量的转换关系
{ θ = 2 a r c c o s s [ n x , n y , n z ] T = [ q 1 , q 2 , q 3 ] T / s i n θ 2 \left\{ \begin{array}{c} \theta=2arccoss \\ [n_x,n_y,n_z]^T=[q_1,q_2,q_3]^T/sin\frac{\theta}{2} \end{array} \right. {θ=2arccoss[nx,ny,nz]T=[q1,q2,q3]T/sin2θ



9.除了欧氏变换以外的其他变换
相似变换
T s = [ s R t 0 T 1 ] \boldsymbol{T_s}=\begin{bmatrix} s\boldsymbol{R}&t\\\boldsymbol{0^T}&1 \end{bmatrix} Ts=[sR0Tt1]
旋转部分多了一个缩放因子s,在对向量旋转后可以在x、y、z三个坐标上进行均匀缩放,相似变换不再保持图像面积不变,三维相似变换的集合也叫做相似相似变换群,记作Sim(3)。会改变体积比。
仿射变换
T A = [ A t 0 T 1 ] \boldsymbol{T_A}=\begin{bmatrix} \boldsymbol{A}&t\\\boldsymbol{0^T}&1 \end{bmatrix} TA=[A0Tt1]
仿射变换只要求A是可逆矩阵而不必是正交矩阵。会改变平行性和体积比。
射影变换
T P = [ A t a T v ] \boldsymbol{T_P}=\begin{bmatrix} \boldsymbol{A}&t\\\boldsymbol{a^T}&v \end{bmatrix} TP=[AaTtv]
左上角为可逆矩阵A,右上角为平移t,左下角为缩放 a T \boldsymbol{a^T} aT。这是最一般的变换,从真实世界到相机照片的变换可以看成一个射影变换。

10.Eigen数据结构
旋转矩阵(3x3):Eigen::Matrix3d
旋转向量(3x1):Eigen::AngleAxisd 初始化赋值:AngleAxisd a(PI/4,Vector3d(0,0,1)),显示时转换函数为.matrix()或者.toRotationMatrix()。
欧拉角(3x1):Eigen::Vector3d 可以通过matrix的.eulerAngles的函数转换得到。
四元数(4x1):Eigen::Quaterniond,可以通过旋转矩阵或者旋转向量初始化赋值。
欧氏变换矩阵(4x4):Eigen::Isometry3d,添加旋转的方法.rotate(rotation_vector或者rotation_matrix),添加平移向量的方法.pretranslate(Vector3d)
仿射变换(4x4):Eigen::Affine3d
射影变换(4x4):Eigen::Projective3d







习题:
只有部分的解答:
4.
旋转向量到旋转矩阵的转换——罗德里格斯公式:
R = c o s θ I + ( 1 − c o s θ ) n n T + s i n θ n \boldsymbol{R}=cos\theta \boldsymbol{I}+(1-cos\theta)\boldsymbol{n}\boldsymbol{n^T}+sin\theta\boldsymbol{n} R=cosθI+(1cosθ)nnT+sinθn^
旋转矩阵到旋转向量的转换——矩阵的迹和特征向量:
t r ( R ) = c o s θ t r ( I ) + ( 1 − c o s θ ) t r ( n n T ) + s i n θ t r ( n tr(\boldsymbol{R})=cos\theta tr(\boldsymbol{I})+(1-cos\theta)tr(\boldsymbol{n}\boldsymbol{n^T})+sin\theta tr(n tr(R)=cosθtr(I)+(1cosθ)tr(nnT)+sinθtr(n^) = 3 c o s θ + ( 1 − c o s θ ) = 1 + 2 c o s θ ⟶ =3cos\theta+(1-cos\theta)=1+2cos\theta\longrightarrow =3cosθ+(1cosθ)=1+2cosθ
θ = a r c c o s t r ( R ) − 1 2 \theta=arccos\frac{tr(\boldsymbol{R})-1}{2} θ=arccos2tr(R)1
旋转轴的向量旋转后不改变,则:
R n = n \boldsymbol{R}\boldsymbol{n}=\boldsymbol{n} Rn=n
可通过求R的特征向量后归一化来求解旋转向量的方向向量。

四元数与旋转矩阵的转换关系
R = v v T + s 2 I + 2 s ( v × ) \boldsymbol{R}=\boldsymbol{v}\boldsymbol{v^T}+s^2\boldsymbol{I}+2s(\boldsymbol{v\times)} R=vvT+s2I+2s(v×)+ ( v × ) 2 (\boldsymbol{v}\times)^2 (v×)2
四元数与旋转向量的转换关系
{ θ = 2 a r c c o s s [ n x , n y , n z ] T = [ q 1 , q 2 , q 3 ] T / s i n θ 2 \left\{ \begin{array}{c} \theta=2arccoss \\ [n_x,n_y,n_z]^T=[q_1,q_2,q_3]^T/sin\frac{\theta}{2} \end{array} \right. {θ=2arccoss[nx,ny,nz]T=[q1,q2,q3]T/sin2θ
5.

Matrix4d matrix44 = Matrix4d::Random();
cout<<"matrix44:"<<endl<<matrix44<<endl;
Matrix3d matrix33_extract = matrix44.block(0,0,3,3);
cout<<"matrix33_extract:"<<endl<<matrix33_extract<<endl;
matrix44.block(0,0,3,3)<<Matrix3d::Identity();
cout<<"exchanged_matrix44:"<<endl<<matrix44<<endl;

6.参考eigenMatrix.cpp中几种方程解法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值