SpaceDSL天體動(dòng)力學(xué)仿真庫的介紹屁擅、編譯和使用說明

1. 介紹

SpaceDSL是一個(gè)天體動(dòng)力學(xué)仿真庫。它使用C++編寫秤朗,為天體動(dòng)力學(xué)愛好者提供一個(gè)開放的框架以更自由的方式實(shí)現(xiàn)天體動(dòng)力學(xué)仿真煤蹭。本項(xiàng)目基于MIT協(xié)議開放源碼,以供自由使用取视。本項(xiàng)目通過CMake構(gòu)建硝皂,可以用于WindowsLinuxMac OS作谭。SpaceDSL庫可以被編譯成靜態(tài)庫稽物、動(dòng)態(tài)庫和Python依賴庫。當(dāng)然也支持直接使用。

1.1 核心特性

SpaceDSL包含了有關(guān)天體動(dòng)力學(xué)仿真的全部基本功能,包括:

  • 天文時(shí)間系統(tǒng):支持EOP web Service舅列,包含UTC倔丈、UT1和TT等多種時(shí)間系統(tǒng)的定義和轉(zhuǎn)換
  • 參考坐標(biāo)系:包含ECI、TOD碉克、ECEF、VVLH等常用空間坐標(biāo)系的變換方程
  • JPL星歷:重新打包了JPL星歷讀取模塊,提供最新的DE436文件羊赵,包括1950至2050年間的數(shù)據(jù)
  • 地球重力模型:使用EGM2008數(shù)據(jù)(80X80)和球諧函數(shù)構(gòu)建地球的高精度重力模型
  • 其他攝動(dòng)模型:大氣阻力(NRLMSISE2000)、太陽輻射壓扇谣、第三天體重力(Third Body Gravity)
  • 雙天體軌道預(yù)測(cè)昧捷、J2軌道預(yù)測(cè)和用于航天器的高精度軌道預(yù)測(cè)
  • 多種地面目標(biāo)模型和訪問分析(Access Analysis
  • 傳感器支持(Simple ConicRectangular
  • 常用物理常量
  • 多線程并行支持:類似于Qt的API,包含線程和線程池
  • 支持基于STL的異常處理
  • 提供基于NLopt的非線性優(yōu)化庫
  • 提供基于ElectronCesium的可視化工具

1.2 后續(xù)支持的特性

  • 攝動(dòng)模型:固體潮(Earth Tide)罐寨、相對(duì)論效應(yīng)
  • 航天器的相對(duì)運(yùn)動(dòng)仿真
  • 軌道動(dòng)作仿真特性
  • 軌道偏移量預(yù)測(cè)

2. 編譯

2.1 支持的編譯器

  • Clang/LLVM 3.3 及以上版本(如果是Xcode的Clang靡挥,需要5.0.0及以上版本)
  • GCC 7.2 及以上版本
  • Microsoft Visual Studio 2015 Update 3 及以上版本
  • Intel C++ compiler 16 及以上版本

2.2 編譯過程

克隆項(xiàng)目代碼:

git clone https://github.com/Astrodynamics/SpaceDSL.git

使用CLion打開項(xiàng)目:


選擇Build All
image

注意,如果平臺(tái)是Linux系統(tǒng)鸯绿,則在Build之前需要安裝以下依賴:(以Ubuntu 16.04系統(tǒng)為例,其他Linux系統(tǒng)下的安裝指令類似):

sudo apt-get install python-dev

sudo apt-get install python3-dev

選擇Run->Build編譯全部

編譯成功后跋破,文件中多出了Build文件夾,其中astrodata是該庫需要的一些基礎(chǔ)數(shù)據(jù)文件瓶蝴,libNLOpt_d.dyliblibSpaceDSL_d.0.0.dylib等是動(dòng)態(tài)鏈接庫文件幔烛,PySpaceDSL_d.cpython-37m-darwin.so是該項(xiàng)目使用python封裝后的依賴庫文件。

基于以上動(dòng)態(tài)鏈接庫和位于Build/Dependence文件夾下的頭文件囊蓝,即可編寫C++代碼饿悬,進(jìn)行仿真,示例代碼如下:(TestMain.cpp)

#include <iostream>

#include "SpaceDSL/SpaceDSL.h"

using namespace std;
using namespace SpaceDSL;

int main(int argc, char *argv[])
{
    cout<<"SpaceDSL Test Run!"<<endl;
    try
    {
        /// Initial Data
        UTCCalTime vehicle_epoch     (2018,1,4,16,58,11.1);

        string targetName1 = "Facility1";
        PointTarget target1(targetName1, -75.5966*DegToRad, 40.0386*DegToRad, 0, 10*DegToRad);

        string vehicle_name1 = "The First Vehicle";// h = 257km
        CartState vehicle1_cart0(-5.04649e+06, -3.53951e+06, -2.44795e+06,
                                    4954.67 , -4008.83, -4417.73 );
        double vehicle1_mass = 1000.0;

        string vehicle_name2 = "The Second Vehicle"; // h = 1065km
        CartState vehicle2_cart0(-5.65484e+06, -3.96619e+06, -2.74305e+06,
                                    4680.57 , -3787.06, -4173.34 );
        double vehicle2_mass = 1500.0;

        /// Mission Start
        Mission *pMission = new Mission();
        auto pVehicle1 = pMission->InsertSpaceVehicle(vehicle_name1,vehicle_epoch,vehicle1_cart0,vehicle1_mass, 2.2, 3, 1.0, 3);
        auto pVehicle2 = pMission->InsertSpaceVehicle(vehicle_name2,vehicle_epoch,vehicle2_cart0,vehicle2_mass, 2.2, 6, 1.0, 6);
        pMission->RemoveSpaceVehicle(pVehicle2->GetID());
        pMission->InsertFacility(targetName1,-75.5966*DegToRad, 40.0386*DegToRad, 0, 10*DegToRad);
        ThirdBodyGravitySign thirdGravSign;
        thirdGravSign.bIsUseSunGrav = true;
        thirdGravSign.bIsUseMoonGrav = true;
        double kp = 3.0;
        VectorXd ap;
        ap.resize(7);
        ap.fill(0.0);
        ap(0) = GeomagneticKpToAp(kp);
        pMission->SetEnvironment(E_Earth, GravityModel::GravModelType::E_EGM08Model,
                                 20 , 20, thirdGravSign,
                                 GeodeticCoordSystem::GeodeticCoordType::E_WGS84System,
                                AtmosphereModel::AtmosphereModelType::E_NRLMSISE00Atmosphere,
                                 150,150,ap,
                                 true, true);
        pMission->SetPropagator(E_RungeKutta4, 60);
        //pMission->SetPropagator(E_RungeKutta78, 60, 0.01, 1, 120, 100);
        UTCCalTime initial_time     (2018,1,5,16,58,11.1);
        pMission->SetMissionSequence(initial_time, 86123);
        pMission->Start(true);

        cout<<"------First Calculation Finished ------"<<endl;
        pMission->CalMissionAccessData();
        auto accessListMap = pMission->GetAccessData();
        for (auto iterMap = accessListMap->begin();
             iterMap != accessListMap->end();
             ++iterMap)
        {
            cout<<"Access Data:"<<endl;
            cout<<iterMap->first.first->GetName()<<"--------"<<iterMap->first.second->GetName()<<endl;
            cout<<"  Start Time (UTCG)           Stop Time (UTCG)    Duration (sec)"<<endl;
            auto accessList = iterMap->second;
            for(auto &data:accessList)
            {
                double mjd = CalendarTimeToMjd(data.first);
                cout.precision(15);
                cout<<mjd<<"    "<<data.first.ToString()<<"    "<<data.second.ToString()<<"    "<<(data.second - data.first)<<endl;
            }
        }

        pVehicle1->Reset();
        pMission->ClearProcessData();
        pMission->Start();

        pMission->CalMissionAccessData();
        cout<<"------Second Calculation Finished ------"<<endl;
        accessListMap = pMission->GetAccessData();
        for (auto iterMap = accessListMap->begin();
             iterMap != accessListMap->end();
             ++iterMap)
        {
            cout<<"Access Data:"<<endl;
            cout<<iterMap->first.first->GetName()<<"--------"<<iterMap->first.second->GetName()<<endl;
            cout<<"  Start Time (UTCG)           Stop Time (UTCG)    Duration (sec)"<<endl;
            auto accessList = iterMap->second;
            for(auto &data:accessList)
            {
                double mjd = CalendarTimeToMjd(data.first);
                cout.precision(15);
                cout<<mjd<<"    "<<data.first.ToString()<<"    "<<data.second.ToString()<<"    "<<(data.second - data.first)<<endl;
            }
        }

        //CalObservationAll();

        cout<<"Calculation Finished!"<<endl;

        /// CZML File Wirte;
        CZMLScript  script;
        script.Initializer("TestData.czml", pMission);
        script.WirteCZML();
        cout<<"CZML Output Finished!"<<endl;
        pMission->Destory();

    }
    catch (SPException &e)
    {
        e.what();
    }

    return 0;
}

通過Python封裝過的依賴庫PySpaceDSL聚霜,可以使用Python編寫仿真代碼狡恬。
PySpaceDSL_d.cpython-37m-darwin.so文件重命名為PySpaceDSL.so珠叔,同時(shí)在當(dāng)前路徑下放置astrodata基礎(chǔ)數(shù)據(jù)文件夾,編寫Python腳本(TestPython.py):

from PySpaceDSL import *
import numpy as np

print("SpaceDSL Test Run!")


def main():
    # Initial Data
    initial_time = UTCCalTime(2018, 1, 4, 16, 58, 11.1)

    vehicle1_cart0 = CartState(-5.04649e+06, -3.53951e+06, -2.44795e+06, 4954.67, -4008.83, -4417.73)
    vehicle1_mass = 1000.0

    vehicle2_cart0 = CartState(-5.65484e+06, -3.96619e+06, -2.74305e+06, 4680.57, -3787.06, -4173.34)
    vehicle2_mass = 1500.0
    # Mission Start
    test_mission = Mission()
    test_mission.InsertSpaceVehicle('The First Vehicle', initial_time, vehicle1_cart0, vehicle1_mass, 2.2, 3, 1.0, 3)
    test_mission.InsertSpaceVehicle('The Second Vehicle', initial_time, vehicle2_cart0, vehicle2_mass, 2.2, 6, 1.0, 6)
    test_mission.InsertFacility('Facility1', -75.5966 * DegToRad(), 40.0386 * DegToRad(), 0, 10 * DegToRad())
    thirdGravSign = ThirdBodyGravitySign()
    thirdGravSign.bIsUseSunGrav = True
    thirdGravSign.bIsUseMoonGrav = True
    kp = 3.0
    ap = np.zeros(7)
    ap[0] = GeomagneticKpToAp(kp)

    test_mission.SetEnvironment(SolarSysStarType.E_Earth, GravityModel.GravModelType.E_EGM08Model, 20, 20,
                                thirdGravSign, GeodeticCoordSystem.GeodeticCoordType.E_WGS84System,
                                AtmosphereModel.AtmosphereModelType.E_NRLMSISE00Atmosphere,
                                150, 150, ap, True, True)
    test_mission.SetPropagator(IntegMethodType.E_RungeKutta4, 60.0)
    test_mission.SetMissionSequence(initial_time, 86400)
    test_mission.Start(True)

    print('------First Calculation Finished ------')
    test_mission.CalMissionAccessData()
    accessListMap = test_mission.GetAccessData()
    print(accessListMap)

    # CZML File Wirte;
    script = CZMLScript()
    script.Initializer("PyTestData.czml", test_mission)
    script.WirteCZML()
    print("CZML Output Finished!")


if __name__ == "__main__":
    main()

運(yùn)行程序弟劲,會(huì)在當(dāng)前目錄生成一個(gè).CZML后綴的文件祷安。CMZL文件是一種用來描述動(dòng)態(tài)場(chǎng)景的JSON架構(gòu)的語言,主要用于Cesium在瀏覽器中的展示兔乞。這里的CZML文件就是用于可視化展示仿真結(jié)果的描述文件汇鞭。

3.使用說明

編寫C++程序或Python腳本完成仿真過程,并自動(dòng)生成.CZML文件后庸追,可以通過SpaceDSL自帶的可視化程序ElectronVisualizer展示仿真結(jié)果霍骄。

首先需要在系統(tǒng)安裝Node.js環(huán)境。
然后切換到SpaceDSL項(xiàng)目中的ElectronVisualizer路徑下:

cd ElectronVisualizer

安裝相關(guān)依賴庫:

npm install --save-dev electron

npm install --save-dev cesium

npm install --save glob

然后淡溯,啟動(dòng)可視化軟件:

npm start

軟件啟動(dòng)后读整,點(diǎn)擊菜單Read Script,選擇先前生成的.CZML文件加載咱娶。

image

文件加載后米间,操作界面左下角的控制按鈕,即可播放仿真結(jié)果膘侮。

原文鏈接:http://www.trojx.me/2020/01/08/spacedsl/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末屈糊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子琼了,更是在濱河造成了極大的恐慌另玖,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件表伦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡慷丽,警方通過查閱死者的電腦和手機(jī)蹦哼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來要糊,“玉大人纲熏,你說我怎么就攤上這事〕恚” “怎么了局劲?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)奶赠。 經(jīng)常有香客問我鱼填,道長(zhǎng),這世上最難降的妖魔是什么毅戈? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任苹丸,我火速辦了婚禮愤惰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赘理。我一直安慰自己宦言,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布商模。 她就那樣靜靜地躺著奠旺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪施流。 梳的紋絲不亂的頭發(fā)上响疚,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音嫂沉,去河邊找鬼稽寒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛趟章,可吹牛的內(nèi)容都是我干的杏糙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼蚓土,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼宏侍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蜀漆,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤谅河,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后确丢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绷耍,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年鲜侥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了褂始。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡描函,死狀恐怖崎苗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舀寓,我是刑警寧澤胆数,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站互墓,受9級(jí)特大地震影響必尼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜篡撵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一胰伍、第九天 我趴在偏房一處隱蔽的房頂上張望齿诞。 院中可真熱鬧,春花似錦骂租、人聲如沸祷杈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽但汞。三九已至,卻和暖如春互站,著一層夾襖步出監(jiān)牢的瞬間私蕾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工胡桃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留踩叭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓翠胰,卻偏偏與公主長(zhǎng)得像容贝,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子之景,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容