TLE为轨道两行数,简单的说是用两行数字表示轨道的相关信息,本文即用轨道两行数来计算任一时刻卫星的位置信息和速度信息,并生成CZML文件能够读取的格式

1、satellite.js库简介

简而言之,satellite.js库可以根据TLE轨道两行数,使用SGP4/SDP4方法对任一时刻卫星的位置信息速度信息进行计算,也可以完成地惯坐标系和地固坐标系下位置信息的转换等其他功能,本篇文章主要使用到satellite.js库的轨道计算功能,感兴趣的读者可以看一下这个库中其他的功能,链接放在下面
satellite.js库介绍
中文翻译
举例:

// 示例TLE轨道两行数
var tleLine1 = '1 25544U 98067A   19156.50900463  .00003075  00000-0  59442-4 0  9992',tleLine2 = '2 25544  51.6433  59.2583 0008217  16.4489 347.6017 15.51174618173442';    // 初始化卫星记录
var satrec = satellite.twoline2satrec(tleLine1, tleLine2);//  获取卫星在某一时间点的位置与方向信息 **(注意时间是从TLE记录的初始时刻后的分钟数,可以为负)**
var positionAndVelocity = satellite.sgp4(satrec, timeSinceTleEpochMinutes);//  或者使用JavaScript日期
var positionAndVelocity = satellite.propagate(satrec, new Date());// 获得地惯坐标系下的当前时间点的位置信息和速度信息
var positionEci = positionAndVelocity.position,velocityEci = positionAndVelocity.velocity;// 将观察者(固定区域)设为西经122.03度,北纬36.96度(degreesToRadians——角度转弧度)
var observerGd = {longitude: satellite.degreesToRadians(-122.0308),latitude: satellite.degreesToRadians(36.9613422),height: 0.370
};// 将GMT中国时、Julindate时转成格林尼治恒星时
var gmst = satellite.gstime(new Date());// 地惯坐标系下的位置信息转换成地固坐标系下的位置信息
var positionEcf   = satellite.eciToEcf(positionEci, gmst),
// 大地坐标系转地固坐标系observerEcf   = satellite.geodeticToEcf(observerGd),
//  地惯坐标系转大地坐标系positionGd    = satellite.eciToGeodetic(positionEci, gmst),
//  获得观测角度lookAngles    = satellite.ecfToLookAngles(observerGd, positionEcf),
// 获得笛卡尔坐标中的x,y,z
var satelliteX = positionEci.x,satelliteY = positionEci.y,satelliteZ = positionEci.z;// 角度可以通过' azimuth ', ' elevation ', ' range_sat '属性访问。
var azimuth   = lookAngles.azimuth,elevation = lookAngles.elevation,rangeSat  = lookAngles.rangeSat;// 通过'经度','纬度','高度'访问大地坐标。
var longitude = positionGd.longitude,latitude  = positionGd.latitude,height    = positionGd.height;//  将弧度转换为度。
var longitudeDeg = satellite.degreesLong(longitude),latitudeDeg  = satellite.degreesLat(latitude);

2、生成CZML能够识别的格式

使用CZML文件表示卫星,不仅需要知道卫星的位置信息,还需要知道卫星在运行过程中每一圈轨道的运行时间,这样画出来的轨道才能够是一圈一圈独立的

不然会出现轨道交叉的现象

其实根本在于要控制好卫星轨迹提前出现的时间,以及轨迹保留的时间,也即leadIntervalArray和trailIntervalArray这两个参数,具体的代码如下:

const satellite = require('satellite.js')
const moment = require('moment')
const julian = require('julian')/*
根据卫星显示的起始时间,终止时间,tle轨道两行数得出czml文件,时间为js的Date对象,tles为对象数组,对象格式为
{
name:xx,
tle1:xx,
tle2:xx
}
*/
function tles2czml(startTime, endTime, tles) {// 计算起始时间和终止时间相隔的分钟数let minsInDuration = (endTime.getTime() - startTime.getTime()) / 60000;   //mins//设置为开始时间let initialTime = moment(startTime.toISOString()).toISOString();//设置为结束时间endTime = moment(endTime.toISOString()).toISOString(); // 初始化czml数据,创建场景信息let tempCZML = [];tempCZML.push({"id": "document","name": "CZML Point - Time Dynamic","version": "1.0","clock": {"interval": `${initialTime}/${endTime}`,"multiplier": 1,"range": "LOOP_STOP","step": "SYSTEM_CLOCK"}},)// 处理每一个satfor (let no = 0; no < tles.length; no++) {if(!tles[no].name){console.log("请输入第" + no+1 + "个卫星的名称");return};if(!tles[no].tle1){console.log("请输入第" + no+1 + "个卫星的第一个两行数");return};if(!tles[no].tle2){console.log("请输入第" + no+1 + "个卫星的第二个两行数");return};let sat_name = tles[no].name;// 保存位置信息let res = []; let satrec satrec = satellite.twoline2satrec(tles[no].tle1, tles[no].tle2);//satrec.no:以弧度/分钟为单位的平均运动,一天有1440分钟,一弧度是0.159155圈// to go from RAD/DAY -> REV/DAY: rad * 1440 * 0.159155//to go from REV/PER DAY to MINS/REV -> 1440/RevPerDaylet totalIntervalsInDay = satrec.no * 1440 * 0.159155; //1440 = min && 0.159155 = 1turn// 获得运行一圈的分钟数let minsPerInterval = 1440 / totalIntervalsInDay; // mins for 1 revolution around earth// intervalTime 取结束时间 格式为2008-09-20T12:25:40.104Zlet intervalTime = endTimelet leadIntervalArray = [];let trailIntervalArray = [];console.log("Setting intervals...");// 注意:这里之所以要倒过来求leadInterval和trailInterval是因为如果正着求,很有可能在终止时刻卫星并没有运行完一圈,导致轨道只显示一半for (let i = minsInDuration; i >= 0; i -= minsPerInterval) {if (i <= minsPerInterval) { // intial interval let currentOrbitalInterval = {"interval": `${initialTime}/${intervalTime}`,"epoch": `${initialTime}`,"number": [0, minsPerInterval * 60,minsPerInterval * 60, 0]}let currTrail = {"interval": `${initialTime}/${intervalTime}`,"epoch": `${initialTime}`,"number": [0, 0,minsPerInterval * 60, minsPerInterval * 60]}leadIntervalArray.push(currentOrbitalInterval);trailIntervalArray.push(currTrail);}else {    //not initial so make intervals let previousIntervalTime = moment(intervalTime).add(-minsPerInterval, 'm').toISOString();let currentOrbitalInterval = {"interval": `${previousIntervalTime}/${intervalTime}`,"epoch": `${previousIntervalTime}`,"number": [0, minsPerInterval * 60,minsPerInterval * 60, 0]}let currTrail = {"interval": `${previousIntervalTime}/${intervalTime}`,"epoch": `${previousIntervalTime}`,"number": [0, 0,minsPerInterval * 60, minsPerInterval * 60]}intervalTime = moment(intervalTime).add(-minsPerInterval, 'm').toISOString();leadIntervalArray.push(currentOrbitalInterval);trailIntervalArray.push(currTrail);}}// Seconds between current time and epoch timelet sec = (startTime - julian.toDate(satrec.jdsatepoch)) / 1000;console.log(startTime, julian.toDate(satrec.jdsatepoch), sec);for (let i = sec; i <= sec + minsInDuration * 60; i++) { //每60秒计算一个位置信息,最后采用拉格朗日插值法处理数据// 根据当前时间距tle两行数历元时刻的分钟数,计算当前卫星位置和速度let positionAndVelocity = satellite.sgp4(satrec, i * 0.0166667); // 0.0166667min = 1sec// 地惯坐标系let positionEci = positionAndVelocity.position;positionEci.x = positionEci.x * 1000;positionEci.y = positionEci.y * 1000;positionEci.z = positionEci.z * 1000;// let velocityEci = positionAndVelocity.velocity;// velocityEci.x = velocityEci.x * 1000;// velocityEci.y = velocityEci.y * 1000;// velocityEci.z = velocityEci.z * 1000;res.push(i - sec, positionEci.x, positionEci.y, positionEci.z);}let initialCZMLProps ={"id": `${sat_name}`,"name": `${sat_name}`,"availability": `${initialTime}/${endTime}`,"label": {"fillColor": {"rgba": [255, 0, 255, 255]},"font": "11pt Lucida Console","horizontalOrigin": "LEFT","outlineColor": {"rgba": [0, 0, 0, 255]},"outlineWidth": 2,"pixelOffset": {"cartesian2": [12, 0]},"show": true,"style": "FILL_AND_OUTLINE","text": `${sat_name}`,"verticalOrigin": "CENTER"},"path": {"show": [{"interval": `${initialTime}/${endTime}`,"boolean": true}],"width": 3,"material": {"solidColor": {"color": {"rgba": [// 随机生成轨道颜色Math.floor(255 * Math.random(0, 1)), Math.floor(255 * Math.random(0, 1)), Math.floor(255 * Math.random(0, 1)), 255]}}},"resolution": 120,// The time ahead of the animation time, in seconds, to show the path."leadTime": leadIntervalArray,// The time behind the animation time, in seconds, to show the"trailTime": trailIntervalArray},"model": {"show": true,"gltf": "./111.gltf","minimumPixelSize": 50,},"position": {// 采用拉格朗日插值法"interpolationAlgorithm": "LAGRANGE",// 1为线性插值,2为平方插值"interpolationDegree": 2,// 参考坐标系,地惯坐标系"referenceFrame": "INERTIAL","epoch": `${initialTime}`,"cartesian": res}}tempCZML.push(initialCZMLProps);}return tempCZML;
}
export default tles2czml

上面的方法参考了tle2czml库的写法,但是有一点需要注意,如果直接调用tle2czml库的话,最后一圈的卫星轨道往往是不完整的,本文所写的方法是根据时间倒序求leadInterval和trailInterval,这样即便到了终止时间,卫星的轨道显示也是完整的一圈。
如果对CZML文件格式有疑问的可以看 这里
欢迎交流~

【Cesium】使用TLE轨道两行数计算轨道信息,并生成CZML格式文件相关推荐

  1. TLE两行数与轨道六根数转换

    TLE与轨道六根数转换方法 一.TLE格式讲解 二.轨道六根数 三.TLE与六根数转换 1."每天环绕地球的圈数"与"轨道半长轴"转换 2.平近点角与真近点角的 ...

  2. 【Bug修复】yuv生成mp4格式文件帧数(时间)与原视频不一致

    问题描述 需要将一系列的视频从yuv格式的文件编码成每秒30帧的视频,但是在yuv生成mp4格式时,存在帧数不对齐的问题. 1.准备两个视频 Animation_1080P-209f.mkv,25fp ...

  3. 【C语言】时间操作,把1970年开始秒数计算的时间,转换为字符串格式输出

    struct tm *ptr; time_t lt; unsigned int times = <秒数时间变量>; char str[80]; lt = times; ptr = loca ...

  4. 卫星轨道推演计算相关知识点总结(含欧拉角、旋转矩阵、及各坐标系转化等)

    来源:轨道机动算法的C++实现_shirro123的专栏-CSDN博客 卫星轨道推演计算相关基础知识点总结 一.卫星的运动特性             二.卫星的空间坐标系               ...

  5. 轨道六根数 matlab,轨道六根数

    在二体问题中,轨道根数(orbital factors)是描述物体运动轨迹的简便形式.三维空间中,唯一确定物体轨迹需要六个参数,如位置矢量和速度矢量(均为三维)可共同确定物体轨迹.此外,用六个轨道根数 ...

  6. 【运筹学】线性规划 人工变量法 ( 人工变量法案例 | 第三次迭代 | 中心元变换 | 检验数计算 | 最优解判定 )

    文章目录 一.第三次迭代 : 中心元变换 二.第三次迭代 : 单纯形表 三.第三次迭代 : 检验数计算 四.第三次迭代 : 最优解判定 五.第三次迭代 : 最终单纯形表 上一篇博客 [运筹学]线性规划 ...

  7. 【运筹学】线性规划 人工变量法 ( 人工变量法案例 | 第二次迭代 | 中心元变换 | 检验数计算 | 最优解判定 | 选择入基变量 | 选择出基变量 )

    文章目录 一.第二次迭代 : 中心元变换 二.第二次迭代 : 单纯形表 三.第二次迭代 : 计算检验数 四.第二次迭代 : 最优解判定 五.第二次迭代 : 选择入基变量 六.第二次迭代 : 选择出基变 ...

  8. 【运筹学】线性规划 人工变量法 ( 人工变量法案例 | 第一次迭代 | 中心元变换 | 检验数计算 | 选择入基变量 | 选择出基变量 )

    文章目录 一.第一次迭代 : 中心元变换 二.第一次迭代 : 单纯形表 三.第一次迭代 : 计算检验数 四.第一次迭代 : 最优解判定 五.第一次迭代 : 选择入基变量 六.第一次迭代 : 选择出基变 ...

  9. 【运筹学】线性规划 单纯形法 案例二 ( 第一次迭代 | 矩阵变换 | 检验数计算 | 最优解判定 | 入基变量 | 出基变量 )

    文章目录 一.第一次迭代 : 进行行变换 二.第一次迭代 : 计算检验数 三.第一次迭代 : 最优解判定 四.第一次迭代 : 入基变量 五.第一次迭代 : 出基变量 [运筹学]线性规划 单纯形法 ( ...

最新文章

  1. Tensorflow多线程输入数据处理框架(一)——队列与多线程
  2. Oracle 执行计划
  3. No.6 建立swap分区、进程、安装软件包的方法(rpm,yum,编译)
  4. 永劫无间为啥显示连接服务器失败,永劫无间服务器故障怎么办?永劫无间服务器故障解决办法...
  5. 万里挑一!北大AI女神每天必看的几个优质公众号
  6. linux内核更新 2.6.38,Linux内核 2.6.38版本预计到四月初完成
  7. 统计学习方法-李航(3)
  8. ajax页面无刷新分页,JS+Ajax+Jquery实现页面无刷新分页以及分组 超强的实现
  9. 数学建模常用算法—模糊综合评价法(FCE)
  10. 触发器的三种触发方式:电平触发、边沿触发、脉冲触发区别
  11. java实现微信公众号官方支付功能
  12. 计算机图形学(六)-光栅化、采样、走样与反走样、滤波与卷积
  13. c语言200-500完数,C语言求完数(完全数)(详解版)
  14. 计算机技术cae是什么意思,什么是CAE?有那些用途?请赐教 爱问知识人
  15. 【狂神说Java】JavaWeb入门到实战(学习笔记)
  16. nose中的一段代码...
  17. 简单的图书馆借/还系统——C++实现
  18. VMware虚拟机解决空间不足,增加磁盘空间(磁盘扩容)
  19. 公司网站制作需要多少钱?
  20. python语言控制nao行走

热门文章

  1. mysql最新版百度云下载[免费]
  2. 前端请柬框架_mpvue+小程序云开发,纯前端实现婚礼邀请函(相册小程序)
  3. 一、Glade-3安装配置
  4. 一个数的因子、因数的区别
  5. 全桥DCDC输出电压和变比占空比的关系
  6. 全国计算机二级office考试选择题知识汇总
  7. 互联网快讯:华为正式上架“花瓣翻译官”APP;极米H3S高清巨幕获用户青睐;网易云音乐即将挂牌上市
  8. 文献管理软件//Zotero的常用插件——Zotero translators//知网下载//知乎翻译器+Jasminum(茉莉花)(四)
  9. 总结--红蓝对抗中的蓝队。
  10. 我是科学家系列科普 | 今天直播 - 刘春明:两粒大米的故事