第一章 坐标系基础:地心惯性坐标系、卫星本体坐标系、太阳翼坐标系、坐标转换矩阵
各位同学,咱们今天正式开讲。做卫星GNC,说白了就是跟坐标系打交道。你想想看,卫星在天上飞,太阳翼要追着太阳转,这中间所有的计算都绕不开一个核心问题——我在哪?我要去哪?我该怎么转?
我个人习惯,拿到一个控制任务,第一件事不是写代码,而是先把坐标系理清楚。坐标系乱了,后面全是坑。我在项目中遇到过不止一次,因为坐标系定义搞混,导致太阳翼指向偏差十几度,最后查了三天才发现是坐标转换矩阵写反了。嗯,这种教训一次就够了。
1.1 地心惯性坐标系(ECI)
地心惯性坐标系,简称ECI。它是我们描述卫星轨道运动的基准。说白了,就是一个在空间中固定不动的坐标系。
定义很简单:
- 原点:地球质心
- X轴:指向春分点(黄道与赤道的交点之一)
- Z轴:指向北极,与地球自转轴重合
- Y轴:由右手定则确定,Y = Z × X
为什么叫“惯性”?因为它不随地球自转。你想想看,如果坐标系跟着地球转,那卫星的位置描述会变得极其复杂。ECI坐标系给了我们一个“绝对”的参考。
重要概念:ECI坐标系是近似的惯性系。严格来说,地球在绕太阳公转,但对我们卫星控制来说,这个近似足够用了。
我记得刚入行时,有个老工程师跟我说:“ECI就是你的宇宙地图。” 这句话我一直记着。所有轨道计算、星历预报,都基于这个坐标系。
1.2 卫星本体坐标系(Body Frame)
卫星本体坐标系,是固定在卫星上的。它跟着卫星一起转。这个坐标系直接关系到姿态控制。
定义方式:
- 原点:卫星质心
- X轴:通常指向卫星飞行方向(速度方向)
- Z轴:指向对地面(或天底方向)
- Y轴:由右手定则确定,Y = Z × X
这里有个坑,我必须要说。不同卫星的本体坐标系定义可能不一样。有的卫星把Z轴指向天顶,有的指向天底。你接手一个项目,第一件事就是确认本体坐标系的定义文档。
避坑指南:我曾经因为本体坐标系定义搞反,导致姿态控制律输出符号错误。卫星在轨测试时,姿态一直往反方向偏。查了两天,最后发现是坐标系定义文档和代码注释不一致。从那以后,我要求所有代码里必须显式写出坐标轴定义,不能只靠注释。
1.3 太阳翼坐标系(Solar Array Frame)
太阳翼坐标系,是专门用来描述太阳翼姿态的。它固定在太阳翼上,随着太阳翼的转动而转动。
定义:
- 原点:太阳翼与卫星的连接点(通常是铰链点)
- X轴:沿太阳翼展开方向(指向翼尖)
- Z轴:垂直于太阳翼板面(指向光照面)
- Y轴:由右手定则确定,Y = Z × X
你可能会问:为什么单独搞一个坐标系?因为太阳翼要转动啊。卫星本体可能在对地定向,而太阳翼要追太阳。两个运动是解耦的,所以需要独立的坐标系来描述。
个人经验:我建议在代码里把太阳翼坐标系定义为一个独立的结构体。不要跟本体坐标系混在一起。这样后续做坐标转换时,逻辑会清晰很多。
1.4 坐标转换矩阵
好了,三个坐标系都有了。现在的问题是:怎么从一个坐标系转到另一个?答案就是坐标转换矩阵。
坐标转换矩阵,本质上是一个3×3的正交矩阵。它满足:
- 矩阵的逆等于它的转置(R-1 = RT)
- 行列式为+1(右手系)
最常见的转换是绕单轴旋转:
// 绕Z轴旋转角度θ
Rz(θ) = [cosθ -sinθ 0
sinθ cosθ 0
0 0 1]
// 绕Y轴旋转角度θ
Ry(θ) = [cosθ 0 sinθ
0 1 0
-sinθ 0 cosθ]
// 绕X轴旋转角度θ
Rx(θ) = [1 0 0
0 cosθ -sinθ
0 sinθ cosθ]
实际工程中,我们通常用3-1-2或3-2-1的旋转顺序。我个人习惯用3-2-1,也就是先绕Z轴,再绕Y轴,最后绕X轴。这个顺序在姿态控制里很常见。
核心公式:从坐标系A到坐标系B的转换:
vB = RA→B · vA
其中RA→B是坐标转换矩阵。
举个例子。假设我们要把太阳翼坐标系下的一个向量转到本体坐标系。如果太阳翼绕Y轴转了30度,那么转换矩阵就是Ry(30°)。
这里有个容易搞混的地方:主动旋转 vs 被动旋转。主动旋转是向量不动,坐标系转;被动旋转是坐标系不动,向量转。在GNC里,我们通常用被动旋转。说白了,就是同一个向量在不同坐标系下的表示。
避坑指南:我曾经在代码里把主动旋转和被动旋转搞混了。结果太阳翼指向计算出来总是差一个负号。查了整整一天,最后发现是旋转矩阵的符号取反了。记住:被动旋转的矩阵是主动旋转矩阵的转置。
1.5 知识体系总览
为了让你更直观地理解这三个坐标系的关系,我画了一张图:
这张图展示了三个坐标系之间的转换关系。从ECI到本体,靠的是姿态确定算法(比如星敏感器+陀螺)。从本体到太阳翼,靠的是太阳翼驱动机构的转角。两个转换矩阵相乘,就得到了从ECI直接到太阳翼的转换矩阵。
1.6 工程实现要点
在实际代码里,我建议你这样组织:
// 定义坐标系转换结构体
typedef struct {
float R_ECI2Body[3][3]; // ECI到本体转换矩阵
float R_Body2Solar[3][3]; // 本体到太阳翼转换矩阵
float R_ECI2Solar[3][3]; // ECI到太阳翼转换矩阵(复合)
} CoordTransform;
// 计算复合矩阵
void ComputeCoordTransform(CoordTransform *ct) {
// R_ECI2Solar = R_Body2Solar * R_ECI2Body
MatMul3x3(ct->R_Body2Solar, ct->R_ECI2Body, ct->R_ECI2Solar);
}
这里有个细节:矩阵乘法的顺序。我见过不少新手把顺序搞反。记住:先发生的变换放在右边。ECI到本体先发生,所以R_ECI2Body在右边。
调试技巧:在测试坐标转换时,我习惯用单位向量做验证。比如把ECI下的Z轴单位向量[0,0,1]转过去,看看在本体系下是不是指向天底。如果结果不对,那肯定是矩阵有问题。
好了,这一章的内容就到这里。坐标系是GNC的基石,你把它搞透了,后面的姿态控制、太阳翼指向计算都会顺风顺水。下一章我们讲姿态表示方法——四元数、欧拉角、方向余弦矩阵,这些都是实际工程里天天用的东西。
公众号:蓝海资料掘金营,微信deep3321