1 /*
2  * Stellarium
3  * Copyright (C) 2009, 2012 Matthew Gates
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
18  */
19 
20 #ifndef SATELLITE_HPP
21 #define SATELLITE_HPP
22 
23 #include <QDateTime>
24 #include <QFont>
25 #include <QList>
26 #include <QSharedPointer>
27 #include <QString>
28 #include <QStringList>
29 #include <QVariant>
30 
31 #include "StelObject.hpp"
32 #include "StelTextureTypes.hpp"
33 #include "StelSphereGeometry.hpp"
34 #include "gSatWrapper.hpp"
35 #include "SolarSystem.hpp"
36 
37 class StelPainter;
38 class StelLocation;
39 
40 //! Radio communication channel properties.
41 //! @ingroup satellites
42 typedef struct
43 {
44 	double frequency; //!< Channel frequency in MHz.
45 	QString modulation; //!< Signal modulation mode.
46 	QString description; //!< Channel description.
47 } CommLink;
48 
49 //! Description of the data roles used in SatellitesListModel.
50 //! @ingroup satellites
51 enum SatelliteDataRole {
52 	SatIdRole = Qt::UserRole,
53 	SatCosparIDRole,
54 	SatDescriptionRole,
55 	SatStdMagnitudeRole,
56 	SatRCSRole,
57 	SatPerigeeRole,
58 	SatApogeeRole,
59 	SatPeriodRole,
60 	SatTLEEpochRole,
61 	SatFlagsRole,
62 	SatGroupsRole,
63 	FirstLineRole,
64 	SecondLineRole
65 };
66 
67 //! Type for sets of satellite group IDs.
68 //! @ingroup satellites
69 typedef QSet<QString> GroupSet;
70 
71 //! Flag type reflecting internal flags of Satellite.
72 //! @ingroup satellites
73 enum SatFlag
74 {
75 	SatNoFlags		= 0x0000,
76 	SatDisplayed		= 0x0001,
77 	SatNotDisplayed		= 0x0002,
78 	SatUser			= 0x0004,
79 	SatOrbit		= 0x0008,
80 	SatNew			= 0x0010,
81 	SatError		= 0x0020,
82 	SatSmallSize		= 0x0040,
83 	SatMediumSize		= 0x0080,
84 	SatLargeSize		= 0x0100,
85 	SatLEO			= 0x0200,
86 	SatMEO			= 0x0400,
87 	SatGSO			= 0x0800,
88 	SatHEO			= 0x1000,
89 	SatHGSO			= 0x2000,
90 	SatOutdatedTLE		= 0x4000
91 };
92 typedef QFlags<SatFlag> SatFlags;
93 Q_DECLARE_OPERATORS_FOR_FLAGS(SatFlags)
94 
95 // Allows the type to be used by QVariant
96 Q_DECLARE_METATYPE(GroupSet)
97 Q_DECLARE_METATYPE(SatFlags)
98 
99 //! @class Satellite
100 //! A representation of a satellite in Earth orbit.
101 //! Details about the satellite are passed with a JSON-representation structure
102 //! that contains a <b>Satellite Catalog</b> entry.
103 //!
104 //! Thanks to operator<() overloading, container classes (QList, QMap, etc.)
105 //! with Satellite or SatelliteP objects can be sorted by satellite name/ID.
106 //! @ingroup satellites
107 class Satellite : public StelObject
108 {
109 	friend class Satellites;
110 	friend class SatellitesDialog;
111 	friend class SatellitesListModel;
112 
113 public:
114 	static const QString SATELLITE_TYPE;
115 
116 	//! @enum OptStatus operational statuses
117 	enum OptStatus
118 	{
119 		StatusOperational		= 1,
120 		StatusNonoperational		= 2,
121 		StatusPartiallyOperational	= 3,
122 		StatusStandby			= 4,
123 		StatusSpare			= 5,
124 		StatusExtendedMission		= 6,
125 		StatusDecayed			= 7,
126 		StatusUnknown			= 0
127 	};
128 	Q_ENUM(OptStatus)
129 
130 	//! \param identifier unique identifier (currently the Catalog Number)
131 	//! \param data a QMap which contains the details of the satellite
132 	//! (TLE set, description etc.)
133 	Satellite(const QString& identifier, const QVariantMap& data);
134 	~Satellite();
135 
136 	//! Get a QVariantMap which describes the satellite.  Could be used to
137 	//! create a duplicate.
138 	QVariantMap getMap(void);
139 
getType(void) const140 	virtual QString getType(void) const
141 	{
142 		return SATELLITE_TYPE;
143 	}
144 
getID(void) const145 	virtual QString getID(void) const
146 	{
147 		return id;
148 	}
149 
150 	virtual float getSelectPriority(const StelCore* core) const;
151 
152 	//! Get an HTML string to describe the object
153 	//! @param core A pointer to the core
154 	//! @param flags a set of flags with information types to include.
155 	//! Supported types for Satellite objects:
156 	//! - Name: designation in large type with the description underneath
157 	//! - RaDecJ2000, RaDecOfDate, HourAngle, AltAzi
158 	//! - Extra: range, range rate and altitude of satellite above the Earth, comms frequencies, modulation types and so on.
159 	virtual QString getInfoString(const StelCore *core, const InfoStringGroup& flags) const;
160 	//! Return a map like StelObject::getInfoMap(), but with a few extra tags also available in getInfoString().
161 	//! - description
162 	//! - catalog
163 	//! - international-designator
164 	//! - type
165 	//! - range (distance in km)
166 	//! - rangerate (distance change in km/s)
167 	//! - height (height in km)
168 	//! - subpoint-lat (latitude of subpoint, decimal degrees)
169 	//! - subpoint-long (longitude of subpoint, decimal degrees)
170 	//! - inclination (decimal degrees)
171 	//! - period (minutes)
172 	//! - perigee-altitude (height in km)
173 	//! - apogee-altitude (height in km)
174 	//! - TEME-km-X
175 	//! - TEME-km-Y
176 	//! - TEME-km-Z
177 	//! - TEME-speed-X
178 	//! - TEME-speed-Y
179 	//! - TEME-speed-Z
180 	//! - sun-reflection-angle (if available)
181 	//! - operational-status
182 	//! - visibility (descriptive string)
183 	//! - comm (Radio information, optional, if available. There may be several comm entries!)
184 	virtual QVariantMap getInfoMap(const StelCore *core) const;
185 	virtual Vec3f getInfoColor(void) const;
186 	virtual Vec3d getJ2000EquatorialPos(const StelCore*) const;
187 	virtual float getVMagnitude(const StelCore* core) const;
188 	//! Get angular size, degrees
189 	virtual double getAngularSize(const StelCore*) const;
190 	virtual QString getNameI18n(void) const;
getEnglishName(void) const191 	virtual QString getEnglishName(void) const
192 	{
193 		return name;
194 	}
195 	//! Returns the (NORAD) catalog number. (For now, the ID string.)
getCatalogNumberString() const196 	QString getCatalogNumberString() const {return id;}
197 
198 	//! Set new tleElements.  This assumes the designation is already set, populates
199 	//! the tleElements values and configures internal orbit parameters.
200 	void setNewTleElements(const QString& tle1, const QString& tle2);
201 
202 	// calculate faders, new position
203 	void update(double deltaTime);
204 
205 	double getDoppler(double freq) const;
206 	static bool showLabels;
207 	static double roundToDp(float n, int dp);
208 
209 	// when the observer location changes we need to
210 	void recalculateOrbitLines(void);
211 
setNew()212 	void setNew() {newlyAdded = true;}
isNew() const213 	bool isNew() const {return newlyAdded;}
214 
215 	//! Get internal flags as a single value.
216 	SatFlags getFlags() const;
217 	//! Sets the internal flags in one operation (only display flags)!
218 	void setFlags(const SatFlags& flags);
219 
220 	//! Needed for sorting lists (if this ever happens...).
221 	//! Compares #name fields. If equal, #id fields, which can't be.
222 	bool operator<(const Satellite& another) const;
223 
224 	//! Calculation of illuminated fraction of the satellite.
225 	float calculateIlluminatedFraction() const;
226 
227 	//! Get operational status of satellite
228 	QString getOperationalStatus() const;
229 
230 	void recomputeSatData();
231 
232 private:
233 	//draw orbits methods
234 	void computeOrbitPoints();
235 	void drawOrbit(StelCore* core, StelPainter& painter);
236 	//! returns 0 - 1.0 for the DRAWORBIT_FADE_NUMBER segments at
237 	//! each end of an orbit, with 1 in the middle.
238 	float calculateOrbitSegmentIntensity(int segNum);
239 	void calculateSatDataFromLine2(QString tle);
240 	//! Parse TLE line to extract International Designator and launch year.
241 	//! Sets #internationalDesignator and #jdLaunchYearJan1.
242 	void parseInternationalDesignator(const QString& tle1);
243 	void calculateEpochFromLine1(QString tle);
244 
245 	bool initialized;
246 	//! Flag indicating whether the satellite should be displayed.
247 	//! Should not be confused with the pedicted visibility of the
248 	//! actual satellite to the observer.
249 	bool displayed;
250 	//! Flag indicating whether an orbit section should be displayed.
251 	bool orbitDisplayed;  // draw orbit enabled/disabled
252 	//! Flag indicating that the satellite is user-defined.
253 	//! This means that its TLE set shouldn't be updated and the satellite
254 	//! itself shouldn't be removed if auto-remove is enabled.
255 	bool userDefined;
256 	//! Flag indicating that the satellite was added during the current session.
257 	bool newlyAdded;
258 	bool orbitValid;
259 
260 	//! Identifier of the satellite, must be unique within the list.
261 	//! Currently, the Satellite Catalog Number/NORAD Number is used,
262 	//! as it is unique and it is contained in both lines of TLE sets.
263 	QString id;
264 	//! Human-readable name of the satellite.
265 	//! Usually the string in the "Title line" of TLE sets.
266 	QString name;
267 	//! Longer description of the satellite.
268 	QString description;
269 	//! International Designator / COSPAR designation / NSSDC ID.
270 	QString internationalDesignator;
271 	//! Epoch of the TLE
272 	QString tleEpoch;
273 	//! Epoch of the TLE (JD)
274 	double tleEpochJD;
275 	//! Julian date of Jan 1st of the launch year.
276 	//! Used to hide satellites before their launch date.
277 	//! Extracted from TLE set with parseInternationalDesignator().
278 	//! It defaults to 1 Jan 1957 if extraction fails.
279 	double jdLaunchYearJan1;
280 	//! Standard visual magnitude of the satellite.
281 	double stdMag;
282 	double RCS;
283 	double perigee;
284 	double apogee;
285 	double inclination;
286 	double eccentricity;
287 	//! Operational status code
288 	int status;
289 	//! Contains the J2000 position.
290 	Vec3d XYZ;
291 	QPair< QByteArray, QByteArray > tleElements;
292 	double height, range, rangeRate;
293 	QList<CommLink> comms;
294 	Vec3f hintColor;
295 	//! Identifiers of the groups to which the satellite belongs.
296 	//! See @ref groups.
297 	GroupSet groups;
298 	QDateTime lastUpdated;
299 
300 	bool isISS;
301 	PlanetP moon;
302 	PlanetP sun;
303 
304 	static StelTextureSP hintTexture;
305 	static SphericalCap  viewportHalfspace;
306 	static float hintBrightness;
307 	static float hintScale;
308 	static int   orbitLineSegments;
309 	static int   orbitLineFadeSegments;
310 	static int   orbitLineSegmentDuration; //measured in seconds
311 	static bool  orbitLinesFlag;
312 	static bool  iconicModeFlag;
313 	static bool  hideInvisibleSatellitesFlag;
314 	//! Mask controlling which info display flags should be honoured.
315 	static StelObject::InfoStringGroupFlags flagsMask;
316 	static Vec3f invisibleSatelliteColor;
317 	static Vec3f transitSatelliteColor;
318 
319 	static double timeRateLimit;
320 	static int tleEpochAge;
321 
322 	void draw(StelCore *core, StelPainter& painter);
323 
324 	//Satellite Orbit Position calculation
325 	gSatWrapper *pSatWrapper;
326 	Vec3d	position;
327 	Vec3d	velocity;
328 	Vec3d	latLongSubPointPosition;
329 	Vec3d	elAzPosition;
330 
331 	gSatWrapper::Visibility	visibility;
332 	double	phaseAngle; // phase angle for the satellite
333 #if(SATELLITES_PLUGIN_IRIDIUM == 1)
334 	static double sunReflAngle; // for Iridium satellites
335 	//static double timeShift; // for Iridium satellites UNUSED
336 #endif
337 	Vec3f    infoColor;
338 	//Satellite Orbit Draw
339 	Vec3f    orbitColor;
340 	double    lastEpochCompForOrbit; //measured in Julian Days
341 	double    epochTime;  //measured in Julian Days
342 	QList<Vec3d> orbitPoints; //orbit points represented by ElAzPos vectors
343 	QList<gSatWrapper::Visibility> visibilityPoints; //orbit visibility points
344 	QMap<gSatWrapper::Visibility, QString> visibilityDescription;
345 };
346 
347 typedef QSharedPointer<Satellite> SatelliteP;
348 bool operator<(const SatelliteP& left, const SatelliteP& right);
349 
350 #endif // SATELLITE_HPP
351 
352