狠狠撸

狠狠撸Share a Scribd company logo
iTamabi 13
ARTSAT API 実践 5
衛星の軌道を描く
2013年12月2日
多摩美術大学PBL科目
田所 淳
今日の内容
? 衛星の軌道を計算
? そのデータをもとに、INVADER衛星の軌道を描画してみる!
今日の内容
? 前回までのサンプルは、INVADER衛星のセンサーによって取得
されたデータを、地上局で受信したものを使用していた
? 傾き、温度、電力 ...etc
!

? 今回は、また別のアプローチで衛星を視覚化したい
? 衛星が地球を周回している軌道を描くことはできないか?
参考:卫星轨道に関係する颈翱厂アプリ
参考:卫星轨道に関係する颈翱厂アプリ
? Orbit Architect, By a.i. solutions, Inc.
? http://itunes.apple.com/us/app/orbit-architect/
id392291462?mt=8
参考:卫星轨道に関係する颈翱厂アプリ
? GoSatWatch - Satellite Tracking, By GoSoftWorks
? http://itunes.apple.com/us/app/gosatwatch-satellitetracking/id300546718?mt=8
参考:卫星轨道に関係する颈翱厂アプリ
? ToriSat AR - 国際宇宙ステーションを見よう, Toriningen
Co.,Ltd.
? http://itunes.apple.com/jp/app/torisat/id361194118?mt=8#
参考:卫星轨道に関係する颈翱厂アプリ
? 今回は、こうしたアプリの基本となる衛星軌道の算出と推定の
方法について試していきたい
どうやって、卫星轨道を取得するのか?
人工衛星の軌道要素
? 軌道要素
? 天体の周囲を運動する天体の軌道を指定するためのパラメータ
人工衛星の軌道要素
? 人工衛星の軌道要素
? 元期: Epoch(年と日)
? 平均運動(m): Mean Motion(周回/日)
? 離心率(e): Eccentricity(単位無し)
? 軌道傾斜角(i): Inclination(度)
? 昇交点赤経(Ω): RAAN (Right Ascension of Ascending Node)
(度)
? 近地点離角(ω): Argument of Perigee(度)
? 平均近点角(M): Mean Anomaly(度)
!

? つまりは… 非常に複雑!!
TLE(Two Line Element) - 2行軌道要素形式
? TLE(Two Line Element) - 2行軌道要素形式
!

? 軌道要素は変動するため定期的な更新が必要
? 人工衛星の運用にあたっては軌道の測定が重要
? アメリカ合衆国のNORAD(※)は定期的に大きさ10cm以上の人
工天体のレーダー観測を行って軌道を測定し、公開している
? このフォーマットはTLE(Two Line Element)と呼ばれる
!

? ※ NORAD - 北アメリカ航空宇宙防衛司令部
TLE(Two Line Element) - 2行軌道要素形式
? NORAD - 北アメリカ航空宇宙防衛司令部
? 24時間体制で人工衛星の状況や地球上の核ミサイルや戦略爆撃
機などの動向を監視
TLE(Two Line Element) - 2行軌道要素形式
? 実際のTLEの例
NOAA 14
1 23455U 94089A
97320.90946019 .00000140 00000-0 10191-3 0 2621
2 23455 99.0090 272.6745 0008546 223.1686 136.8816 14.11711747148495

!

MIDORI (ADEOS)
1 24277U 96046A
2 24277 98.3597

!

09116.47337938 -.00000023 00000-0 73445-5 0
432
83.2073 0002090 64.7512 295.3886 14.28595439661547

ORBCOMM FM08 [+]
1 25112U 97084A
09116.51259343 .00000203 00000-0 12112-3 0 2154
2 25112 45.0199 241.1109 0010042 194.4473 165.6089 14.34380830592834
SGP
? 更新から30日以上経過した2行軌道要素形式を用いて計算され
た値は、信頼性に欠ける可能性がある
? 2行軌道要素形式から、SGP (Simpli?ed General Perturbations
Satellite Orbit Model) というアルゴリズムを用いて、より正確
な位置を推定
!

? 参考:Revisiting Spacetrack Report #3 (PDFファイル)
? http://www.centerforspace.com/downloads/?les/pubs/
AIAA-2006-6753.pdf
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1
? TLEおよびSGPを用いた軌道の推定を、自力でコーディングす
るのはかなり大変!!
? ARTSAT APIでは、SGPを使用した軌道推定の機能もインクルー
ドされている
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1
? ofxSgp - SGPを利用した軌道の計算を行う
!

? 例えば、ofxSgpのインスタンスをsgpとすると
!

? sgp.update(&現在の時刻)
? 軌道計算のための時間を更新
!

? sgp.getPos()?
? 現在の衛星軌道の座標(ofVec3f)を返す
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1
? では、ofxSgpを活用して、まずはシンプルに現在の時刻のPRISM
衛星の座標を取得してみましょう!
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1
? testApp.h
#pragma once

!

#include
#include
#include
#include
#include

!

"ofMain.h"
"ofxiOS.h"
"ofxiOSExtras.h"
"ofxARTSATAPI.h"
"ofxSgp.h"

class testApp : public ofxiOSApp, private ofxSAT::Notifier {
public:
void
void
void
void

!

setup();
update();
draw();
exit();

… (中略)…

!

};

virtual void onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time);
virtual void onNotifyData(ofxSATTime const& time);
ofxInvaderSAT invader;
ofxSgp sgp;
ofxSATTime current;
ofVec3f position;
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1
? testApp.mm
#include "testApp.h"

!

void testApp::setup(){
// 画面設定
ofBackground(0);
ofSetFrameRate(30);
// INVADERのセットアップ
if (invader.setNotifier(this) == SATERROR_OK) {
if (invader.setup() == SATERROR_OK) {
cout << "Hello ARTSAT." << endl;
}
}
}

!

void testApp::update(){
// 現在の時刻を取得
current = ofxSATTime::currentTime();
// SGPに時間を設定
sgp.update(&current);
// 現在のPRISM衛星の3D座標を算出
position = sgp.getPos();
}
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1
? testApp.mm
void testApp::draw(){
// 現在の衛星の座標を表示
ofSetHexColor(0xffffff);
string curretTimeStr = current.format("%YYYY/%MM/%DD %hh:%mm:%ss");
ofDrawBitmapString(curretTimeStr, 10, 15);
ofDrawBitmapString("x = " + ofToString(position.x, 4) + "n"
+ "y = " + ofToString(position.y, 4) + "n"
+ "z = " + ofToString(position.z, 4), 10, 50);
}

!
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1
? testApp.mm
void testApp::onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time){
// 取得したTLEをファイルに保存

!

!

string name;
string path;
ofstream file;
name = invader.getID();
ofStringReplace(name, "://", "");
path = ofToDataPath("");
path = ofFilePath::join(ofFilePath::getEnclosingDirectory(path), "Library");
path = ofFilePath::join(path, name + ".txt");
file.open(path.c_str());
if (file.is_open()) {
file << name << endl;
file << tle.line[0] << endl;
file << tle.line[1] << endl;
file.close();
// SGPをセットアップ
sgp.setup(path.c_str());
}

}
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1
? 完成! - 現在の衛星位置が取得されている
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 2
? では、取得したデータもとに実際に3D空間に描画してみましょ
う!
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 2
? testApp.h
#pragma once

!

#include
#include
#include
#include
#include

!

"ofMain.h"
"ofxiOS.h"
"ofxiOSExtras.h"
"ofxARTSATAPI.h"
"ofxSgp.h"

class testApp : public ofxiOSApp, private ofxSAT::Notifier {
public:
void setup();
void update();
void draw();

!

… (中略) …

!

};

virtual void onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time);
virtual void onNotifyData(ofxSATTime const& time);
ofxInvaderSAT invader;
ofxSgp sgp;
std::vector<ofxSATTime> available;
ofEasyCam camera;
ofxSATTime epoch;
ofxSATTime current;
ofBoxPrimitive box;
static const int TIME_SCALE = 100;
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 2
? testApp.mm
#include "testApp.h"

!

void testApp::setup(){
// 画面設定
ofBackground(0);
ofSetFrameRate(30);
// INVADERのセットアップ
if (invader.setNotifier(this) == SATERROR_OK) {
if (invader.setup() == SATERROR_OK) {
cout << "Hello ARTSAT." << endl;
}
}
// カメラ設定
camera.setFov(45);
camera.setFarClip(100000);
camera.setDistance(30000);
// 時間設定
epoch = ofxSATTime::currentTime();
current = epoch;
// 衛星設定
}

box.set(500);

!

void testApp::update(){
current = epoch + ofxSATTimeDiff(ofGetElapsedTimef() * TIME_SCALE);
sgp.update(&current);
// 衛星の位置を設定
}

box.setPosition(sgp.getPos());
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 2
? testApp.mm
void testApp::update(){
current = epoch + ofxSATTimeDiff(ofGetElapsedTimef() * TIME_SCALE);
sgp.update(&current);
// 衛星の位置を設定
box.setPosition(sgp.getPos());
}

!

void testApp::draw(){
camera.begin();

!

// 衛星を描画
ofSetColor(255);
box.draw();
camera.end();

}
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1
? testApp.mm
void testApp::onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time){
// 取得したTLEをファイルに保存

!

!

string name;
string path;
ofstream file;
name = invader.getID();
ofStringReplace(name, "://", "");
path = ofToDataPath("");
path = ofFilePath::join(ofFilePath::getEnclosingDirectory(path), "Library");
path = ofFilePath::join(path, name + ".txt");
file.open(path.c_str());
if (file.is_open()) {
file << name << endl;
file << tle.line[0] << endl;
file << tle.line[1] << endl;
file.close();
// SGPをセットアップ
sgp.setup(path.c_str());
}

}
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 2
? 完成! 表示されている小さな点が、PRISM衛星!!
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 3
? 衛星の点が表示されるだけでは、よくわからない
? 地球を実際のスケールで描いてみる
? 地球の赤道半径、6378km
? 6378kmの球を描けばよい
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 3
? testApp.h
#pragma once

!

#include
#include
#include
#include
#include

!

"ofMain.h"
"ofxiOS.h"
"ofxiOSExtras.h"
"ofxARTSATAPI.h"
"ofxSgp.h"

class testApp : public ofxiOSApp, private ofxSAT::Notifier {
public:
void setup();
void update();

!

… (中略) …

!

};

virtual void onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time);
virtual void onNotifyData(ofxSATTime const& time);
ofxInvaderSAT invader;
ofxSgp sgp;
std::vector<ofxSATTime> available;
ofEasyCam camera;
ofxSATTime epoch;
ofxSATTime current;
ofBoxPrimitive box;
ofSpherePrimitive earth;
static const int EARTH_SIZE = 6378;
static const int TIME_SCALE = 100;
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1
? testApp.mm
#include "testApp.h"

!

void testApp::setup(){
// 画面設定
ofBackground(0);
ofSetFrameRate(30);
// INVADERのセットアップ
if (invader.setNotifier(this) == SATERROR_OK) {
if (invader.setup() == SATERROR_OK) {
cout << "Hello ARTSAT." << endl;
}
}
// カメラ設定
camera.setFov(45);
camera.setFarClip(100000);
camera.setDistance(30000);
// 時間設定
epoch = ofxSATTime::currentTime();
current = epoch;
// 衛星設定
}

box.set(500);
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1
? testApp.mm
void testApp::update(){
current = epoch + ofxSATTimeDiff(ofGetElapsedTimef() * TIME_SCALE);
sgp.update(&current);
// 衛星の位置を設定
}

box.setPosition(sgp.getPos());

!

void testApp::draw(){
camera.begin();
// 地球を描画
ofSetColor(0, 127, 255);
earth.setRadius(EARTH_SIZE);
earth.setPosition(0, 0, 0);
earth.drawWireframe();
// 衛星を描画
ofSetColor(255);
box.draw();
}

!

camera.end();

… (後略) …
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 3
? 地球の周囲を周回!
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 4
? さらに、いろいろ工夫してみる
!

? 時間の経過スピードを変えてみる (例:60倍速)
? 指定した過去から始める
!

? 軌道を線で描く
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 4
? testApp.h
#pragma once

!

#include
#include
#include
#include
#include

!

"ofMain.h"
"ofxiOS.h"
"ofxiOSExtras.h"
"ofxARTSATAPI.h"
"ofxSgp.h"

class testApp : public ofxiOSApp, private ofxSAT::Notifier {
public:
void setup();
… (中略) …

!

};

virtual void onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time);
virtual void onNotifyData(ofxSATTime const& time);
ofxInvaderSAT invader;
ofxSgp sgp;
std::vector<ofxSATTime> available;
ofEasyCam camera;
ofxSATTime epoch;
ofxSATTime current;
ofBoxPrimitive box;
ofSpherePrimitive earth;
ofImage earthTexture;
ofMesh orbit;
static const int EARTH_SIZE = 6378;
static const int TIME_SCALE = 100;
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 4
? testApp.mm
#include "testApp.h"

!

void testApp::setup(){
// 画面設定
ofBackground(0);
ofSetFrameRate(30);
// INVADERのセットアップ
if (invader.setNotifier(this) == SATERROR_OK) {
if (invader.setup() == SATERROR_OK) {
cout << "Hello ARTSAT." << endl;
}
}
// カメラ設定
camera.setFov(45);
camera.setFarClip(100000);
camera.setDistance(30000);
// 時間設定
epoch = ofxSATTime::currentTime();
current = epoch;
// 衛星の大きさ設定
box.set(500);
// 軌道の描画モード設定
orbit.setMode(OF_PRIMITIVE_LINE_STRIP);
}
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 4
? testApp.mm
void testApp::update(){
current = epoch + ofxSATTimeDiff(ofGetElapsedTimef() * TIME_SCALE);
sgp.update(&current);
// 衛星の位置を設定

}

box.setPosition(sgp.getPos());
orbit.addVertex(sgp.getPos());
orbit.addColor(ofFloatColor(1.0,1.0,0.0));

!

void testApp::draw(){
camera.begin();
// Zバッファー
ofEnableDepthTest();
// 地球を描画
ofSetColor(0, 0, 255);
earth.setRadius(EARTH_SIZE);
earth.drawWireframe();
// 衛星を描画
ofSetColor(255);
box.draw();
// 軌道を描画
orbit.draw();

}

ofDisableDepthTest();
camera.end();
ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 4
? 完成!!

More Related Content

iTamabi 13 ARTSAT API 実践 5 - 衛星の軌道を描く

  • 1. iTamabi 13 ARTSAT API 実践 5 衛星の軌道を描く 2013年12月2日 多摩美術大学PBL科目 田所 淳
  • 3. 今日の内容 ? 前回までのサンプルは、INVADER衛星のセンサーによって取得 されたデータを、地上局で受信したものを使用していた ? 傾き、温度、電力 ...etc ! ? 今回は、また別のアプローチで衛星を視覚化したい ? 衛星が地球を周回している軌道を描くことはできないか?
  • 5. 参考:卫星轨道に関係する颈翱厂アプリ ? Orbit Architect, By a.i. solutions, Inc. ? http://itunes.apple.com/us/app/orbit-architect/ id392291462?mt=8
  • 6. 参考:卫星轨道に関係する颈翱厂アプリ ? GoSatWatch - Satellite Tracking, By GoSoftWorks ? http://itunes.apple.com/us/app/gosatwatch-satellitetracking/id300546718?mt=8
  • 7. 参考:卫星轨道に関係する颈翱厂アプリ ? ToriSat AR - 国際宇宙ステーションを見よう, Toriningen Co.,Ltd. ? http://itunes.apple.com/jp/app/torisat/id361194118?mt=8#
  • 11. 人工衛星の軌道要素 ? 人工衛星の軌道要素 ? 元期: Epoch(年と日) ? 平均運動(m): Mean Motion(周回/日) ? 離心率(e): Eccentricity(単位無し) ? 軌道傾斜角(i): Inclination(度) ? 昇交点赤経(Ω): RAAN (Right Ascension of Ascending Node) (度) ? 近地点離角(ω): Argument of Perigee(度) ? 平均近点角(M): Mean Anomaly(度) ! ? つまりは… 非常に複雑!!
  • 12. TLE(Two Line Element) - 2行軌道要素形式 ? TLE(Two Line Element) - 2行軌道要素形式 ! ? 軌道要素は変動するため定期的な更新が必要 ? 人工衛星の運用にあたっては軌道の測定が重要 ? アメリカ合衆国のNORAD(※)は定期的に大きさ10cm以上の人 工天体のレーダー観測を行って軌道を測定し、公開している ? このフォーマットはTLE(Two Line Element)と呼ばれる ! ? ※ NORAD - 北アメリカ航空宇宙防衛司令部
  • 13. TLE(Two Line Element) - 2行軌道要素形式 ? NORAD - 北アメリカ航空宇宙防衛司令部 ? 24時間体制で人工衛星の状況や地球上の核ミサイルや戦略爆撃 機などの動向を監視
  • 14. TLE(Two Line Element) - 2行軌道要素形式 ? 実際のTLEの例 NOAA 14 1 23455U 94089A 97320.90946019 .00000140 00000-0 10191-3 0 2621 2 23455 99.0090 272.6745 0008546 223.1686 136.8816 14.11711747148495 ! MIDORI (ADEOS) 1 24277U 96046A 2 24277 98.3597 ! 09116.47337938 -.00000023 00000-0 73445-5 0 432 83.2073 0002090 64.7512 295.3886 14.28595439661547 ORBCOMM FM08 [+] 1 25112U 97084A 09116.51259343 .00000203 00000-0 12112-3 0 2154 2 25112 45.0199 241.1109 0010042 194.4473 165.6089 14.34380830592834
  • 15. SGP ? 更新から30日以上経過した2行軌道要素形式を用いて計算され た値は、信頼性に欠ける可能性がある ? 2行軌道要素形式から、SGP (Simpli?ed General Perturbations Satellite Orbit Model) というアルゴリズムを用いて、より正確 な位置を推定 ! ? 参考:Revisiting Spacetrack Report #3 (PDFファイル) ? http://www.centerforspace.com/downloads/?les/pubs/ AIAA-2006-6753.pdf
  • 16. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得
  • 17. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1 ? TLEおよびSGPを用いた軌道の推定を、自力でコーディングす るのはかなり大変!! ? ARTSAT APIでは、SGPを使用した軌道推定の機能もインクルー ドされている
  • 18. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1 ? ofxSgp - SGPを利用した軌道の計算を行う ! ? 例えば、ofxSgpのインスタンスをsgpとすると ! ? sgp.update(&現在の時刻) ? 軌道計算のための時間を更新 ! ? sgp.getPos()? ? 現在の衛星軌道の座標(ofVec3f)を返す
  • 19. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1 ? では、ofxSgpを活用して、まずはシンプルに現在の時刻のPRISM 衛星の座標を取得してみましょう!
  • 20. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1 ? testApp.h #pragma once ! #include #include #include #include #include ! "ofMain.h" "ofxiOS.h" "ofxiOSExtras.h" "ofxARTSATAPI.h" "ofxSgp.h" class testApp : public ofxiOSApp, private ofxSAT::Notifier { public: void void void void ! setup(); update(); draw(); exit(); … (中略)… ! }; virtual void onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time); virtual void onNotifyData(ofxSATTime const& time); ofxInvaderSAT invader; ofxSgp sgp; ofxSATTime current; ofVec3f position;
  • 21. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1 ? testApp.mm #include "testApp.h" ! void testApp::setup(){ // 画面設定 ofBackground(0); ofSetFrameRate(30); // INVADERのセットアップ if (invader.setNotifier(this) == SATERROR_OK) { if (invader.setup() == SATERROR_OK) { cout << "Hello ARTSAT." << endl; } } } ! void testApp::update(){ // 現在の時刻を取得 current = ofxSATTime::currentTime(); // SGPに時間を設定 sgp.update(&current); // 現在のPRISM衛星の3D座標を算出 position = sgp.getPos(); }
  • 22. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1 ? testApp.mm void testApp::draw(){ // 現在の衛星の座標を表示 ofSetHexColor(0xffffff); string curretTimeStr = current.format("%YYYY/%MM/%DD %hh:%mm:%ss"); ofDrawBitmapString(curretTimeStr, 10, 15); ofDrawBitmapString("x = " + ofToString(position.x, 4) + "n" + "y = " + ofToString(position.y, 4) + "n" + "z = " + ofToString(position.z, 4), 10, 50); } !
  • 23. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1 ? testApp.mm void testApp::onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time){ // 取得したTLEをファイルに保存 ! ! string name; string path; ofstream file; name = invader.getID(); ofStringReplace(name, "://", ""); path = ofToDataPath(""); path = ofFilePath::join(ofFilePath::getEnclosingDirectory(path), "Library"); path = ofFilePath::join(path, name + ".txt"); file.open(path.c_str()); if (file.is_open()) { file << name << endl; file << tle.line[0] << endl; file << tle.line[1] << endl; file.close(); // SGPをセットアップ sgp.setup(path.c_str()); } }
  • 24. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1 ? 完成! - 現在の衛星位置が取得されている
  • 25. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 2 ? では、取得したデータもとに実際に3D空間に描画してみましょ う!
  • 26. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 2 ? testApp.h #pragma once ! #include #include #include #include #include ! "ofMain.h" "ofxiOS.h" "ofxiOSExtras.h" "ofxARTSATAPI.h" "ofxSgp.h" class testApp : public ofxiOSApp, private ofxSAT::Notifier { public: void setup(); void update(); void draw(); ! … (中略) … ! }; virtual void onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time); virtual void onNotifyData(ofxSATTime const& time); ofxInvaderSAT invader; ofxSgp sgp; std::vector<ofxSATTime> available; ofEasyCam camera; ofxSATTime epoch; ofxSATTime current; ofBoxPrimitive box; static const int TIME_SCALE = 100;
  • 27. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 2 ? testApp.mm #include "testApp.h" ! void testApp::setup(){ // 画面設定 ofBackground(0); ofSetFrameRate(30); // INVADERのセットアップ if (invader.setNotifier(this) == SATERROR_OK) { if (invader.setup() == SATERROR_OK) { cout << "Hello ARTSAT." << endl; } } // カメラ設定 camera.setFov(45); camera.setFarClip(100000); camera.setDistance(30000); // 時間設定 epoch = ofxSATTime::currentTime(); current = epoch; // 衛星設定 } box.set(500); ! void testApp::update(){ current = epoch + ofxSATTimeDiff(ofGetElapsedTimef() * TIME_SCALE); sgp.update(&current); // 衛星の位置を設定 } box.setPosition(sgp.getPos());
  • 28. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 2 ? testApp.mm void testApp::update(){ current = epoch + ofxSATTimeDiff(ofGetElapsedTimef() * TIME_SCALE); sgp.update(&current); // 衛星の位置を設定 box.setPosition(sgp.getPos()); } ! void testApp::draw(){ camera.begin(); ! // 衛星を描画 ofSetColor(255); box.draw(); camera.end(); }
  • 29. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1 ? testApp.mm void testApp::onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time){ // 取得したTLEをファイルに保存 ! ! string name; string path; ofstream file; name = invader.getID(); ofStringReplace(name, "://", ""); path = ofToDataPath(""); path = ofFilePath::join(ofFilePath::getEnclosingDirectory(path), "Library"); path = ofFilePath::join(path, name + ".txt"); file.open(path.c_str()); if (file.is_open()) { file << name << endl; file << tle.line[0] << endl; file << tle.line[1] << endl; file.close(); // SGPをセットアップ sgp.setup(path.c_str()); } }
  • 30. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 2 ? 完成! 表示されている小さな点が、PRISM衛星!!
  • 31. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 3 ? 衛星の点が表示されるだけでは、よくわからない ? 地球を実際のスケールで描いてみる ? 地球の赤道半径、6378km ? 6378kmの球を描けばよい
  • 32. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 3 ? testApp.h #pragma once ! #include #include #include #include #include ! "ofMain.h" "ofxiOS.h" "ofxiOSExtras.h" "ofxARTSATAPI.h" "ofxSgp.h" class testApp : public ofxiOSApp, private ofxSAT::Notifier { public: void setup(); void update(); ! … (中略) … ! }; virtual void onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time); virtual void onNotifyData(ofxSATTime const& time); ofxInvaderSAT invader; ofxSgp sgp; std::vector<ofxSATTime> available; ofEasyCam camera; ofxSATTime epoch; ofxSATTime current; ofBoxPrimitive box; ofSpherePrimitive earth; static const int EARTH_SIZE = 6378; static const int TIME_SCALE = 100;
  • 33. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1 ? testApp.mm #include "testApp.h" ! void testApp::setup(){ // 画面設定 ofBackground(0); ofSetFrameRate(30); // INVADERのセットアップ if (invader.setNotifier(this) == SATERROR_OK) { if (invader.setup() == SATERROR_OK) { cout << "Hello ARTSAT." << endl; } } // カメラ設定 camera.setFov(45); camera.setFarClip(100000); camera.setDistance(30000); // 時間設定 epoch = ofxSATTime::currentTime(); current = epoch; // 衛星設定 } box.set(500);
  • 34. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 1 ? testApp.mm void testApp::update(){ current = epoch + ofxSATTimeDiff(ofGetElapsedTimef() * TIME_SCALE); sgp.update(&current); // 衛星の位置を設定 } box.setPosition(sgp.getPos()); ! void testApp::draw(){ camera.begin(); // 地球を描画 ofSetColor(0, 127, 255); earth.setRadius(EARTH_SIZE); earth.setPosition(0, 0, 0); earth.drawWireframe(); // 衛星を描画 ofSetColor(255); box.draw(); } ! camera.end(); … (後略) …
  • 35. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 3 ? 地球の周囲を周回!
  • 36. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 4 ? さらに、いろいろ工夫してみる ! ? 時間の経過スピードを変えてみる (例:60倍速) ? 指定した過去から始める ! ? 軌道を線で描く
  • 37. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 4 ? testApp.h #pragma once ! #include #include #include #include #include ! "ofMain.h" "ofxiOS.h" "ofxiOSExtras.h" "ofxARTSATAPI.h" "ofxSgp.h" class testApp : public ofxiOSApp, private ofxSAT::Notifier { public: void setup(); … (中略) … ! }; virtual void onNotifyTLE(ofxSAT::TLERec const& tle, ofxSATTime const& time); virtual void onNotifyData(ofxSATTime const& time); ofxInvaderSAT invader; ofxSgp sgp; std::vector<ofxSATTime> available; ofEasyCam camera; ofxSATTime epoch; ofxSATTime current; ofBoxPrimitive box; ofSpherePrimitive earth; ofImage earthTexture; ofMesh orbit; static const int EARTH_SIZE = 6378; static const int TIME_SCALE = 100;
  • 38. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 4 ? testApp.mm #include "testApp.h" ! void testApp::setup(){ // 画面設定 ofBackground(0); ofSetFrameRate(30); // INVADERのセットアップ if (invader.setNotifier(this) == SATERROR_OK) { if (invader.setup() == SATERROR_OK) { cout << "Hello ARTSAT." << endl; } } // カメラ設定 camera.setFov(45); camera.setFarClip(100000); camera.setDistance(30000); // 時間設定 epoch = ofxSATTime::currentTime(); current = epoch; // 衛星の大きさ設定 box.set(500); // 軌道の描画モード設定 orbit.setMode(OF_PRIMITIVE_LINE_STRIP); }
  • 39. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 4 ? testApp.mm void testApp::update(){ current = epoch + ofxSATTimeDiff(ofGetElapsedTimef() * TIME_SCALE); sgp.update(&current); // 衛星の位置を設定 } box.setPosition(sgp.getPos()); orbit.addVertex(sgp.getPos()); orbit.addColor(ofFloatColor(1.0,1.0,0.0)); ! void testApp::draw(){ camera.begin(); // Zバッファー ofEnableDepthTest(); // 地球を描画 ofSetColor(0, 0, 255); earth.setRadius(EARTH_SIZE); earth.drawWireframe(); // 衛星を描画 ofSetColor(255); box.draw(); // 軌道を描画 orbit.draw(); } ofDisableDepthTest(); camera.end();
  • 40. ARTSAT API + 辞蹿虫厂骋笔で卫星轨道を取得 4 ? 完成!!