AstSPICE模块
2026/4/9大约 5 分钟
AstSPICE模块
说明:本文档旨在帮助理解模块功能,具体API和行为请查阅源代码。
模块概述
AstSPICE模块提供了与NASA SPICE(Spacecraft Planet Instrument C-matrix Events)工具包接口兼容的函数封装。SPICE是航天任务中广泛使用的工具包,用于计算星历、坐标系变换、行星状态等航天动力学相关参数。AstSPICE模块将这些功能以现代C++风格封装,便于在C++项目中集成使用。
核心概念
SPICE简介
SPICE是由NASA导航和天文信息服务部门(NAIF)开发的工具包,主要包含以下几类数据文件(Kernel):
- SPK (Spacecraft Planet Kernel):星历数据,记录天体位置和速度
- PCK (Planetary Constants Kernel):行星常数,如引力参数、自转参数等
- FK (Frame Kernel):坐标系定义
- CK (C-matrix Kernel):姿态数据
- IK (Instrument Kernel):仪器参数
- LSK (Leapseconds Kernel):闰秒数据
常用参考系
AstSPICE支持多种标准参考系:
- J2000:儒略日2000年1月1日12:00 TT的惯性参考系
- ICRF:国际天球参考系,是J2000的现代实现
- ECLIPJ2000:黄道J2000惯性系
- EM:地月系质心惯性系
- IAU_EARTH:国际天文学联合会定义的地球固连系
时间系统
- ET (Ephemeris Time):星历时间,动力学时
- UTC (Coordinated Universal Time):协调世界时
- TT (Terrestrial Time):地球时
主要功能
1. 坐标变换
1.1 旋转矩阵变换 - pxform
计算两个参考系之间的旋转矩阵:
errc_t pxform(
StringView from, // 源参考系名称
StringView to, // 目标参考系名称
const TimePoint& et, // 时间点
Matrix3d& rotate // 输出旋转矩阵
);1.2 旋转轴与角度 - axisar
根据旋转轴和角度计算旋转矩阵:
void axisar(
const Vector3d& axis, // 旋转轴
double angle, // 旋转角度(弧度)
Matrix3d& r // 输出旋转矩阵
);2. 坐标系转换
2.1 球坐标/直角坐标转换
| 函数 | 功能 |
|---|---|
| latrec | 球坐标(半径、经度、纬度)转直角坐标 |
| radrec | 距离-赤经-赤纬转直角坐标 |
| azlrec | 距离-方位角-俯仰角转直角坐标 |
2.2 矩阵/欧拉角/四元数转换
| 函数 | 功能 |
|---|---|
| eul2m | 欧拉角转旋转矩阵 |
| m2eul | 旋转矩阵转欧拉角 |
| m2q | 旋转矩阵转四元数 |
| q2m | 四元数转旋转矩阵 |
3. 星历计算
3.1 天体位置计算 - spkpos
计算目标天体相对于观测者的位置:
errc_t spkpos(
CelestialBody* targ, // 目标天体
const TimePoint& et, // 时间点
Axes* ref, // 参考轴系
StringView abcorr, // 像差校正选项
CelestialBody* obs, // 观测者
Vector3d& ptarg, // 输出位置
double* lt = nullptr // 光行时(可选)
);像差校正选项(abcorr):
- "NONE":无校正
- "LT":光行时校正
- "LT+S":光行时+恒星像差校正
- "CN":天文台网校正
- "CN+S":天文台网+恒星像差校正
- "XLT": 光行时校正(高精度,X表示高精度模式)
- "XLT+S": 光行时+恒星像差校正(高精度)
- "XCN": 天文台网校正(高精度)
- "XCN+S": 天文台网+恒星像差校正(高精度)
3.2 天体位置速度计算 - spkgeo
计算天体位置和速度:
void spkgeo(
CelestialBody* targ, // 目标天体
const TimePoint& et, // 时间点
Axes* ref, // 参考轴系
CelestialBody* obs, // 观测者
CartState& state, // 输出位置速度状态
double* lt = nullptr // 光行时(可选)
);3.3 太阳系质心状态 - spkssb
errc_t spkssb(
CelestialBody* targ, // 目标天体
const TimePoint& et, // 时间点
Axes* ref, // 参考轴系
CartState& starg // 输出状态
);4. 姿态计算
4.1 恒星位置计算 - stelab
计算恒星表观位置(考虑光行差和视差):
errc_t stelab(
const Vector3d& pobj, // 恒星位置向量
const Vector3d& vobs, // 观测者速度
Vector3d& appobj // 输出表观位置
);5. 矩阵运算
5.1 矩阵乘法 - mxm
void mxm(
const Matrix3d& m1, // 矩阵1
const Matrix3d& m2, // 矩阵2
Matrix3d& mout // 输出矩阵
);5.2 向量旋转 - vrotv
绕指定轴旋转向量:
void vrotv(
const Vector3d& v, // 输入向量
const Vector3d& axis, // 旋转轴
double theta, // 旋转角度(弧度)
Vector3d& r // 输出向量
);6. 时间转换
6.1 UTC转ET - utc2et
errc_t utc2et(
StringView utcstr, // UTC时间字符串
double& et // 输出星历时间
);7. 旋转矩阵转状态变换 - rav2xf
void rav2xf(
const Matrix3d& rot, // 旋转矩阵
const Vector3d& av, // 角速度向量
Matrix6d& xform // 输出6x6状态变换矩阵
);8. 运行时查询
8.1 天体查询
CelestialBody* aSpiceFindBody(StringView name); // 按名称查找
CelestialBody* aSpiceFindBody(int id); // 按ID查找8.2 参考系查询
Axes* aSpiceFindAxes(StringView name); // 按名称查找参考系常量与历元
| 函数 | 值/说明 | 说明 |
|---|---|---|
clight() | ~299792458.0 m/s | 光速 (真空) |
j2000() | 2451545.0 | J2000儒略日 |
j1900() | 2415020.31352 | J1900儒略日 |
j1950() | 2433282.4235 | J1950儒略日 |
b1900() | 2415020.31352 | B1900贝塞尔日 |
b1950() | 2433282.4235 | B1950贝塞尔日 |
dpr() | ~57.295779513 | 弧度转角度因子 |
jyear() | 31557600.0 | 儒略年秒数 |
文件结构
src/AstSPICE/
README.md # 模块说明
SpiceUsr.h # C接口声明
SpiceUsr.hpp # C++接口声明
SpiceZpr.h # C SPICE函数实现声明
SpiceZpr.hpp # C++ SPICE函数实现
SpiceZpr.cpp # SPICE函数实现
xmake.lua # 构建配置
RunTime/
SpiceRunTime.hpp # 运行时查询接口
SpiceRunTime.cpp
SpiceBodyRegistry.hpp # 天体注册表
SpiceBodyRegistry.cpp
SpiceFrameRegistry.hpp # 参考系注册表
SpiceFrameRegistry.cpp依赖关系
- AstGlobal.h:项目全局定义和宏
- AstCore/Time.hpp:时间系统定义
- AstCore/Axes.hpp:轴系定义
- AstCore/Matrix.hpp:矩阵运算
- AstCore/Quaternion.hpp:四元数定义
- AstCore/CelestialBody.hpp:天体定义
- AstCore/CartState.hpp:笛卡尔状态定义
使用示例
示例1:旋转轴与角度 - axisar
使用axisar函数根据旋转轴和角度计算旋转矩阵:
#include "AstSPICE/SpiceZpr.hpp"
#include "AstMath/Vector.hpp"
#include "AstMath/Matrix.hpp"
#include "AstUtil/Constants.h"
#include <cmath>
#include <cstdio>
AST_USING_NAMESPACE
int main()
{
// 绕Z轴旋转45度
Vector3d axis = {0, 0, 1};
double angle = kPI / 4; // 45度
Matrix3d rotation;
axisar(axis, angle, rotation);
printf("axisar旋转矩阵示例:\n");
printf("旋转轴: (%.1f, %.1f, %.1f), 角度: %.2f rad\n", axis[0], axis[1], axis[2], angle);
printf("旋转矩阵:\n");
for (int i = 0; i < 3; i++) {
printf(" [%.6f %.6f %.6f]\n", rotation(i,0), rotation(i,1), rotation(i,2));
}
return 0;
}示例2:坐标转换 - latrec/radrec
球坐标(半径、经度、纬度)和直角坐标的相互转换:
#include "AstSPICE/SpiceZpr.hpp"
#include "AstMath/Vector.hpp"
#include "AstMath/Matrix.hpp"
#include "AstUtil/Constants.h"
#include <cmath>
#include <cstdio>
AST_USING_NAMESPACE
int main()
{
// 示例:球坐标转直角坐标
// 地球平均半径约6371km
double radius = 6371000.0; // 米
double lon = kPI / 4; // 45度经度
double lat = 0.0; // 赤道
Vector3d rectan;
latrec(radius, lon, lat, rectan);
printf("球坐标 (r=%.0f m, lon=%.2f rad, lat=%.2f rad)\n", radius, lon, lat);
printf("直角坐标: X=%.2f, Y=%.2f, Z=%.2f\n", rectan[0], rectan[1], rectan[2]);
return 0;
}示例3:矩阵/欧拉角/四元数转换
欧拉角、旋转矩阵和四元数之间的相互转换:
#include "AstSPICE/SpiceZpr.hpp"
#include "AstUtil/Constants.h"
#include "AstMath/Matrix.hpp"
#include "AstMath/Quaternion.hpp"
#include <cmath>
#include <cstdio>
AST_USING_NAMESPACE
int main()
{
// 示例:欧拉角转旋转矩阵
double angle1 = kPI / 6; // 30度
double angle2 = kPI / 4; // 45度
double angle3 = kPI / 3; // 60度
Matrix3d rotation;
eul2m(angle3, angle2, angle1, 3, 2, 1, rotation);
printf("欧拉角 (3-2-1顺序): angle1=%.2f, angle2=%.2f, angle3=%.2f (弧度)\n",
angle1, angle2, angle3);
printf("旋转矩阵:\n");
for (int i = 0; i < 3; i++) {
printf(" [%8.4f %8.4f %8.4f]\n", rotation(i,0), rotation(i,1), rotation(i,2));
}
// 示例:旋转矩阵转欧拉角
double ang1_out, ang2_out, ang3_out;
m2eul(rotation, 3, 2, 1, ang1_out, ang2_out, ang3_out);
printf("\n反向欧拉角: %.6f, %.6f, %.6f (弧度)\n", ang1_out, ang2_out, ang3_out);
// 示例:旋转矩阵转四元数
Quaternion q;
m2q(rotation, q);
printf("\n四元数: w=%.4f, x=%.4f, y=%.4f, z=%.4f\n", q.w(), q.x(), q.y(), q.z());
// 示例:四元数转旋转矩阵
Matrix3d rotation2;
q2m(q, rotation2);
return 0;
}示例4:向量旋转与矩阵乘法
使用vrotv函数绕指定轴旋转向量,以及使用mxm进行矩阵乘法:
#include "AstSPICE/SpiceZpr.hpp"
#include "AstMath/Vector.hpp"
#include "AstMath/Matrix.hpp"
#include "AstUtil/Constants.h"
#include <cmath>
#include <cstdio>
AST_USING_NAMESPACE
int main()
{
// 示例:绕指定轴旋转向量
Vector3d v = {1, 0, 0}; // 初始向量沿X轴
Vector3d axis = {0, 0, 1}; // 绕Z轴旋转
double theta = kPI / 4; // 45度
Vector3d result;
vrotv(v, axis, theta, result);
printf("向量旋转示例:\n");
printf("输入向量: (%.4f, %.4f, %.4f)\n", v[0], v[1], v[2]);
printf("旋转轴: (%.4f, %.4f, %.4f)\n", axis[0], axis[1], axis[2]);
printf("旋转角度: %.2f 弧度 (%.2f 度)\n", theta, theta * 180 / kPI);
printf("结果向量: (%.4f, %.4f, %.4f)\n", result[0], result[1], result[2]);
// 示例:矩阵乘法
Matrix3d m1, m2, mout;
m1 = Matrix3d::Identity();
m1(0, 1) = 0.5;
m1(1, 0) = -0.5;
m2 = Matrix3d::Identity();
m2(0, 2) = 0.3;
m2(2, 0) = -0.3;
mxm(m1, m2, mout);
printf("\n矩阵乘法示例:\n");
printf("矩阵1:\n");
for (int i = 0; i < 3; i++) {
printf(" [%.2f %.2f %.2f]\n", m1(i,0), m1(i,1), m1(i,2));
}
printf("结果:\n");
for (int i = 0; i < 3; i++) {
printf(" [%.4f %.4f %.4f]\n", mout(i,0), mout(i,1), mout(i,2));
}
return 0;
}注意事项
- Kernel文件:使用SPICE功能前需要加载相应的Kernel文件(.bsp, .tpc, .tf等)
- 时间系统:SPICE内部使用ET(星历时间),与UTC之间需要进行转换
- 像差校正:进行高精度计算时需要考虑光行时和恒星像差校正
- 坐标系名称:参考系名称需要与加载的Frame Kernel中定义的一致
- 天体名称:天体名称需要与SPICE命名的规范一致(如"EARTH"、"SUN"等)