Satellite.cpp   Satellite.cpp 
skipping to change at line 30 skipping to change at line 30
#include "Satellite.hpp" #include "Satellite.hpp"
#include "StelObject.hpp" #include "StelObject.hpp"
#include "StelPainter.hpp" #include "StelPainter.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelNavigator.hpp" #include "StelNavigator.hpp"
#include "StelLocation.hpp" #include "StelLocation.hpp"
#include "StelCore.hpp" #include "StelCore.hpp"
#include "StelTexture.hpp" #include "StelTexture.hpp"
#include "VecMath.hpp" #include "VecMath.hpp"
#include "StelUtils.hpp" #include "StelUtils.hpp"
#include "sgp4sdp4/sgp4sdp4.h"
#include "gsatellite/gSatTEME.hpp"
#include "gsatellite/gObserver.hpp"
#include "gsatellite/gTime.hpp"
#include "gsatellite/gVector.hpp"
#include <QTextStream> #include <QTextStream>
#include <QRegExp> #include <QRegExp>
#include <QDebug> #include <QDebug>
#include <QVariant> #include <QVariant>
#include <QtOpenGL>
#include <QSettings>
#include <QByteArray>
#include <cmath>
// static data members - will be initialised in the Satallites class (the S telObjectMgr) // static data members - will be initialised in the Satallites class (the S telObjectMgr)
StelTextureSP Satellite::hintTexture; StelTextureSP Satellite::hintTexture;
float Satellite::showLabels = true; float Satellite::showLabels = true;
float Satellite::hintBrightness = 0.0; float Satellite::hintBrightness = 0.0;
float Satellite::hintScale = 1.f; float Satellite::hintScale = 1.f;
SphericalCap Satellite::viewportHalfspace = SphericalCap();
int Satellite::orbitLineSegments = 90;
int Satellite::orbitLineFadeSegments = 4;
int Satellite::orbitLineSegmentDuration = 20;
bool Satellite::orbitLinesFlag = true;
Satellite::Satellite(const QVariantMap& map) Satellite::Satellite(const QVariantMap& map)
: initialized(false), visible(true), hintColor(0.0,0.0,0.0) : initialized(false), visible(true), hintColor(0.0,0.0,0.0), lastUpd ated(), pSatellite(NULL)
{ {
// return initialized if the mandatory fields are not present // return initialized if the mandatory fields are not present
if (!map.contains("designation") || !map.contains("tle1") || !map.co ntains("tle2")) if (!map.contains("designation") || !map.contains("tle1") || !map.co ntains("tle2"))
return; return;
font.setPixelSize(16);
designation = map.value("designation").toString(); designation = map.value("designation").toString();
strncpy(elements[0], "DUMMY", 5);
strncpy(elements[1], qPrintable(map.value("tle1").toString()), 80);
strncpy(elements[2], qPrintable(map.value("tle2").toString()), 80);
if (map.contains("description")) description = map.value("descriptio n").toString(); if (map.contains("description")) description = map.value("descriptio n").toString();
if (map.contains("visible")) visible = map.value("visible").toBool() ; if (map.contains("visible")) visible = map.value("visible").toBool() ;
if (map.contains("orbitVisible")) orbitVisible = map.value("orbitVis ible").toBool();
if (map.contains("hintColor")) if (map.contains("hintColor"))
{ {
if (map.value("hintColor").toList().count() == 3) if (map.value("hintColor").toList().count() == 3)
{ {
hintColor[0] = map.value("hintColor").toList().at(0) .toDouble(); hintColor[0] = map.value("hintColor").toList().at(0) .toDouble();
hintColor[1] = map.value("hintColor").toList().at(1) .toDouble(); hintColor[1] = map.value("hintColor").toList().at(1) .toDouble();
hintColor[2] = map.value("hintColor").toList().at(2) .toDouble(); hintColor[2] = map.value("hintColor").toList().at(2) .toDouble();
} }
} }
if (map.contains("orbitColor"))
{
if (map.value("orbitColor").toList().count() == 3)
{
orbitColorNormal[0] = map.value("orbitColor").toList
().at(0).toDouble();
orbitColorNormal[1] = map.value("orbitColor").toList
().at(1).toDouble();
orbitColorNormal[2] = map.value("orbitColor").toList
().at(2).toDouble();
}
}
else
{
orbitColorNormal = hintColor;
}
// Set the night color of orbit lines to red with the
// intensity of the average of the RGB for the day color.
float orbitColorBrightness = (orbitColorNormal[0] + orbitColorNormal
[1] + orbitColorNormal[2])/3;
orbitColorNight[0] = orbitColorBrightness;
orbitColorNight[1] = 0;
orbitColorNight[2] = 0;
if (StelApp::getInstance().getVisionModeNight())
orbitColor = &orbitColorNight;
else
orbitColor = &orbitColorNormal;
if (map.contains("comms")) if (map.contains("comms"))
{ {
foreach(QVariant comm, map.value("comms").toList()) foreach(QVariant comm, map.value("comms").toList())
{ {
QVariantMap commMap = comm.toMap(); QVariantMap commMap = comm.toMap();
commLink c; commLink c;
if (commMap.contains("frequency")) c.frequency = com mMap.value("frequency").toDouble(); if (commMap.contains("frequency")) c.frequency = com mMap.value("frequency").toDouble();
if (commMap.contains("modulation")) c.modulation = c ommMap.value("modulation").toString(); if (commMap.contains("modulation")) c.modulation = c ommMap.value("modulation").toString();
if (commMap.contains("description")) c.description = commMap.value("description").toString(); if (commMap.contains("description")) c.description = commMap.value("description").toString();
comms.append(c); comms.append(c);
skipping to change at line 89 skipping to change at line 129
if (map.contains("groups")) if (map.contains("groups"))
{ {
foreach(QVariant group, map.value("groups").toList()) foreach(QVariant group, map.value("groups").toList())
{ {
if (!groupIDs.contains(group.toString())) if (!groupIDs.contains(group.toString()))
groupIDs << group.toString(); groupIDs << group.toString();
} }
} }
setNewTleElements(map.value("tle1").toString(), map.value("tle2").to
String());
if (map.contains("lastUpdated"))
{
lastUpdated = map.value("lastUpdated").toDateTime();
}
setObserverLocation(); setObserverLocation();
initialized = true; initialized = true;
} }
Satellite::~Satellite() Satellite::~Satellite()
{ {
if(pSatellite != NULL)
delete pSatellite;
}
double Satellite::roundToDp(float n, int dp)
{
// round n to dp decimal places
return floor(n * pow(10., dp) + .5) / pow(10., dp);
} }
QVariantMap Satellite::getMap(void) QVariantMap Satellite::getMap(void)
{ {
QVariantMap map; QVariantMap map;
map["designation"] = designation; map["designation"] = designation;
map["visible"] = visible; map["tle1"] = tleElements.first.data();
map["tle1"] = QString(elements[1]); map["tle2"] = tleElements.second.data();
map["tle2"] = QString(elements[2]);
QVariantList col; if (!description.isEmpty() && description!="")
col << (double)hintColor[0] << (double)hintColor[1] << (double)hintC map["description"] = description;
olor[2];
map["visible"] = visible;
map["orbitVisible"] = orbitVisible;
QVariantList col, orbitCol;
col << roundToDp(hintColor[0],3) << roundToDp(hintColor[1], 3) << ro
undToDp(hintColor[2], 3);
orbitCol << roundToDp(orbitColorNormal[0], 3) << roundToDp(orbitColo
rNormal[1], 3) << roundToDp(orbitColorNormal[2],3);
map["hintColor"] = col; map["hintColor"] = col;
map["orbitColor"] = orbitCol;
QVariantList commList; QVariantList commList;
foreach(commLink c, comms) foreach(commLink c, comms)
{ {
QVariantMap commMap; QVariantMap commMap;
commMap["frequency"] = c.frequency; commMap["frequency"] = c.frequency;
if (!c.modulation.isEmpty() && c.modulation != "") commMap[" modulation"] = c.modulation; if (!c.modulation.isEmpty() && c.modulation != "") commMap[" modulation"] = c.modulation;
if (!c.description.isEmpty() && c.description != "") commMap ["description"] = c.description; if (!c.description.isEmpty() && c.description != "") commMap ["description"] = c.description;
commList << commMap; commList << commMap;
} }
map["comms"] = commList; map["comms"] = commList;
QVariantList groupList;
foreach(QString g, groupIDs)
{
groupList << g;
}
map["groups"] = groupList;
if (!lastUpdated.isNull())
{
map["lastUpdated"] = lastUpdated;
}
return map; return map;
} }
float Satellite::getSelectPriority(const StelNavigator*) const float Satellite::getSelectPriority(const StelNavigator*) const
{ {
return -10.; return -10.;
} }
QString Satellite::getInfoString(const StelCore *core, const InfoStringGrou p& flags) const QString Satellite::getInfoString(const StelCore *core, const InfoStringGrou p& flags) const
{ {
skipping to change at line 142 skipping to change at line 216
oss << "<h2>" << designation << "</h2><br>"; oss << "<h2>" << designation << "</h2><br>";
if (description!="") if (description!="")
oss << description << "<br>"; oss << description << "<br>";
} }
// Ra/Dec etc. // Ra/Dec etc.
oss << getPositionInfoString(core, flags); oss << getPositionInfoString(core, flags);
if (flags&Extra1) if (flags&Extra1)
{ {
oss << "<p>";
oss << QString("Range (km): <b>%1</b>").arg(range, 5, 'f', 2 ) << "<br>"; oss << QString("Range (km): <b>%1</b>").arg(range, 5, 'f', 2 ) << "<br>";
oss << QString("Range rate (km/s): <b>%1</b>").arg(rangeRate , 5, 'f', 3) << "<br>"; oss << QString("Range rate (km/s): <b>%1</b>").arg(rangeRate , 5, 'f', 3) << "<br>";
oss << QString("Altitude (km): <b>%1</b>").arg(height, 5, 'f ', 2) << "<br>"; oss << QString("Altitude (km): <b>%1</b>").arg(height, 5, 'f ', 2) << "<br>";
oss << QString("SubPoint Lat/Long(Deg): <b>%1</b>").arg(LatL
ong[0], 5, 'f', 2) << "/";
oss << QString("<b>%1</b>").arg(LatLong[1], 5, 'f', 3);
oss << "</p>";
oss << "TEME Coordinates(km): ";
oss << QString("<b>X:</b> %1 ").arg(Position[0], 5, 'f', 2);
oss << QString("<b>Y:</b> %1 ").arg(Position[1], 5, 'f', 2);
oss << QString("<b>Z:</b> %1 ").arg(Position[2], 5, 'f', 2)
<< "<br>";
oss << "TEME Vel(km/s): ";
oss << QString("<b>X:</b> %1 ").arg(Vel[0], 5, 'f', 2);
oss << QString("<b>Y:</b> %1 ").arg(Vel[1], 5, 'f', 2);
oss << QString("<b>Z:</b> %1 ").arg(Vel[2], 5, 'f', 2) << "<
br>";
} }
if (flags&Extra2 && comms.size() > 0) if (flags&Extra2 && comms.size() > 0)
{ {
foreach (commLink c, comms) foreach (commLink c, comms)
{ {
double dop = getDoppler(c.frequency); double dop = getDoppler(c.frequency);
double ddop = dop; double ddop = dop;
char sign; char sign;
if (dop<0.) if (dop<0.)
skipping to change at line 187 skipping to change at line 275
{ {
StelLocation l; StelLocation l;
if (loc==NULL) if (loc==NULL)
{ {
l = StelApp::getInstance().getCore()->getNavigator()->getCur rentLocation(); l = StelApp::getInstance().getCore()->getNavigator()->getCur rentLocation();
} }
else else
{ {
l = *loc; l = *loc;
} }
obs_geodetic.lon = l.longitude * de2ra;
obs_geodetic.lat = l.latitude * de2ra; observer.setPosition( l.latitude, l.longitude, l.altitude / 1000.0);
obs_geodetic.alt = l.altitude / 1000.0;
} }
Vec3f Satellite::getInfoColor(void) const { Vec3f Satellite::getInfoColor(void) const {
return StelApp::getInstance().getVisionModeNight() ? Vec3f(0.6, 0.0, 0.0) : hintColor; return StelApp::getInstance().getVisionModeNight() ? Vec3f(0.6, 0.0, 0.0) : hintColor;
} }
float Satellite::getVMagnitude(const StelNavigator*) const float Satellite::getVMagnitude(const StelNavigator*) const
{ {
return 5.0; return 5.0;
} }
double Satellite::getAngularSize(const StelCore*) const double Satellite::getAngularSize(const StelCore*) const
{ {
return 0.00001; return 0.00001;
} }
void Satellite::setNewTleElements(const QString& tle1, const QString& tle2)
{
if (pSatellite)
{
gSatTEME *old = pSatellite;
pSatellite = NULL;
delete old;
}
tleElements.first.clear();
tleElements.first.append(tle1);
tleElements.second.clear();
tleElements.second.append(tle2);
// The TLE library actually modifies the TLE strings, which is annoy
ing (because
// when we get updates, we want to check if there has been a change
by using ==
// with the original. Thus we make a copy to send to the TLE librar
y.
QByteArray t1(tleElements.first), t2(tleElements.second);
// Also, the TLE library expects no more than 130 characters length
input. We
// shouldn't have sane input with a TLE longer than about 80, but ju
st in case
// we have a mal-formed input, we will truncate here to be safe
t1.truncate(130);
t2.truncate(130);
pSatellite = new gSatTEME(designation.toAscii().data(),
t1.data(),
t2.data());
}
void Satellite::update(double) void Satellite::update(double)
{ {
ClearFlag(ALL_FLAGS); double jul_utc = StelApp::getInstance().getCore()->getNavigator()->g
Get_Next_Tle_Set(elements, &tle); etJDay();
memcpy(&localtle, &tle, sizeof(tle_t));
select_ephemeris(&tle);
double jul_epoch, jul_utc, tsince, phase;
vector_t vel = {0,0,0,0};
vector_t pos = {0,0,0,0};
vector_t obs_set;
geodetic_t sat_geodetic;
jul_utc = StelApp::getInstance().getCore()->getNavigator()->getJDay(
);
jul_epoch = Julian_Date_of_Epoch(tle.epoch);
tsince = (jul_utc - jul_epoch) * xmnpda;
if (isFlagSet(DEEP_SPACE_EPHEM_FLAG)) epochTime = jul_utc;
SDP4(tsince, &tle, &pos, &vel, &phase);
else if (pSatellite)
SGP4(tsince, &tle, &pos, &vel, &phase); {
pSatellite->setEpoch( epochTime);
Position = pSatellite->getPos();
Vel = pSatellite->getVel();
LatLong = pSatellite->getSubPoint( epochTime);
azElPos = observer.calculateLook( *pSatellite, epochTime);
azimuth = azElPos[ AZIMUTH]/KDEG2RAD;
elevation = azElPos[ ELEVATION]/KDEG2RAD;
range = azElPos[ RANGE];
rangeRate = azElPos[ RANGERATE];
height = LatLong[2];
Convert_Sat_State(&pos, &vel); // Compute orbit points to draw orbit line.
SgpMagnitude(&vel); // scalar magnitude, not brightness... if(orbitVisible) computeOrbitPoints();
velocity=vel.w; }
Calculate_Obs(jul_utc, &pos, &vel, &obs_geodetic, &obs_set);
Calculate_LatLonAlt(jul_utc, &pos, &sat_geodetic);
azimuth=Degrees(obs_set.x);
elevation=Degrees(obs_set.y);
range=obs_set.z;
rangeRate=obs_set.w;
height=sat_geodetic.alt;
} }
double Satellite::getDoppler(double freq) const double Satellite::getDoppler(double freq) const
{ {
double result; double result;
double f = freq * 1000000; double f = freq * 1000000;
result = -f*((rangeRate*1000.0)/SPEED_OF_LIGHT); result = -f*((rangeRate*1000.0)/SPEED_OF_LIGHT);
return result/1000000; return result/1000000;
} }
void Satellite::recalculateOrbitLines(void)
{
orbitPoints.clear();
}
void Satellite::draw(const StelCore* core, StelPainter& painter, float) void Satellite::draw(const StelCore* core, StelPainter& painter, float)
{ {
float a = (azimuth-90)*M_PI/180; float a = (azimuth-90)*M_PI/180;
Vec3d pos(sin(a),cos(a), tan(elevation * M_PI / 180.)); Vec3d pos(sin(a),cos(a), tan(elevation * M_PI / 180.));
XYZ = core->getNavigator()->j2000ToEquinoxEqu(core->getNavigator()-> altAzToEquinoxEqu(pos)); XYZ = core->getNavigator()->altAzToJ2000(pos);
StelApp::getInstance().getVisionModeNight() ? glColor4f(0.6,0.0,0.0, 1.0) : glColor4f(hintColor[0],hintColor[1],hintColor[2], Satellite::hintBri ghtness); StelApp::getInstance().getVisionModeNight() ? glColor4f(0.6,0.0,0.0, 1.0) : glColor4f(hintColor[0],hintColor[1],hintColor[2], Satellite::hintBri ghtness);
StelProjectorP prj = core->getProjection(StelCore::FrameJ2000); StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
Vec3d xy; Vec3d xy;
if (prj->project(XYZ,xy)) if (prj->project(XYZ,xy))
{ {
if (Satellite::showLabels) if (Satellite::showLabels)
{ {
painter.drawText(xy[0], xy[1], designation, 0, 10, 1 0, false); painter.drawText(xy[0], xy[1], designation, 0, 10, 1 0, false);
Satellite::hintTexture->bind(); Satellite::hintTexture->bind();
} }
painter.drawSprite2dMode(xy[0], xy[1], 11); painter.drawSprite2dMode(xy[0], xy[1], 11);
if(orbitVisible && Satellite::orbitLinesFlag) drawOrbit(pain
ter);
}
}
void Satellite::drawOrbit(StelPainter& painter){
Vec3d pos,posPrev;
float a, azimth, elev;
glDisable(GL_TEXTURE_2D);
QList<gVector>::iterator it= orbitPoints.begin();
//First point projection calculation
azimth = it->at( AZIMUTH);
elev = it->at( ELEVATION);
a = ( (azimth/KDEG2RAD)-90)*M_PI/180;
posPrev.set(sin(a),cos(a), tan( (elev/KDEG2RAD) * M_PI / 180.));
it++;
StelVertexArray vertexArray;
vertexArray.primitiveType=StelVertexArray::Lines;
//Rest of points
for(int i=1; i<orbitPoints.size();i++)
{
azimth = it->at( AZIMUTH);
elev = it->at( ELEVATION);
a = ( (azimth/KDEG2RAD)-90)*M_PI/180;
pos.set(sin(a),cos(a), tan( (elev/KDEG2RAD) * M_PI / 180.));
it++;
pos.normalize();
posPrev.normalize();
// Draw end (fading) parts of orbit lines one segment at a t
ime.
if (i<=orbitLineFadeSegments || orbitLineSegments-i < orbitL
ineFadeSegments)
{
painter.setColor((*orbitColor)[0], (*orbitColor)[1],
(*orbitColor)[2], hintBrightness * calculateOrbitSegmentIntensity(i));
painter.drawGreatCircleArc(posPrev, pos, &viewportHa
lfspace);
}
else {
vertexArray.vertex << posPrev << pos;
}
posPrev = pos;
}
// Draw center section of orbit in one go
painter.setColor((*orbitColor)[0], (*orbitColor)[1], (*orbitColor)[2
], hintBrightness);
painter.drawGreatCircleArcs(vertexArray, &viewportHalfspace);
glEnable(GL_TEXTURE_2D);
}
float Satellite::calculateOrbitSegmentIntensity(int segNum)
{
int endDist = (orbitLineSegments/2) - abs(segNum-1 - (orbitLineSegme
nts/2) % orbitLineSegments);
if (endDist > orbitLineFadeSegments) { return 1.0; }
else { return (endDist + 1) / (orbitLineFadeSegments + 1.0); }
}
void Satellite::setNightColors(bool night)
{
if (night)
orbitColor = &orbitColorNight;
else
orbitColor = &orbitColorNormal;
}
void Satellite::computeOrbitPoints()
{
gTimeSpan computeInterval(0, 0, 0, orbitLineSegmentDuration);
gTimeSpan orbitSpan(0, 0, 0, orbitLineSegments*orbitLineSegmentDurat
ion/2);
gTime epochTm;
gVector azElVector;
int diffSlots;
if( orbitPoints.isEmpty())//Setup orbitPoins
{
epochTm = epochTime - orbitSpan;
for(int i=0; i<=orbitLineSegments; i++)
{
pSatellite->setEpoch( epochTm);
azElVector = observer.calculateLook( *pSatellite, e
pochTm);
orbitPoints.append(azElVector);
epochTm += computeInterval;
}
lastEpochCompForOrbit = epochTime;
}
else if( epochTime > lastEpochCompForOrbit)
{ // compute next orbit point when clock runs forward
gTimeSpan diffTime = epochTime - lastEpochCompForOrbit;
diffSlots = (int)(diffTime.getDblSeconds()/orbitLin
eSegmentDuration);
if(diffSlots > 0)
{
if( diffSlots > orbitLineSegments)
{
diffSlots = orbitLineSegments + 1;
epochTm = epochTime - orbitSpan;
}
else
{
epochTm = lastEpochCompForOrbit + orbitSpa
n + computeInterval;
}
for( int i=0; i<diffSlots; i++)
{ //remove points at beginning of list and add poin
ts at end.
orbitPoints.removeFirst();
pSatellite->setEpoch( epochTm);
azElVector = observer.calculateLook( *pSate
llite, epochTm);
orbitPoints.append(azElVector);
epochTm += computeInterval;
}
lastEpochCompForOrbit = epochTime;
}
}
else if(epochTime < lastEpochCompForOrbit)
{ // compute next orbit point when clock runs backward
gTimeSpan diffTime = lastEpochCompForOrbit - epochTime;
diffSlots = (int)(diffTime.getDblSeconds()/orbitLin
eSegmentDuration);
if(diffSlots > 0)
{
if( diffSlots > orbitLineSegments)
{
diffSlots = orbitLineSegments + 1;
epochTm = epochTime + orbitSpan;
}
else
{
epochTm = epochTime - orbitSpan - computeI
nterval;
}
for( int i=0; i<diffSlots;i++)
{ //remove points at end of list and add points at b
eginning.
orbitPoints.removeLast();
pSatellite->setEpoch( epochTm);
azElVector = observer.calculateLook( *pSate
llite, epochTm);
orbitPoints.push_front(azElVector);
epochTm -= computeInterval;
}
lastEpochCompForOrbit = epochTime;
}
} }
} }
 End of changes. 24 change blocks. 
44 lines changed or deleted 341 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/