feat: 优化卫星实体类,更新 TLE 处理逻辑并增强类型定义
This commit is contained in:
@ -1,20 +1,20 @@
|
||||
import type { Cartesian3 } from 'cesium';
|
||||
|
||||
import * as Cesium from 'cesium';
|
||||
import { propagate, twoline2satrec } from 'satellite.js';
|
||||
import { propagate, type SatRec, twoline2satrec } from 'satellite.js';
|
||||
|
||||
class SatelliteEntity {
|
||||
private leadTime!: number;
|
||||
private name!: string;
|
||||
private satrec: any;
|
||||
private satrec: SatRec;
|
||||
private stepSeconds!: number;
|
||||
private tleLine1!: string;
|
||||
private tleLine2!: string;
|
||||
private totalSeconds!: number;
|
||||
private trailTime!: number;
|
||||
|
||||
constructor(tle = '' /* , options = {} */) {
|
||||
const [name, tleLine1, tleLine2] = this._checkTle(tle);
|
||||
constructor(tle2LineStr = '' /* , options = {} */) {
|
||||
const [name, tleLine1, tleLine2] = this._checkTle(tle2LineStr);
|
||||
const circle = Number(tleLine2.slice(52, 64));
|
||||
|
||||
this.name = name.trim();
|
||||
@ -28,8 +28,8 @@ class SatelliteEntity {
|
||||
this.trailTime = 0;
|
||||
}
|
||||
|
||||
_checkTle(tle: string) {
|
||||
const elements = tle.split('\n');
|
||||
_checkTle(tle2LineStr: string) {
|
||||
const elements = tle2LineStr.split('\n');
|
||||
if (elements.length !== 3) throw new Error('tle data error');
|
||||
return elements as [string, string, string];
|
||||
}
|
||||
|
@ -1,8 +1,123 @@
|
||||
// eslint-disable no-unused-vars
|
||||
/* eslint-disable perfectionist/sort-objects */
|
||||
|
||||
import { twoline2satrec } from 'satellite.js';
|
||||
|
||||
// https://en.wikipedia.org/wiki/Two-line_element_set#Format
|
||||
|
||||
// https://celestrak.org/NORAD/elements/gp.php?GROUP=last-30-days&FORMAT=tle
|
||||
|
||||
const longstr1 = `1 63157U 25045A 25069.35219743 .00000545 -65692-6 00000+0 0 9992`;
|
||||
const longstr2 = `2 63157 19.0062 64.6364 7327661 179.7218 141.4162 2.26206155 28`;
|
||||
|
||||
export const TLE_LIST = [
|
||||
/* `ISS (ZARYA)
|
||||
1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927
|
||||
2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537`, */
|
||||
`2025-045A
|
||||
1 63157U 25045A 25069.35219743 .00000545 -65692-6 00000+0 0 9992
|
||||
2 63157 19.0062 64.6364 7327661 179.7218 141.4162 2.26206155 28`,
|
||||
${longstr1}
|
||||
${longstr2}`,
|
||||
`STARLINK-11371 [DTC]
|
||||
1 62879U 25024A 25062.93300820 .00003305 00000+0 21841-4 0 9995
|
||||
2 62879 42.9977 257.3937 0001725 269.2925 90.7748 15.77864921 5143`,
|
||||
];
|
||||
|
||||
// https://celestrak.org/NORAD/elements/gp.php?GROUP=last-30-days&FORMAT=json
|
||||
export const TLE_LIST_JSON = [
|
||||
{
|
||||
OBJECT_NAME: '2025-045A',
|
||||
OBJECT_ID: '2025-045A',
|
||||
EPOCH: '2025-03-10T08:27:09.857952',
|
||||
MEAN_MOTION: 2.26206155, // 平均运动(Mean Motion),单位是圈/天,表示卫星每天绕地球运行的圈数,此处约为 2.26 圈(周期约 10.6 小时)。
|
||||
ECCENTRICITY: 0.7327661, // 偏心率(Eccentricity),无单位,科学记数法为 0.7327661,表示轨道是一个高度椭圆的形状(接近 1 表示非常扁平)。
|
||||
INCLINATION: 19.0062, // 轨道倾角(Inclination),单位是度,表示轨道平面与地球赤道的夹角。此处为 19.0062°,属于低倾角轨道。
|
||||
RA_OF_ASC_NODE: 64.6364, // 升交点赤经(RAAN, Right Ascension of Ascending Node),单位是度,表示轨道平面在赤道上的交叉点位置。
|
||||
ARG_OF_PERICENTER: 179.7218, // 近地点角距(Argument of Perigee),单位是度,表示近地点相对于升交点的角度。
|
||||
MEAN_ANOMALY: 141.4162, // 平近点角(Mean Anomaly),单位是度,表示卫星在轨道上的位置。
|
||||
EPHEMERIS_TYPE: 0, // 轨道模型类型(通常为 0,表示 SGP4 模型)。
|
||||
CLASSIFICATION_TYPE: 'U', // U 表示未分类(可能是临时编号)。
|
||||
NORAD_CAT_ID: 63157, // NORAD
|
||||
ELEMENT_SET_NO: 999, // 校验码或元素集编号,表示这是第 999 次更新的 TLE 数据。
|
||||
REV_AT_EPOCH: 2, // Checksum 校验和
|
||||
BSTAR: 0, // 轨道模型类型(0=SGP4模型)。
|
||||
MEAN_MOTION_DOT: 5.45e-6, // 0.00000545 // 平均运动的一阶导数(每天的轨道变化率),单位是圈/天²,这里非常小,表示轨道衰减缓慢。
|
||||
MEAN_MOTION_DDOT: -6.5692e-7, // 平均运动的二阶导数(科学记数法:-6.5692 × 10⁻⁶),表示轨道受摄动(如大气阻力)的加速度变化。
|
||||
},
|
||||
];
|
||||
|
||||
// 为了twoline2satrec函数需要哪些参数
|
||||
// https://github.com/shashwatak/satellite-js/blob/0e921026d20b75f42553366994af70eed63a304f/src/io.js#L62
|
||||
function twoline2satrecFake(longstr1: string, longstr2: string) {
|
||||
console.group('twoline2satrec');
|
||||
const satrec = {} as Record<string, any>;
|
||||
satrec.error = 0;
|
||||
|
||||
satrec.satnum = longstr1.substring(2, 7);
|
||||
console.debug(`longstr1.substring(2, 7) :>> `, `"${longstr1.substring(2, 7)}"`);
|
||||
|
||||
satrec.epochyr = parseInt(longstr1.substring(18, 20), 10);
|
||||
console.debug(`longstr1.substring(18, 20) :>> `, `"${longstr1.substring(18, 20)}"`);
|
||||
|
||||
satrec.epochdays = parseFloat(longstr1.substring(20, 32));
|
||||
console.debug(`longstr1.substring(20, 32) :>> `, `"${longstr1.substring(20, 32)}"`);
|
||||
|
||||
satrec.ndot = parseFloat(longstr1.substring(33, 43));
|
||||
console.debug(`longstr1.substring(33, 43) :>> `, `"${longstr1.substring(33, 43)}"`);
|
||||
|
||||
satrec.nddot = parseFloat(`.${parseInt(longstr1.substring(44, 50), 10)}E${longstr1.substring(50, 52)}`);
|
||||
console.debug(`longstr1.substring(44, 50) :>> `, `"${longstr1.substring(44, 50)}"`);
|
||||
console.debug(`longstr1.substring(50, 52) :>> `, `"${longstr1.substring(50, 52)}"`);
|
||||
|
||||
satrec.bstar = parseFloat(
|
||||
`${longstr1.substring(53, 54)}.${parseInt(longstr1.substring(54, 59), 10)}E${longstr1.substring(59, 61)}`,
|
||||
);
|
||||
console.debug(`longstr1.substring(53, 54) :>> `, `"${longstr1.substring(53, 54)}"`);
|
||||
console.debug(`longstr1.substring(54, 59) :>> `, `"${longstr1.substring(54, 59)}"`);
|
||||
console.debug(`longstr1.substring(59, 61) :>> `, `"${longstr1.substring(59, 61)}"`);
|
||||
|
||||
// satrec.satnum = longstr2.substring(2, 7);
|
||||
satrec.inclo = parseFloat(longstr2.substring(8, 16));
|
||||
console.debug(`longstr2.substring(8, 16) :>> `, `"${longstr2.substring(8, 16)}"`);
|
||||
|
||||
satrec.nodeo = parseFloat(longstr2.substring(17, 25));
|
||||
console.debug(`longstr2.substring(17, 25) :>> `, `"${longstr2.substring(17, 25)}"`);
|
||||
|
||||
satrec.ecco = parseFloat(`.${longstr2.substring(26, 33)}`);
|
||||
console.debug(`longstr2.substring(26, 33) :>> `, `"${longstr2.substring(26, 33)}"`);
|
||||
satrec.argpo = parseFloat(longstr2.substring(34, 42));
|
||||
console.debug(`longstr2.substring(34, 42) :>> `, `"${longstr2.substring(34, 42)}"`);
|
||||
satrec.mo = parseFloat(longstr2.substring(43, 51));
|
||||
console.debug(`longstr2.substring(43, 51) :>> `, `"${longstr2.substring(43, 51)}"`);
|
||||
satrec.no = parseFloat(longstr2.substring(52, 63));
|
||||
console.debug(`longstr2.substring(52, 63) :>> `, `"${longstr2.substring(52, 63)}"`);
|
||||
|
||||
console.groupEnd();
|
||||
return satrec;
|
||||
}
|
||||
|
||||
// console.debug(`twoline2satrecFake(longstr1, longstr2) :>> `, twoline2satrecFake(longstr1, longstr2));
|
||||
const satrec1 = twoline2satrec(longstr1, longstr2);
|
||||
const satrec2 = twoline2satrec(
|
||||
`1 63157 25069.35219743 .00000545 -65692-6 00000+0 `,
|
||||
`2 19.0062 64.6364 7327661 179.7218 141.4162 2.26206155 `,
|
||||
);
|
||||
const satrec1_str = JSON.stringify(satrec1, null, 2);
|
||||
const satrec2_str = JSON.stringify(satrec2, null, 2);
|
||||
if ($__DEV__) console.debug(`satrec1_str === satrec2_str :>> `, satrec1_str === satrec2_str);
|
||||
|
||||
// longstr1.substring(2, 7) :>> "63157"
|
||||
// longstr1.substring(18, 20) :>> "25"
|
||||
// longstr1.substring(20, 32) :>> "069.35219743"
|
||||
// longstr1.substring(33, 43) :>> " .00000545"
|
||||
// longstr1.substring(44, 50) :>> "-65692"
|
||||
// longstr1.substring(50, 52) :>> "-6"
|
||||
// longstr1.substring(53, 54) :>> " "
|
||||
// longstr1.substring(54, 59) :>> "00000"
|
||||
// longstr1.substring(59, 61) :>> "+0"
|
||||
//
|
||||
// longstr2.substring(8, 16) :>> " 19.0062"
|
||||
// longstr2.substring(17, 25) :>> " 64.6364"
|
||||
// longstr2.substring(26, 33) :>> "7327661"
|
||||
// longstr2.substring(34, 42) :>> "179.7218"
|
||||
// longstr2.substring(43, 51) :>> "141.4162"
|
||||
// longstr2.substring(52, 63) :>> " 2.26206155"
|
||||
|
Reference in New Issue
Block a user