summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJogi Hofmüller <jogi@mur.at>2011-08-23 16:59:29 +0000
committerJogi Hofmüller <jogi@mur.at>2011-08-23 16:59:29 +0000
commit5032f03fc11cd231decd2d7cfd5dd3576a7e45ea (patch)
tree0221b3387ab7c022fb1dd9b9b8108cb65ecfb667 /tools
parent- changed date string in tle.js file output (diff)
- created tracker.wsgi as wsgi app
- imported updated javascript libraries git-svn-id: https://svn.spreadspace.org/mur.sat@147 7de4ea59-55d0-425e-a1af-a3118ea81d4c
Diffstat (limited to 'tools')
-rw-r--r--tools/mmd/MmdLocation.py5
-rw-r--r--tools/mmd/MmdWidgets.py133
-rw-r--r--tools/mmd/mmd.css39
-rw-r--r--tools/mmd/orbtrak.js298
-rw-r--r--tools/mmd/predictlib.js1916
-rw-r--r--tools/mmd/tracker.wsgi106
6 files changed, 2438 insertions, 59 deletions
diff --git a/tools/mmd/MmdLocation.py b/tools/mmd/MmdLocation.py
index a31ff67..e50360f 100644
--- a/tools/mmd/MmdLocation.py
+++ b/tools/mmd/MmdLocation.py
@@ -43,6 +43,10 @@ class Location:
self.longitude = 15.44226
if not self.latitude:
self.latitude = 47.06576
+ if not self.altitude:
+ self.altitude = 376
+ if not self.name:
+ self.name = 'Graz/Austria'
self.location_id = hashlib.sha1 ('{0}{1}{2}'.format (user_id, self.longitude, self.latitude)).hexdigest ()
return self.db.locationCreate (
@@ -73,6 +77,7 @@ class Location:
self.name = l['name']
self.longitude = float (l['longitude'])
self.latitude = float (l['latitude'])
+ self.altitude = float (l['altitude'])
self.is_default = l['is_default']
self.user_id = l['user_id']
return True
diff --git a/tools/mmd/MmdWidgets.py b/tools/mmd/MmdWidgets.py
index e245397..4cdedef 100644
--- a/tools/mmd/MmdWidgets.py
+++ b/tools/mmd/MmdWidgets.py
@@ -295,73 +295,88 @@ def osmWidget (session):
user_location = session.user.getDefaultLocation ()
if not user_location:
user_location = Location ()
- minutes_preview = 180
-
html = '''
- <div id="osm"></div>
- <script src="http://www.openlayers.org/api/OpenLayers.js"></script>
- <script type="text/javascript">
- // satellite and user position
- var from = new OpenLayers.Projection ("EPSG:4326");
- var to = new OpenLayers.Projection ("EPSG:900913");
- var sat_position = new OpenLayers.LonLat ({0}, {1}).transform (from, to);
- var user_location = new OpenLayers.LonLat ({2}, {3}).transform (from, to);
-
- // create a map
- var map = new OpenLayers.Map ("osm");
- map.addLayer (new OpenLayers.Layer.OSM ());
-
- // create a markers
- var markersLayer = new OpenLayers.Layer.Markers ("Markers");
- var sat = new OpenLayers.Marker (sat_position);
- var user = new OpenLayers.Marker (user_location);
- user.setOpacity (0.5);
- map.addLayer (markersLayer);
- markersLayer.addMarker (sat);
- markersLayer.addMarker (user);
-
- // array build by python ;)
- {4}
-
- // points/polygons
- var lineLayer = new OpenLayers.Layer.Vector ("Polygons");
- map.addLayer (lineLayer);
- // map.addControl (new OpenLayers.Control.DrawFeature(lineLayer, OpenLayers.Handler.Path));
- var Features = new Array ();
- // var colors = new Array ('#ff0000', '#00ff00', '#0000ff');
-
- for (var i = 0; i < curves.length; i++)
- {{
- var points = new Array ();
- for (var j = 0; j < curves[i].length; j++)
- {{
- points.push (new OpenLayers.Geometry.Point (curves[i][j].lon, curves[i][j].lat));
- }}
- var c = i % 3;
- var lineStyle = {{strokeColor: '#003366', strokeOpacity: 1, strokeWidth: 1}};
- Features.push (new OpenLayers.Feature.Vector (new OpenLayers.Geometry.LineString (points), null, lineStyle))
- }}
-
- lineLayer.addFeatures (Features);
-
- // zoom to world view
- map.zoomTo (1);
-
- </script>
- <div class="info">
- The map shows the satellite's expected ground track for the next {5} minutes.
- </div>
+ <iframe src="http://hofos.at/tracker?name={0}&longitude={1}&latitude={2}&altitude={3}" width="540px" height="400px" frameborder="0" scrolling="no"></iframe>
'''.format (
- session.satellite.longitude,
- session.satellite.latitude,
+ user_location.name,
user_location.longitude,
user_location.latitude,
- session.satellite.getTrajectoryAsJavaArray ('curves', minutes_preview),
- minutes_preview
+ user_location.altitude
)
return html
+# def osmWidget (session):
+# user_location = session.user.getDefaultLocation ()
+# if not user_location:
+# user_location = Location ()
+# minutes_preview = 180
+#
+# html = '''
+# <div id="osm"></div>
+# <script src="http://www.openlayers.org/api/OpenLayers.js"></script>
+# <script type="text/javascript">
+# // satellite and user position
+# var from = new OpenLayers.Projection ("EPSG:4326");
+# var to = new OpenLayers.Projection ("EPSG:900913");
+# var sat_position = new OpenLayers.LonLat ({0}, {1}).transform (from, to);
+# var user_location = new OpenLayers.LonLat ({2}, {3}).transform (from, to);
+#
+# // create a map
+# var map = new OpenLayers.Map ("osm");
+# map.addLayer (new OpenLayers.Layer.OSM ());
+#
+# // create a markers
+# var markersLayer = new OpenLayers.Layer.Markers ("Markers");
+# var sat = new OpenLayers.Marker (sat_position);
+# var user = new OpenLayers.Marker (user_location);
+# user.setOpacity (0.5);
+# map.addLayer (markersLayer);
+# markersLayer.addMarker (sat);
+# markersLayer.addMarker (user);
+#
+# // array build by python ;)
+# {4}
+#
+# // points/polygons
+# var lineLayer = new OpenLayers.Layer.Vector ("Polygons");
+# map.addLayer (lineLayer);
+# // map.addControl (new OpenLayers.Control.DrawFeature(lineLayer, OpenLayers.Handler.Path));
+# var Features = new Array ();
+# // var colors = new Array ('#ff0000', '#00ff00', '#0000ff');
+#
+# for (var i = 0; i < curves.length; i++)
+# {{
+# var points = new Array ();
+# for (var j = 0; j < curves[i].length; j++)
+# {{
+# points.push (new OpenLayers.Geometry.Point (curves[i][j].lon, curves[i][j].lat));
+# }}
+# var c = i % 3;
+# var lineStyle = {{strokeColor: '#003366', strokeOpacity: 1, strokeWidth: 1}};
+# Features.push (new OpenLayers.Feature.Vector (new OpenLayers.Geometry.LineString (points), null, lineStyle))
+# }}
+#
+# lineLayer.addFeatures (Features);
+#
+# // zoom to world view
+# map.zoomTo (1);
+#
+# </script>
+# <div class="info">
+# The map shows the satellite's expected ground track for the next {5} minutes.
+# </div>
+# '''.format (
+# session.satellite.longitude,
+# session.satellite.latitude,
+# user_location.longitude,
+# user_location.latitude,
+# session.satellite.getTrajectoryAsJavaArray ('curves', minutes_preview),
+# minutes_preview
+# )
+#
+# return html
+
def statusWidget (session):
if session.status == 'auth':
inout = '''Status: logged in as {0}. <span id="logout"><a href="?cmd=logout">logout</a></span>'''.format (session.user.email)
diff --git a/tools/mmd/mmd.css b/tools/mmd/mmd.css
index 43c17c6..609ea5e 100644
--- a/tools/mmd/mmd.css
+++ b/tools/mmd/mmd.css
@@ -129,3 +129,42 @@ em
float: left;
width: 1em;
}
+
+.telemetry
+{
+ font: 10pt courier, monospace;
+ color: white;
+}
+
+.groundstation
+{
+ font: 10pt courier, monospace;
+ color: yellow;
+}
+
+select.telemetry,
+input.telemetry
+{
+ border: 1px solid #ffffff;
+ background: #003366;
+}
+
+td.telemetry,
+th.telemetry,
+th.telemetry
+{
+ font: 10pt courier, monospace;
+ color: white;
+ border: 1px solid white;
+}
+
+th.telemetry
+{
+ font-weight: bold;
+}
+
+table.current
+{
+ border: 1px solid white;
+}
+
diff --git a/tools/mmd/orbtrak.js b/tools/mmd/orbtrak.js
new file mode 100644
index 0000000..c2582bd
--- /dev/null
+++ b/tools/mmd/orbtrak.js
@@ -0,0 +1,298 @@
+/****************************************************************************
+* OrbTrak: A satellite orbit visualization library *
+* Copyright Andrew T. West, 2008 *
+* Last update: 07-Jun-2008 *
+*****************************************************************************
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU General Public License as published by the *
+* Free Software Foundation; either version 2 of the License or any later *
+* version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+* General Public License for more details. *
+* *
+*****************************************************************************/
+
+// orbtrak.js and predictlib.js both work for one satellite now
+// Jogi, 2011-08-22
+
+var Orb =
+ {
+ satelliteMarkers: new Array(),
+ satellitePoint: new Object (),
+ satLayer: new OpenLayers.Layer.Vector ("satLayer"),
+ homeLayer: new OpenLayers.Layer.Vector ("homeLayer"),
+ trackLayer: new OpenLayers.Layer.Vector ("trackLayer"),
+ track: new Array (),
+ from: new OpenLayers.Projection ("EPSG:4326"),
+ to: new OpenLayers.Projection ("EPSG:900913"),
+
+ startOSMTracking: function (minutes, longitude, latitude, altitude, name)
+ {
+ PLib.InitializeData();
+ PLib.configureGroundStation(latitude, longitude, altitude, name);
+ document.getElementById ("gsName").innerHTML = name;
+ document.getElementById ("gsLongitude").innerHTML = longitude;
+ document.getElementById ("gsLatitude").innerHTML = latitude;
+ document.getElementById ("gsAltitude").innerHTML = altitude;
+ Orb.createOSMSatellite ();
+
+ var map = new OpenLayers.Map ("osm");
+ map.addLayers ([new OpenLayers.Layer.OSM (), Orb.trackLayer, Orb.satLayer, Orb.homeLayer]);
+ map.zoomTo (1);
+
+ var satStyle = {fillColor: "#FFED00", pointRadius: 3, stroke: false};
+ var homeStyle = {fillColor: "#00ff00", pointRadius: 3, stroke: false};
+ var home = new OpenLayers.LonLat (longitude, latitude).transform (Orb.from, Orb.to);
+
+ Orb.createSatelliteTrack (minutes);
+ Orb.homeLayer.addFeatures ([
+ new OpenLayers.Feature.Vector (
+ new OpenLayers.Geometry.Point (home.lon, home.lat),
+ null, homeStyle)]);
+ // map.zoomToMaxExtent ();
+ Orb.satLayer.addFeatures ([
+ new OpenLayers.Feature.Vector (Orb.satellitePoint,
+ null, satStyle)]);
+ setTimeout ("Orb.updateOSMSatellite ()", document.getElementById ("refresh").value);
+ },
+
+ createSatelliteTrack: function (minutes)
+ {
+ if (document.getElementById ("previewMinutes") != null)
+ minutes = document.getElementById ("previewMinutes").value;
+ Orb.trackLayer.destroyFeatures ();
+ var curve = new Array ();
+ var points = new Array ();
+ var track = PLib.calculateTrack (minutes);
+ var lineStyle = {strokeColor: '#003366', strokeOpacity: 1, strokeWidth: 1};
+ var last = "east";
+
+ for (var i = 0; i < track.length; i++)
+ {
+ var lonlat = new OpenLayers.LonLat (track[i][0], track[i][1]).transform (Orb.from, Orb.to);
+ var lon = "" + track[i][0];
+ if (lon.substring (0, 1) == "-")
+ {
+ if (last == "east")
+ {
+ curve.push (new OpenLayers.Feature.Vector (new OpenLayers.Geometry.LineString (points), null, lineStyle))
+ points = new Array ();
+ }
+ last = "west";
+ }
+ else
+ last = "east";
+ points.push (new OpenLayers.Geometry.Point (lonlat.lon, lonlat.lat));
+ }
+ curve.push (new OpenLayers.Feature.Vector (new OpenLayers.Geometry.LineString (points), null, lineStyle))
+ Orb.trackLayer.addFeatures (curve);
+ },
+
+ updateOSMSatellite: function ()
+ {
+ var satInfo;
+ var satellites = Orb.satLayer.features;
+
+ satInfo = PLib.QuickFind (PLib.sat.name);
+ var pos = new OpenLayers.LonLat (satInfo.longitude, satInfo.latitude).transform (Orb.from, Orb.to);
+ satellites[0].move (pos);
+ Orb.printSatellite (satInfo);
+ setTimeout ("Orb.updateOSMSatellite ()", document.getElementById ("refresh").value);
+ },
+
+ createOSMSatellite: function ()
+ {
+ var satInfo;
+ satInfo = PLib.QuickFind (PLib.sat.name);
+ var pos = new OpenLayers.LonLat (satInfo.longitude, satInfo.latitude).transform (Orb.from, Orb.to);
+ Orb.satellitePoint = new OpenLayers.Geometry.Point (pos.lon, pos.lat);
+ },
+
+ startTracking: function(map, homeLat, homeLng)
+ {
+ Orb.map = map;
+ Orb.crossBrowserSetStyle(map, "background-image: url(orbimages/world.jpg); overflow: hidden;", true);
+
+ var frag = document.createDocumentFragment();
+ var div = document.createElement("div");
+ div.id = "home";
+ Orb.crossBrowserSetStyle(div, "position:relative; width: 24px; height: 24px; background-image: url(orbimages/home.gif);", false);
+ frag.appendChild(div);
+ Orb.map.appendChild(frag);
+ Orb.home = document.getElementById("home");
+
+ PLib.InitializeData();
+ Orb.setHomeCoordinates(homeLat, homeLng);
+ Orb.createSatelliteMarkers();
+ Orb.updateSatellites();
+ },
+
+ setHomeCoordinates: function(homeLat, homeLng)
+ {
+ PLib.configureGroundStation(homeLat, homeLng);
+
+ Orb.home.style.top = ((-homeLat + 90) * 1.5 - 12.0) + "px";
+ Orb.home.style.left = ((parseInt(homeLng) + 180) * 1.5 - 12.0) + "px";
+ },
+
+ crossBrowserSetStyle: function(element, css, append)
+ {
+ var obj, attributeName;
+ var useStyleObject = element.style.setAttribute;
+
+ obj = useStyleObject ? element.style : element;
+ attributeName = useStyleObject ? "cssText" : "style";
+
+ if (append)
+ css += obj.getAttribute(attributeName);
+
+ obj.setAttribute(attributeName, css);
+ },
+
+ createOneMarker: function(txt)
+ {
+ var frag = document.createDocumentFragment();
+ var markerCount = Orb.satelliteMarkers.length;
+
+ var div = document.createElement("div");
+ div.id = "satelliteMarker" + markerCount;
+ Orb.crossBrowserSetStyle(div, "position:absolute; width: 24px; height: 24px; background-image: url(orbimages/saticon.gif);", false);
+ var innerDiv = document.createElement("div");
+ Orb.crossBrowserSetStyle(innerDiv, "position:absolute; left: 7px; top: 5px;");
+ var txt = document.createTextNode(txt);
+
+ innerDiv.appendChild(txt);
+ div.appendChild(innerDiv);
+ frag.appendChild(div);
+ Orb.map.appendChild(frag);
+
+ Orb.satelliteMarkers[markerCount] = document.getElementById(div.id)
+ },
+
+ createSatelliteMarkers: function()
+ {
+ for (var i = 1; i <= PLib.sat.length; i++)
+ Orb.createOneMarker(i);
+ },
+
+ updateSatellites: function()
+ {
+ var satInfo;
+
+ for (var i = 0; i < PLib.sat.length; i++)
+ {
+ satInfo = PLib.QuickFind(PLib.sat[i].name);
+
+ Orb.satelliteMarkers[i].style.top = ((-satInfo.latitude + 90) * 1.5 - 12.0) + "px";
+ Orb.satelliteMarkers[i].style.left = ((satInfo.longitude + 180) * 1.5 - 12.0) + "px";
+ Orb.printSatellite (satInfo);
+ }
+
+ setTimeout("Orb.updateSatellites()", 1000);
+ },
+
+ // added by Jogi
+ // 2011-08-21
+ printSatellite: function (satInfo)
+ {
+ document.getElementById ("longitude").innerHTML = satInfo.longitude;
+ document.getElementById ("latitude").innerHTML = satInfo.latitude;
+ document.getElementById ("elevation").innerHTML = satInfo.elevation;
+ document.getElementById ("azimuth").innerHTML = satInfo.azimuth;
+ document.getElementById ("altitude").innerHTML = satInfo.altitude;
+ },
+
+ createCell: function(tr, className, txt)
+ {
+ var td = document.createElement("td");
+ td.className = className;
+ txt = document.createTextNode(txt);
+ td.appendChild(txt);
+ tr.appendChild(td);
+ },
+
+ createHeaderColumn: function(tr, txt)
+ {
+ var th = document.createElement("th");
+ th.className = "orb-header";
+ txt = document.createTextNode(txt);
+ th.appendChild(txt);
+ tr.appendChild(th);
+ },
+
+ generateTable: function(divTable)
+ {
+ var tr, visibilityText, detailClassName;
+ var frag = document.createDocumentFragment();
+ var satInfoColl = PLib.getTodaysPasses();
+
+ while (divTable.childNodes.length > 0)
+ {
+ divTable.removeChild(divTable.firstChild);
+ }
+
+ var tbl = document.createElement("table");
+ Orb.crossBrowserSetStyle(tbl, "border-collapse: collapse; margin-left: auto; margin-right: auto;", false);
+
+ var thead = document.createElement("thead");
+ tr = document.createElement("tr");
+
+ Orb.createHeaderColumn(tr, '# on Map');
+ Orb.createHeaderColumn(tr, 'Name');
+ Orb.createHeaderColumn(tr, 'Pass #');
+ Orb.createHeaderColumn(tr, 'Date');
+ Orb.createHeaderColumn(tr, 'Local Time');
+ Orb.createHeaderColumn(tr, 'Peak Elev.');
+ Orb.createHeaderColumn(tr, 'Azimuth');
+ Orb.createHeaderColumn(tr, 'Range (km)');
+ Orb.createHeaderColumn(tr, 'Visibility');
+
+ thead.appendChild(tr);
+ tbl.appendChild(thead);
+
+ var tbody = document.createElement("tbody");
+
+ for (var i = 0; i < satInfoColl.length; i++)
+ {
+ tr = document.createElement("tr");
+
+ detailClassName = satInfoColl[i].visibility == "+" ? "orb-detailVisible" : "orb-detail";
+
+ Orb.createCell(tr, detailClassName, satInfoColl[i].number);
+ Orb.createCell(tr, detailClassName, satInfoColl[i].name);
+ Orb.createCell(tr, detailClassName, satInfoColl[i].passNo);
+ Orb.createCell(tr, detailClassName, PLib.formatDateOnly(satInfoColl[i].dateTimeStart));
+ Orb.createCell(tr, detailClassName, PLib.formatTimeOnly(satInfoColl[i].dateTimeStart) + " - " + PLib.formatTimeOnly(satInfoColl[i].dateTimeEnd));
+ Orb.createCell(tr, detailClassName, satInfoColl[i].peakElevation + "\u00B0");
+ Orb.createCell(tr, detailClassName, satInfoColl[i].riseAzimuth + ", " + satInfoColl[i].peakAzimuth + ", " + satInfoColl[i].decayAzimuth);
+ Orb.createCell(tr, detailClassName, satInfoColl[i].riseRange + ", " + satInfoColl[i].peakRange + ", " + satInfoColl[i].decayRange);
+
+ switch(satInfoColl[i].visibility)
+ {
+ case "+":
+ visibilityText = 'Visible';
+ break;
+ case "*":
+ visibilityText = 'Not Visible';
+ break;
+ default:
+ visibilityText = 'Eclipsed';
+ }
+
+ Orb.createCell(tr, detailClassName, visibilityText);
+
+ tbody.appendChild(tr);
+ }
+
+ tbl.appendChild(tbody);
+ frag.appendChild(tbl);
+ divTable.appendChild(frag);
+ }
+ }
+
+// vim: ts=2 tw=0 expandtab
+// EOF
diff --git a/tools/mmd/predictlib.js b/tools/mmd/predictlib.js
new file mode 100644
index 0000000..574bd3f
--- /dev/null
+++ b/tools/mmd/predictlib.js
@@ -0,0 +1,1916 @@
+/****************************************************************************
+* PredictLib: A satellite tracking/orbital prediction library *
+* Copyright Andrew T. West, 2008 *
+* Based on PREDICT, Copyright John A. Magliacane, KD2BD 1991-2002 *
+* Last update: 07-Jun-2008 *
+*****************************************************************************
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU General Public License as published by the *
+* Free Software Foundation; either version 2 of the License or any later *
+* version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+* General Public License for more details. *
+* *
+*****************************************************************************/
+
+var PLib =
+ {
+ deg2rad: 1.745329251994330E-2,
+ pi: 3.14159265358979323846, pio2: 1.57079632679489656, twopi: 6.28318530717958623,
+ e6a: 1.0E-6,
+ tothrd: 6.6666666666666666E-1,
+ xj3: -2.53881E-6, xke: 7.43669161E-2, xkmper: 6.378137E3, xmnpda: 1.44E3,
+ ae: 1.0,
+ ck2: 5.413079E-4, ck4: 6.209887E-7,
+ f: 3.35281066474748E-3, s: 1.012229,
+ qoms2t: 1.880279E-09,
+ secday: 8.6400E4,
+ omega_E: 1.00273790934,
+ zns: 1.19459E-5, c1ss: 2.9864797E-6, zes: 1.675E-2, znl: 1.5835218E-4, c1l: 4.7968065E-7, zel: 5.490E-2,
+ zcosis: 9.1744867E-1, zsinis: 3.9785416E-1, zsings: -9.8088458E-1, zcosgs: 1.945905E-1,
+ q22: 1.7891679E-6, q31: 2.1460748E-6, q33: 2.2123015E-7,
+ g22: 5.7686396, g32: 9.5240898E-1, g44: 1.8014998, g52: 1.0508330, g54: 4.4108898,
+ root22: 1.7891679E-6, root32: 3.7393792E-7, root44: 7.3636953E-9, root52: 1.1428639E-7, root54: 2.1765803E-9,
+ thdt: 4.3752691E-3,
+ mfactor: 7.292115E-5,
+ sr: 6.96000E5,
+ AU: 1.49597870691E8,
+
+ dpinit: 1, dpsec: 2, dpper: 3,
+
+ ALL_FLAGS: -1,
+ SGP4_INITIALIZED_FLAG: 0x000002,
+ SDP4_INITIALIZED_FLAG: 0x000004,
+ SIMPLE_FLAG: 0x000020,
+ DEEP_SPACE_EPHEM_FLAG: 0x000040,
+ LUNAR_TERMS_DONE_FLAG: 0x000080,
+ DO_LOOP_FLAG: 0x000200,
+ RESONANCE_FLAG: 0x000400,
+ SYNCHRONOUS_FLAG: 0x000800,
+ EPOCH_RESTART_FLAG: 0x001000,
+ VISIBLE_FLAG: 0x002000,
+ SAT_ECLIPSED_FLAG: 0x004000,
+
+ sat_t: function()
+ {
+ this.line1 = "";
+ this.line2 = "";
+ this.name = "";
+ this.catnum = 0;
+ this.setnum = 0;
+ this.designator = "";
+ this.year = 0;
+ this.refepoch = 0.0;
+ this.incl = 0.0;
+ this.raan = 0.0;
+ this.eccn = 0.0;
+ this.argper = 0.0;
+ this.meanan = 0.0;
+ this.meanmo = 0.0;
+ this.drag = 0.0;
+ this.nddot6 = 0.0;
+ this.bstar = 0.0;
+ this.orbitnum = 0.0;
+ this.refepoch = 0;
+ },
+
+ // sat: new Array(),
+ sat: "",
+
+ qth:
+ {
+ callsign: "HOME",
+ name: "",
+ stnlat: 0.0,
+ stnlong: 0.0,
+ stnalt: 1000,
+ utc_offset: new Date().getTimezoneOffset() / 60
+ },
+
+ tempstr: "", output: "",
+
+ tsince: 0.0, jul_epoch: 0.0, jul_utc: 0.0, eclipse_depth: 0.0,
+ sat_azi: 0.0, sat_ele: 0.0, sat_range: 0.0, sat_range_rate: 0.0,
+ sat_lat: 0.0, sat_lon: 0.0, sat_alt: 0.0, sat_vel: 0.0, phase: 0.0,
+ sun_azi: 0.0, sun_ele: 0.0, daynum: 0.0, fm: 0.0, fk: 0.0, age: 0.0, aostime: 0.0,
+ lostime: 0.0, ax: 0.0, ay: 0.0, az: 0.0, rx: 0.0, ry: 0.0, rz: 0.0, squint: 0.0, alat: 0.0, alon: 0.0,
+
+ ephem: "", sat_sun_status: "", findsun: "",
+
+ indx: 0, iaz: 0, iel: 0, ma256: 0, isplat: 0, isplong: 0, Flags: 0,
+
+ rv: 0, irk: 0,
+
+ tle_t: function()
+ {
+ this.epoch = 0.0;
+ this.xndt2o = 0.0;
+ this.xndd6o = 0.0;
+ this.bstar = 0.0;
+ this.xincl = 0.0;
+ this.xnodeo = 0.0;
+ this.eo = 0.0;
+ this.omegao = 0.0;
+ this.xmo = 0.0;
+ this.xno = 0.0;
+ this.catnr = 0;
+ this.elset = 0;
+ this.revnum = 0;
+ this.sat_name = "";
+ this.idesg = "";
+ },
+
+ geodetic_t: function()
+ {
+ this.lat = 0.0;
+ this.lon = 0.0;
+ this.alt = 0.0;
+ this.theta = 0.0;
+ },
+
+ vector_t: function()
+ {
+ this.x = 0.0;
+ this.y = 0.0;
+ this.z = 0.0;
+ this.w = 0.0;
+ },
+
+ deep_arg_t: function()
+ {
+ this.eosq = 0.0;
+ this.sinio = 0.0;
+ this.cosio = 0.0;
+ this.betao = 0.0;
+ this.aodp = 0.0;
+ this.theta2 = 0.0;
+ this.sing = 0.0;
+ this.cosg = 0.0;
+ this.betao2 = 0.0;
+ this.xmdot = 0.0;
+ this.omgdot = 0.0;
+ this.xnodot = 0.0;
+ this.xnodp = 0.0;
+ this.xll = 0.0;
+ this.omgadf = 0.0;
+ this.xnode = 0.0;
+ this.em = 0.0;
+ this.xinc = 0.0;
+ this.xn = 0.0;
+ this.t = 0.0;
+ this.ds50 = 0.0;
+ },
+
+ obs_geodetic: new Object(),
+ tle: new Object(),
+ tleData: new Array(),
+
+ isFlagSet: function(flag)
+ {
+ return (PLib.Flags & flag);
+ },
+
+ isFlagClear: function(flag)
+ {
+ return (~PLib.Flags & flag);
+ },
+
+ SetFlag: function(flag)
+ {
+ PLib.Flags |= flag;
+ },
+
+ ClearFlag: function (flag)
+ {
+ PLib.Flags &= ~flag;
+ },
+
+ Sqr: function(arg)
+ {
+ return (arg * arg);
+ },
+
+ Radians: function(arg)
+ {
+ return (arg * PLib.deg2rad);
+ },
+
+ Degrees: function(arg)
+ {
+ return (arg / PLib.deg2rad);
+ },
+
+ Magnitude: function(v)
+ {
+ v.w = Math.sqrt(PLib.Sqr(v.x) + PLib.Sqr(v.y) + PLib.Sqr(v.z));
+ },
+
+ Vec_Sub: function(v1, v2, v3)
+ {
+ v3.x = v1.x - v2.x;
+ v3.y = v1.y - v2.y;
+ v3.z = v1.z - v2.z;
+ PLib.Magnitude(v3);
+ },
+
+ Scalar_Multiply: function(k, v1, v2)
+ {
+ v2.x = k * v1.x;
+ v2.y = k * v1.y;
+ v2.z = k * v1.z;
+ v2.w = Math.abs(k) * v1.w;
+ },
+
+ Scale_Vector: function(k, v)
+ {
+ v.x *= k;
+ v.y *= k;
+ v.z *= k;
+ PLib.Magnitude(v);
+ },
+
+ Dot: function(v1, v2)
+ {
+ return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z);
+ },
+
+ Angle: function(v1, v2)
+ {
+ PLib.Magnitude(v1);
+ PLib.Magnitude(v2);
+ return (Math.acos(PLib.Dot(v1, v2) / (v1.w * v2.w)));
+ },
+
+ FMod2p: function(x)
+ {
+ var i = 0;
+ var ret_val = 0.0;
+
+ ret_val = x;
+ i = parseInt(ret_val / PLib.twopi);
+ ret_val -= i * PLib.twopi;
+
+ if (ret_val < 0.0)
+ ret_val += PLib.twopi;
+
+ return ret_val;
+ },
+
+ Modulus: function(arg1, arg2)
+ {
+ return arg1 - (parseInt(arg1 / arg2)) * arg2;
+ },
+
+ Frac: function(arg)
+ {
+ return(arg - Math.floor(arg));
+ },
+
+ Convert_Sat_State: function(pos, vel)
+ {
+ PLib.Scale_Vector(PLib.xkmper, pos);
+ PLib.Scale_Vector(PLib.xkmper * PLib.xmnpda / PLib.secday, vel);
+ },
+
+ Julian_Date_of_Year: function(year)
+ {
+ var A = 0, B = 0, i = 0;
+ var jdoy = 0.0;
+
+ year = year - 1;
+ i = parseInt(year / 100);
+ A = i;
+ i = parseInt(A / 4);
+ B = 2 - A + i;
+ i = parseInt(365.25 * year);
+ i += parseInt(30.6001 * 14);
+ jdoy = i + 1720994.5 + B;
+
+ return jdoy;
+ },
+
+ Julian_Date_of_Epoch: function(epoch)
+ {
+ var year = 0.0, day = 0.0;
+
+ year = parseInt(epoch * 1E-3);
+ day = ((epoch * 1E-3) - year) * 1E3;
+
+ if (year < 57)
+ year = year + 2000;
+ else
+ year = year + 1900;
+
+ return (PLib.Julian_Date_of_Year(year) + day);
+ },
+
+ Delta_ET: function(year)
+ {
+ var delta_et = 0.0;
+
+ delta_et = 26.465 + 0.747622 * (year - 1950) + 1.886913 * Math.sin(PLib.twopi * (year - 1975) / 33);
+
+ return delta_et;
+ },
+
+ ThetaG: function(epoch, deep_arg)
+ {
+ var year = 0.0, day = 0.0, UT = 0.0, jd = 0.0, TU = 0.0, GMST = 0.0, ThetaG = 0.0;
+
+ year = parseInt(epoch * 1E-3);
+ day = ((epoch * 1E-3) - year) * 1E3;
+
+ if (year < 57)
+ year += 2000;
+ else
+ year += 1900;
+
+ UT = (day - parseInt(day));
+ day = parseInt(day);
+ jd = PLib.Julian_Date_of_Year(year) + day;
+ TU = (jd - 2451545.0) / 36525;
+ GMST = 24110.54841 + TU * (8640184.812866 + TU * (0.093104 - TU * 6.2E-6));
+ GMST = PLib.Modulus(GMST + PLib.secday * PLib.omega_E * UT, PLib.secday);
+ ThetaG = twopi * GMST / PLib.secday;
+ deep_arg.ds50 = jd - 2433281.5 + UT;
+ ThetaG = PLib.FMod2p(6.3003880987 * deep_arg.ds50 + 1.72944494);
+
+ return ThetaG;
+ },
+
+ ThetaG_JD: function(jd)
+ {
+ var UT = 0.0, TU = 0.0, GMST = 0.0;
+
+ UT = PLib.Frac(jd + 0.5);
+ jd = jd - UT;
+ TU = (jd - 2451545.0) / 36525;
+ GMST = 24110.54841 + TU * (8640184.812866 + TU * (0.093104 - TU * 6.2E-6));
+ GMST = PLib.Modulus(GMST + PLib.secday * PLib.omega_E * UT, PLib.secday);
+
+ return (PLib.twopi * GMST / PLib.secday);
+ },
+
+ Calculate_Solar_Position: function(time, solar_vector)
+ {
+ var mjd = 0.0, year = 0.0, T = 0.0, M = 0.0, L = 0.0, e = 0.0, C = 0.0, O = 0.0, Lsa = 0.0, nu = 0.0, R = 0.0, eps = 0.0;
+
+ mjd = time - 2415020.0;
+ year = 1900 + mjd / 365.25;
+ T = (mjd + PLib.Delta_ET(year) / PLib.secday) / 36525.0;
+ M = PLib.Radians(PLib.Modulus(358.47583 + PLib.Modulus(35999.04975 * T, 360.0) - (0.000150 + 0.0000033 * T) * PLib.Sqr(T), 360.0));
+ L = PLib.Radians(PLib.Modulus(279.69668 + PLib.Modulus(36000.76892 * T, 360.0) + 0.0003025 * PLib.Sqr(T),360.0));
+ e = 0.01675104 - (0.0000418 + 0.000000126 * T) * T;
+ C = PLib.Radians((1.919460 - (0.004789 + 0.000014 * T) * T) * Math.sin(M) + (0.020094 - 0.000100 * T) * Math.sin(2 * M) + 0.000293 * Math.sin(3 * M));
+ O = PLib.Radians(PLib.Modulus(259.18-1934.142 * T, 360.0));
+ Lsa = PLib.Modulus(L + C - PLib.Radians(0.00569-0.00479 * Math.sin(O)), PLib.twopi);
+ nu = PLib.Modulus(M + C, PLib.twopi);
+ R = 1.0000002 * (1.0 - PLib.Sqr(e)) / (1.0 + e * Math.cos(nu));
+ eps = PLib.Radians(23.452294 - (0.0130125 + (0.00000164 - 0.000000503 * T) * T) * T + 0.00256 * Math.cos(O));
+ R = PLib.AU * R;
+ solar_vector.x = R * Math.cos(Lsa);
+ solar_vector.y = R * Math.sin(Lsa) * Math.cos(eps);
+ solar_vector.z = R * Math.sin(Lsa) * Math.sin(eps);
+ solar_vector.w = R;
+ },
+
+ Sat_Eclipsed: function(pos, sol)
+ {
+ var sd_sun = 0.0, sd_earth = 0.0, delta = 0.0;
+ var Rho = new PLib.vector_t();
+ var earth = new PLib.vector_t();;
+
+ sd_earth = Math.asin(PLib.xkmper / pos.w);
+ PLib.Vec_Sub(sol, pos, Rho);
+ sd_sun = Math.asin(PLib.sr / Rho.w);
+ PLib.Scalar_Multiply(-1, pos, earth);
+ delta = PLib.Angle(sol, earth);
+ PLib.eclipse_depth = sd_earth - sd_sun - delta;
+
+ if (sd_earth < sd_sun)
+ return 0;
+ else
+ if (PLib.eclipse_depth >= 0)
+ return 1;
+ else
+ return 0;
+ },
+
+ select_ephemeris: function(tle)
+ {
+ var ao = 0.0, xnodp = 0.0, dd1 = 0.0, dd2 = 0.0, delo = 0.0, temp = 0.0, a1 = 0.0, del1 = 0.0, r1 = 0.0;
+
+ tle.xnodeo *= PLib.deg2rad;
+ tle.omegao *= PLib.deg2rad;
+ tle.xmo *= PLib.deg2rad;
+ tle.xincl *= PLib.deg2rad;
+ temp = PLib.twopi / PLib.xmnpda / PLib.xmnpda;
+ tle.xno = tle.xno * temp * PLib.xmnpda;
+ tle.xndt2o *= temp;
+ tle.xndd6o = tle.xndd6o * temp / PLib.xmnpda;
+ tle.bstar /= PLib.ae;
+
+ dd1 = (PLib.xke / tle.xno);
+ dd2 = PLib.tothrd;
+ a1 = Math.pow(dd1, dd2);
+ r1 = Math.cos(tle.xincl);
+ dd1 = (1.0 - tle.eo * tle.eo);
+ temp = PLib.ck2 * 1.5 * (r1 * r1 * 3.0 - 1.0) / Math.pow(dd1, 1.5);
+ del1 = temp / (a1 * a1);
+ ao = a1 * (1.0 - del1 * (PLib.tothrd * 0.5 + del1 * (del1 * 1.654320987654321 + 1.0)));
+ delo = temp / (ao * ao);
+ xnodp = tle.xno / (delo + 1.0);
+
+ if (PLib.twopi / PLib.xnodp / PLib.xmnpda >= 0.15625)
+ PLib.SetFlag(PLib.DEEP_SPACE_EPHEM_FLAG);
+ else
+ PLib.ClearFlag(PLib.DEEP_SPACE_EPHEM_FLAG);
+ },
+
+ SGP4: function(tsince, tle, pos, vel)
+ {
+ var cosuk = 0.0, sinuk = 0.0, rfdotk = 0.0, vx = 0.0, vy = 0.0, vz = 0.0, ux = 0.0, uy = 0.0, uz = 0.0, xmy = 0.0, xmx = 0.0, cosnok = 0.0,
+ sinnok = 0.0, cosik = 0.0, sinik = 0.0, rdotk = 0.0, xinck = 0.0, xnodek = 0.0, uk = 0.0, rk = 0.0, cos2u = 0.0, sin2u = 0.0,
+ u = 0.0, sinu = 0.0, cosu = 0.0, betal = 0.0, rfdot = 0.0, rdot = 0.0, r = 0.0, pl = 0.0, elsq = 0.0, esine = 0.0, ecose = 0.0, epw = 0.0,
+ cosepw = 0.0, x1m5th = 0.0, xhdot1 = 0.0, tfour = 0.0, sinepw = 0.0, capu = 0.0, ayn = 0.0, xlt = 0.0, aynl = 0.0, xll = 0.0,
+ axn = 0.0, xn = 0.0, beta = 0.0, xl = 0.0, e = 0.0, a = 0.0, tcube = 0.0, delm = 0.0, delomg = 0.0, templ = 0.0, tempe = 0.0, tempa = 0.0,
+ xnode = 0.0, tsq = 0.0, xmp = 0.0, omega = 0.0, xnoddf = 0.0, omgadf = 0.0, xmdf = 0.0, a1 = 0.0, a3ovk2 = 0.0, ao = 0.0,
+ betao = 0.0, betao2 = 0.0, c1sq = 0.0, c2 = 0.0, c3 = 0.0, coef = 0.0, coef1 = 0.0, del1 = 0.0, delo = 0.0, eeta = 0.0, eosq = 0.0,
+ etasq = 0.0, perigee = 0.0, pinvsq = 0.0, psisq = 0.0, qoms24 = 0.0, s4 = 0.0, temp = 0.0, temp1 = 0.0, temp2 = 0.0,
+ temp3 = 0.0, temp4 = 0.0, temp5 = 0.0, temp6 = 0.0, theta2 = 0.0, theta4 = 0.0, tsi = 0.0;
+
+ var i = 0;
+
+ if (PLib.isFlagClear(PLib.SGP4_INITIALIZED_FLAG))
+ {
+ PLib.SetFlag(PLib.SGP4_INITIALIZED_FLAG);
+
+ a1 = Math.pow(PLib.xke / tle.xno, PLib.tothrd);
+ PLib.SGP4.cosio = Math.cos(tle.xincl);
+ theta2 = PLib.SGP4.cosio * PLib.SGP4.cosio;
+ PLib.SGP4.x3thm1 = 3 * theta2 - 1.0;
+ eosq = tle.eo * tle.eo;
+ betao2 = 1.0 - eosq;
+ betao = Math.sqrt(betao2);
+ del1 = 1.5 * PLib.ck2 * PLib.SGP4.x3thm1 / (a1 * a1 * betao * betao2);
+ ao = a1 * (1.0 - del1 * (0.5 * PLib.tothrd + del1 * (1.0 + 134.0 / 81.0 * del1)));
+ delo = 1.5 * PLib.ck2 * PLib.SGP4.x3thm1 / (ao * ao * betao * betao2);
+ PLib.SGP4.xnodp = tle.xno / (1.0 + delo);
+ PLib.SGP4.aodp = ao / (1.0 - delo);
+
+ if ((PLib.SGP4.aodp * (1 - tle.eo) / PLib.ae) < (220 / PLib.xkmper + PLib.ae))
+ PLib.SetFlag(PLib.SIMPLE_FLAG);
+ else
+ PLib.ClearFlag(PLib.SIMPLE_FLAG);
+
+ s4 = PLib.s;
+ PLib.qoms24 = PLib.qoms2t;
+ PLib.perigee = (PLib.SGP4.aodp * (1 - tle.eo) - PLib.ae) * PLib.xkmper;
+
+ if (PLib.perigee < 156.0)
+ {
+ if (PLib.perigee <= 98.0)
+ s4 = 20;
+ else
+ s4 = PLib.perigee - 78.0;
+
+ PLib.qoms24 = Math.pow((120 - s4) * PLib.ae / PLib.xkmper, 4);
+ s4 = s4 / PLib.xkmper + PLib.ae;
+ }
+
+ pinvsq = 1 / (PLib.SGP4.aodp * PLib.SGP4.aodp * betao2 * betao2);
+ tsi = 1 / (PLib.SGP4.aodp - s4);
+ PLib.SGP4.eta = PLib.SGP4.aodp * tle.eo * tsi;
+ etasq = PLib.SGP4.eta * PLib.SGP4.eta;
+ eeta = tle.eo * PLib.SGP4.eta;
+ psisq = Math.abs(1 - etasq);
+ coef = qoms24 * Math.pow(tsi, 4);
+ coef1 = coef / Math.pow(psisq, 3.5);
+ c2 = coef1 * PLib.SGP4.xnodp * (PLib.SGP4.aodp * (1 + 1.5 * etasq + eeta * (4 + etasq)) + 0.75 * PLib.ck2 * tsi / psisq * PLib.SGP4.x3thm1 * (8 + 3 * etasq * (8 + etasq)));
+ PLib.SGP4.c1 = tle.bstar * c2;
+ PLib.SGP4.sinio = Math.sin(tle.xincl);
+ a3ovk2 = -PLib.xj3 / PLib.ck2 * Math.pow(PLib.ae, 3);
+ c3 = coef * tsi * a3ovk2 * PLib.SGP4.xnodp * PLib.ae * PLib.SGP4.sinio / tle.eo;
+ PLib.SGP4.x1mth2 = 1 - theta2;
+
+ PLib.SGP4.c4 = 2 * PLib.SGP4.xnodp * coef1 * PLib.SGP4.aodp * betao2 * (PLib.SGP4.eta * (2 + 0.5 * etasq)+tle.eo * (0.5 + 2 * etasq) - 2 * PLib.ck2 * tsi / (PLib.SGP4.aodp * psisq) * (-3 * PLib.SGP4.x3thm1 * (1 - 2 * eeta + etasq * (1.5 - 0.5 * eeta)) + 0.75 * PLib.SGP4.x1mth2 * (2 * etasq-eeta * (1 + etasq)) * Math.cos(2 * tle.omegao)));
+ PLib.SGP4.c5 = 2 * coef1 * PLib.SGP4.aodp * betao2 * (1 + 2.75 * (etasq + eeta) + eeta * etasq);
+
+ theta4 = theta2 * theta2;
+ temp1 = 3 * PLib.ck2 * pinvsq * PLib.SGP4.xnodp;
+ temp2 = temp1 * PLib.ck2 * pinvsq;
+ temp3 = 1.25 * PLib.ck4 * pinvsq * pinvsq * PLib.SGP4.xnodp;
+ PLib.SGP4.xmdot = PLib.SGP4.xnodp + 0.5 * temp1 * betao * PLib.SGP4.x3thm1 + 0.0625 * temp2 * betao * (13 - 78 * theta2 + 137 * theta4);
+ x1m5th = 1 - 5 * theta2;
+ PLib.SGP4.omgdot = -0.5 * temp1 * x1m5th + 0.0625 * temp2 * (7 - 114 * theta2 + 395 * theta4) + temp3 * (3 - 36 * theta2 + 49 * theta4);
+ xhdot1 = -temp1 * PLib.SGP4.cosio;
+ PLib.SGP4.xnodot = xhdot1 + (0.5 * temp2 * (4 - 19 * theta2) + 2 * temp3 * (3 - 7 * theta2)) * PLib.SGP4.cosio;
+ PLib.SGP4.omgcof = tle.bstar * c3 * Math.cos(tle.omegao);
+ PLib.SGP4.xmcof = -PLib.tothrd * coef * tle.bstar * PLib.ae / eeta;
+ PLib.SGP4.xnodcf = 3.5 * betao2 * xhdot1 * PLib.SGP4.c1;
+ PLib.SGP4.t2cof = 1.5 * PLib.SGP4.c1;
+ PLib.SGP4.xlcof = 0.125 * a3ovk2 * PLib.SGP4.sinio * (3 + 5 * PLib.SGP4.cosio) / (1 + PLib.SGP4.cosio);
+ PLib.SGP4.aycof = 0.25 * a3ovk2 * PLib.SGP4.sinio;
+ PLib.SGP4.delmo = Math.pow(1 + PLib.SGP4.eta * Math.cos(tle.xmo), 3);
+ PLib.SGP4.sinmo = Math.sin(tle.xmo);
+ PLib.SGP4.x7thm1 = 7 * theta2 - 1;
+
+ if (PLib.isFlagClear(PLib.SIMPLE_FLAG))
+ {
+ c1sq = PLib.SGP4.c1 * PLib.SGP4.c1;
+ PLib.SGP4.d2 = 4 * PLib.SGP4.aodp * tsi * c1sq;
+ temp = PLib.SGP4.d2 * tsi * PLib.SGP4.c1/3;
+ PLib.SGP4.d3 = (17 * PLib.SGP4.aodp + s4) * temp;
+ PLib.SGP4.d4 = 0.5 * temp * PLib.SGP4.aodp * tsi * (221 * PLib.SGP4.aodp + 31 * s4) * PLib.SGP4.c1;
+ PLib.SGP4.t3cof = PLib.SGP4.d2 + 2 * c1sq;
+ PLib.SGP4.t4cof = 0.25 * (3 * PLib.SGP4.d3 + PLib.SGP4.c1 * (12 * PLib.SGP4.d2 + 10 * c1sq));
+ PLib.SGP4.t5cof = 0.2 * (3 * PLib.SGP4.d4 + 12 * PLib.SGP4.c1 * PLib.SGP4.d3 + 6 * PLib.SGP4.d2 * PLib.SGP4.d2 + 15 * c1sq * (2 * PLib.SGP4.d2 + c1sq));
+ }
+ }
+
+ xmdf = tle.xmo + PLib.SGP4.xmdot * tsince;
+ omgadf = tle.omegao + PLib.SGP4.omgdot * tsince;
+ xnoddf = tle.xnodeo + PLib.SGP4.xnodot * tsince;
+ omega = omgadf;
+ xmp = xmdf;
+ tsq = tsince * tsince;
+ xnode = xnoddf + PLib.SGP4.xnodcf * tsq;
+ tempa = 1 - PLib.SGP4.c1 * tsince;
+ tempe = tle.bstar * PLib.SGP4.c4 * tsince;
+ templ = PLib.SGP4.t2cof * tsq;
+
+ if (PLib.isFlagClear(PLib.SIMPLE_FLAG))
+ {
+ delomg = PLib.SGP4.omgcof * tsince;
+ delm = PLib.SGP4.xmcof * (Math.pow(1 + PLib.SGP4.eta * Math.cos(xmdf), 3) - PLib.SGP4.delmo);
+ temp = delomg + delm;
+ xmp = xmdf + temp;
+ omega = omgadf - temp;
+ tcube = tsq * tsince;
+ tfour = tsince * tcube;
+ tempa = tempa - PLib.SGP4.d2 * tsq - PLib.SGP4.d3 * tcube - PLib.SGP4.d4 * tfour;
+ tempe = tempe + tle.bstar * PLib.SGP4.c5 * (Math.sin(xmp) - PLib.SGP4.sinmo);
+ templ = templ + PLib.SGP4.t3cof * tcube + tfour * (PLib.SGP4.t4cof + tsince * PLib.SGP4.t5cof);
+ }
+
+ a = PLib.SGP4.aodp * Math.pow(tempa, 2);
+ e = tle.eo - tempe;
+ xl = xmp + omega + xnode + PLib.SGP4.xnodp * templ;
+ beta = Math.sqrt(1 - e * e);
+ xn = PLib.xke / Math.pow(a, 1.5);
+
+ axn = e * Math.cos(omega);
+ temp = 1 / (a * beta * beta);
+ xll = temp * PLib.SGP4.xlcof * axn;
+ aynl = temp * PLib.SGP4.aycof;
+ xlt = xl + xll;
+ ayn = e * Math.sin(omega) + aynl;
+
+ capu = PLib.FMod2p(xlt - xnode);
+ temp2 = capu;
+ i = 0;
+
+ do
+ {
+ sinepw = Math.sin(temp2);
+ cosepw = Math.cos(temp2);
+ temp3 = axn * sinepw;
+ temp4 = ayn * cosepw;
+ temp5 = axn * cosepw;
+ temp6 = ayn * sinepw;
+ epw = (capu - temp4 + temp3 - temp2) / (1 - temp5 - temp6) + temp2;
+
+ if (Math.abs(epw - temp2) <= PLib.e6a)
+ break;
+
+ temp2 = epw;
+ } while (i++ < 10);
+
+ ecose = temp5 + temp6;
+ esine = temp3 - temp4;
+ elsq = axn * axn + ayn * ayn;
+ temp = 1 - elsq;
+ pl = a * temp;
+ r = a * (1 - ecose);
+ temp1 = 1 / r;
+ rdot = PLib.xke * Math.sqrt(a) * esine * temp1;
+ rfdot = PLib.xke * Math.sqrt(pl) * temp1;
+ temp2 = a * temp1;
+ betal = Math.sqrt(temp);
+ temp3 = 1 / (1 + betal);
+ cosu = temp2 * (cosepw - axn + ayn * esine * temp3);
+ sinu = temp2 * (sinepw - ayn - axn * esine * temp3);
+ u = Math.atan2(sinu, cosu);
+ sin2u = 2 * sinu * cosu;
+ cos2u = 2 * cosu * cosu - 1;
+ temp = 1 / pl;
+ temp1 = PLib.ck2 * temp;
+ temp2 = temp1 * temp;
+
+ rk = r * (1 - 1.5 * temp2 * betal * PLib.SGP4.x3thm1) + 0.5 * temp1 * PLib.SGP4.x1mth2 * cos2u;
+ uk = u - 0.25 * temp2 * PLib.SGP4.x7thm1 * sin2u;
+ xnodek = xnode + 1.5 * temp2 * PLib.SGP4.cosio * sin2u;
+ xinck = tle.xincl + 1.5 * temp2 * PLib.SGP4.cosio * PLib.SGP4.sinio * cos2u;
+ rdotk = rdot - xn * temp1 * PLib.SGP4.x1mth2 * sin2u;
+ rfdotk = rfdot + xn * temp1 * (PLib.SGP4.x1mth2 * cos2u + 1.5 * PLib.SGP4.x3thm1);
+
+ sinuk = Math.sin(uk);
+ cosuk = Math.cos(uk);
+ sinik = Math.sin(xinck);
+ cosik = Math.cos(xinck);
+ sinnok = Math.sin(xnodek);
+ cosnok = Math.cos(xnodek);
+ xmx = -sinnok * cosik;
+ xmy = cosnok * cosik;
+ ux = xmx * sinuk+cosnok * cosuk;
+ uy = xmy * sinuk+sinnok * cosuk;
+ uz = sinik * sinuk;
+ vx = xmx * cosuk-cosnok * sinuk;
+ vy = xmy * cosuk-sinnok * sinuk;
+ vz = sinik * cosuk;
+
+ pos.x = rk * ux;
+ pos.y = rk * uy;
+ pos.z = rk * uz;
+ vel.x = rdotk * ux + rfdotk * vx;
+ vel.y = rdotk * uy + rfdotk * vy;
+ vel.z = rdotk * uz + rfdotk * vz;
+
+ PLib.phase = xlt - xnode - omgadf + PLib.twopi;
+
+ if (PLib.phase < 0.0)
+ PLib.phase += PLib.twopi;
+
+ PLib.phase = PLib.FMod2p(PLib.phase);
+ },
+
+ Deep: function(ientry, tle, deep_arg)
+ {
+ var a1 = 0.0, a2 = 0.0, a3 = 0.0, a4 = 0.0, a5 = 0.0, a6 = 0.0, a7 = 0.0, a8 = 0.0, a9 = 0.0, a10 = 0.0, ainv2 = 0.0, alfdp = 0.0, aqnv = 0.0,
+ sgh = 0.0, sini2 = 0.0, sinis = 0.0, sinok = 0.0, sh = 0.0, si = 0.0, sil = 0.0, day = 0.0, betdp = 0.0, dalf = 0.0, bfact = 0.0, c = 0.0,
+ cc = 0.0, cosis = 0.0, cosok = 0.0, cosq = 0.0, ctem = 0.0, f322 = 0.0, zx = 0.0, zy = 0.0, dbet = 0.0, dls = 0.0, eoc = 0.0, eq = 0.0, f2 = 0.0,
+ f220 = 0.0, f221 = 0.0, f3 = 0.0, f311 = 0.0, f321 = 0.0, xnoh = 0.0, f330 = 0.0, f441 = 0.0, f442 = 0.0, f522 = 0.0, f523 = 0.0,
+ f542 = 0.0, f543 = 0.0, g200 = 0.0, g201 = 0.0, g211 = 0.0, pgh = 0.0, ph = 0.0, s1 = 0.0, s2 = 0.0, s3 = 0.0, s4 = 0.0, s5 = 0.0, s6 = 0.0, s7 = 0.0,
+ se = 0.0, sel = 0.0, ses = 0.0, xls = 0.0, g300 = 0.0, g310 = 0.0, g322 = 0.0, g410 = 0.0, g422 = 0.0, g520 = 0.0, g521 = 0.0, g532 = 0.0,
+ g533 = 0.0, gam = 0.0, sinq = 0.0, sinzf = 0.0, sis = 0.0, sl = 0.0, sll = 0.0, sls = 0.0, stem = 0.0, temp = 0.0, temp1 = 0.0, x1 = 0.0,
+ x2 = 0.0, x2li = 0.0, x2omi = 0.0, x3 = 0.0, x4 = 0.0, x5 = 0.0, x6 = 0.0, x7 = 0.0, x8 = 0.0, xl = 0.0, xldot = 0.0, xmao = 0.0, xnddt = 0.0,
+ xndot = 0.0, xno2 = 0.0, xnodce = 0.0, xnoi = 0.0, xomi = 0.0, xpidot = 0.0, z1 = 0.0, z11 = 0.0, z12 = 0.0, z13 = 0.0, z2 = 0.0,
+ z21 = 0.0, z22 = 0.0, z23 = 0.0, z3 = 0.0, z31 = 0.0, z32 = 0.0, z33 = 0.0, ze = 0.0, zf = 0.0, zm = 0.0, zmo = 0.0, zn = 0.0, zsing = 0.0,
+ zsinh = 0.0, zsini = 0.0, zcosg = 0.0, zcosh = 0.0, zcosi = 0.0, delt = 0.0, ft = 0.0;
+
+ switch (ientry)
+ {
+ case dpinit:
+ PLib.Deep.thgr = PLib.ThetaG(tle.epoch, deep_arg);
+ eq = tle.eo;
+ PLib.Deep.xnq = deep_arg.xnodp;
+ aqnv = 1 / deep_arg.aodp;
+ PLib.Deep.xqncl = tle.xincl;
+ xmao = tle.xmo;
+ xpidot = deep_arg.omgdot + deep_arg.xnodot;
+ sinq = Math.sin(tle.xnodeo);
+ cosq = Math.cos(tle.xnodeo);
+ PLib.Deep.omegaq = tle.omegao;
+
+ day = deep_arg.ds50 + 18261.5;
+
+ if (day != PLib.Deep.preep)
+ {
+ PLib.Deep.preep = day;
+ xnodce = 4.5236020 - 9.2422029E-4 * day;
+ stem = Math.sin(xnodce);
+ ctem = Math.cos(xnodce);
+ PLib.Deep.zcosil = 0.91375164 - 0.03568096 * ctem;
+ PLib.Deep.zsinil = Math.sqrt(1 - PLib.Deep.zcosil * PLib.Deep.zcosil);
+ PLib.Deep.zsinhl = 0.089683511 * stem / PLib.Deep.zsinil;
+ PLib.Deep.zcoshl = Math.sqrt(1 - PLib.Deep.zsinhl * PLib.Deep.zsinhl);
+ c = 4.7199672 + 0.22997150 * day;
+ gam = 5.8351514 + 0.0019443680 * day;
+ PLib.Deep.zmol = PLib.FMod2p(c - gam);
+ zx = 0.39785416 * stem / PLib.Deep.zsinil;
+ zy = PLib.Deep.zcoshl * ctem + 0.91744867 * PLib.Deep.zsinhl * stem;
+ zx = Math.atan2(zx, zy);
+ zx = gam + zx - xnodce;
+ PLib.Deep.zcosgl = Math.cos(zx);
+ PLib.Deep.zsingl = Math.sin(zx);
+ PLib.Deep.zmos = 6.2565837 + 0.017201977 * day;
+ PLib.Deep.zmos = PLib.FMod2p(PLib.Deep.zmos);
+ }
+
+ PLib.Deep.savtsn = 1E20;
+ zcosg = PLib.zcosgs;
+ zsing = PLib.zsings;
+ zcosi = PLib.zcosis;
+ zsini = PLib.zsinis;
+ zcosh = cosq;
+ zsinh = sinq;
+ cc = PLib.c1ss;
+ zn = PLib.zns;
+ ze = PLib.zes;
+ zmo = PLib.Deep.zmos;
+ xnoi = 1 / PLib.Deep.xnq;
+
+ for (;;)
+ {
+ a1 = zcosg * zcosh + zsing * zcosi * zsinh;
+ a3 = -zsing * zcosh + zcosg * zcosi * zsinh;
+ a7 = -zcosg * zsinh + zsing * zcosi * zcosh;
+ a8 = zsing * zsini;
+ a9 = zsing * zsinh + zcosg * zcosi * zcosh;
+ a10 = zcosg * zsini;
+ a2 = deep_arg.cosio * a7 + deep_arg.sinio * a8;
+ a4 = deep_arg.cosio * a9 + deep_arg.sinio * a10;
+ a5 = -deep_arg.sinio * a7 + deep_arg.cosio * a8;
+ a6 = -deep_arg.sinio * a9 + deep_arg.cosio * a10;
+ x1 = a1 * deep_arg.cosg + a2 * deep_arg.sing;
+ x2 = a3 * deep_arg.cosg + a4 * deep_arg.sing;
+ x3 = -a1 * deep_arg.sing + a2 * deep_arg.cosg;
+ x4 = -a3 * deep_arg.sing + a4 * deep_arg.cosg;
+ x5 = a5 * deep_arg.sing;
+ x6 = a6 * deep_arg.sing;
+ x7 = a5 * deep_arg.cosg;
+ x8 = a6 * deep_arg.cosg;
+ z31 = 12 * x1 * x1 - 3 * x3 * x3;
+ z32 = 24 * x1 * x2 - 6 * x3 * x4;
+ z33 = 12 * x2 * x2 - 3 * x4 * x4;
+ z1 = 3 * (a1 * a1 + a2 * a2) + z31 * deep_arg.eosq;
+ z2 = 6 * (a1 * a3 + a2 * a4) + z32 * deep_arg.eosq;
+ z3 = 3 * (a3 * a3 + a4 * a4) + z33 * deep_arg.eosq;
+ z11 = -6 * a1 * a5 + deep_arg.eosq * (-24 * x1 * x7 - 6 * x3 * x5);
+ z12 = -6 * (a1 * a6 + a3 * a5) + deep_arg.eosq * (-24 * (x2 * x7 + x1 * x8) - 6 * (x3 * x6 + x4 * x5));
+ z13 = -6 * a3 * a6 + deep_arg.eosq * (-24 * x2 * x8 - 6 * x4 * x6);
+ z21 = 6 * a2 * a5 + deep_arg.eosq * (24 * x1 * x5 - 6 * x3 * x7);
+ z22 = 6 * (a4 * a5 + a2 * a6) + deep_arg.eosq * (24 * (x2 * x5 + x1 * x6) - 6 * (x4 * x7 + x3 * x8));
+ z23 = 6 * a4 * a6 + deep_arg.eosq * (24 * x2 * x6 - 6 * x4 * x8);
+ z1 = z1 + z1 + deep_arg.betao2 * z31;
+ z2 = z2 + z2 + deep_arg.betao2 * z32;
+ z3 = z3 + z3 + deep_arg.betao2 * z33;
+ s3 = cc * xnoi;
+ s2 = -0.5 * s3 / deep_arg.betao;
+ s4 = s3 * deep_arg.betao;
+ s1 = -15 * eq * s4;
+ s5 = x1 * x3 + x2 * x4;
+ s6 = x2 * x3 + x1 * x4;
+ s7 = x2 * x4 - x1 * x3;
+ se = s1 * zn * s5;
+ si = s2 * zn * (z11 + z13);
+ sl = -zn * s3 * (z1 + z3 - 14 - 6 * deep_arg.eosq);
+ sgh = s4 * zn * (z31 + z33 - 6);
+ sh = -zn * s2 * (z21 + z23);
+
+ if (PLib.Deep.xqncl < 5.2359877E-2)
+ sh = 0;
+
+ PLib.Deep.ee2 = 2 * s1 * s6;
+ PLib.Deep.e3 = 2 * s1 * s7;
+ PLib.Deep.xi2 = 2 * s2 * z12;
+ PLib.Deep.xi3 = 2 * s2 * (z13 - z11);
+ PLib.Deep.xl2 = -2 * s3 * z2;
+ PLib.Deep.xl3 = -2 * s3 * (z3 - z1);
+ PLib.Deep.xl4 = -2 * s3 * (-21 - 9 * deep_arg.eosq) * ze;
+ PLib.Deep.xgh2 = 2 * s4 * z32;
+ PLib.Deep.xgh3 = 2 * s4 * (z33 - z31);
+ PLib.Deep.xgh4 = -18 * s4 * ze;
+ PLib.Deep.xh2 = -2 * s2 * z22;
+ PLib.Deep.xh3 = -2 * s2 * (z23 - z21);
+
+ if (PLib.isFlagSet(PLib.LUNAR_TERMS_DONE_FLAG))
+ break;
+
+ PLib.Deep.sse = se;
+ PLib.Deep.ssi = si;
+ PLib.Deep.ssl = sl;
+ PLib.Deep.ssh = sh / deep_arg.sinio;
+ PLib.Deep.ssg = sgh - deep_arg.cosio * PLib.Deep.ssh;
+ PLib.Deep.se2 = PLib.Deep.ee2;
+ PLib.Deep.si2 = PLib.Deep.xi2;
+ PLib.Deep.sl2 = PLib.Deep.xl2;
+ PLib.Deep.sgh2 = PLib.Deep.xgh2;
+ PLib.Deep.sh2 = PLib.Deep.xh2;
+ PLib.Deep.se3 = PLib.Deep.e3;
+ PLib.Deep.si3 = PLib.Deep.xi3;
+ PLib.Deep.sl3 = PLib.Deep.xl3;
+ PLib.Deep.sgh3 = PLib.Deep.xgh3;
+ PLib.Deep.sh3 = PLib.Deep.xh3;
+ PLib.Deep.sl4 = PLib.Deep.xl4;
+ PLib.Deep.sgh4 = PLib.Deep.xgh4;
+ zcosg = PLib.Deep.zcosgl;
+ zsing = PLib.Deep.zsingl;
+ zcosi = PLib.Deep.zcosil;
+ zsini = PLib.Deep.zsinil;
+ zcosh = PLib.Deep.zcoshl * cosq + PLib.Deep.zsinhl * sinq;
+ zsinh = sinq * PLib.Deep.zcoshl - cosq * PLib.Deep.zsinhl;
+ zn = PLib.znl;
+ cc = PLib.c1l;
+ ze = PLib.zel;
+ zmo = PLib.Deep.zmol;
+ PLib.SetFlag(PLib.LUNAR_TERMS_DONE_FLAG);
+ }
+
+ PLib.Deep.sse = PLib.Deep.sse + se;
+ PLib.Deep.ssi = PLib.Deep.ssi + si;
+ PLib.Deep.ssl = PLib.Deep.ssl + sl;
+ PLib.Deep.ssg = PLib.Deep.ssg + sgh - deep_arg.cosio / deep_arg.sinio * sh;
+ PLib.Deep.ssh = PLib.Deep.ssh + sh / deep_arg.sinio;
+
+ PLib.ClearFlag(PLib.RESONANCE_FLAG);
+ PLib.ClearFlag(PLib.SYNCHRONOUS_FLAG);
+
+ if (!((PLib.Deep.xnq < 0.0052359877) && (PLib.Deep.xnq > 0.0034906585)))
+ {
+ if ((PLib.Deep.xnq < 0.00826) || (PLib.Deep.xnq > 0.00924))
+ return;
+
+ if (eq < 0.5)
+ return;
+
+ PLib.SetFlag(PLib.RESONANCE_FLAG);
+ eoc = eq * deep_arg.eosq;
+ g201 = -0.306 - (eq - 0.64) * 0.440;
+
+ if (eq <= 0.65)
+ {
+ g211 = 3.616 - 13.247 * eq + 16.290 * deep_arg.eosq;
+ g310 = -19.302 + 117.390 * eq - 228.419 * deep_arg.eosq + 156.591 * eoc;
+ g322 = -18.9068 + 109.7927 * eq - 214.6334 * deep_arg.eosq + 146.5816 * eoc;
+ g410 = -41.122 + 242.694 * eq - 471.094 * deep_arg.eosq + 313.953 * eoc;
+ g422 = -146.407 + 841.880 * eq - 1629.014 * deep_arg.eosq + 1083.435 * eoc;
+ g520 = -532.114 + 3017.977 * eq - 5740 * deep_arg.eosq + 3708.276 * eoc;
+ }
+
+ else
+ {
+ g211 = -72.099 + 331.819 * eq - 508.738 * deep_arg.eosq + 266.724 * eoc;
+ g310 = -346.844 + 1582.851 * eq - 2415.925 * deep_arg.eosq + 1246.113 * eoc;
+ g322 = -342.585 + 1554.908 * eq - 2366.899 * deep_arg.eosq + 1215.972 * eoc;
+ g410 = -1052.797 + 4758.686 * eq - 7193.992 * deep_arg.eosq + 3651.957 * eoc;
+ g422 = -3581.69 + 16178.11 * eq - 24462.77 * deep_arg.eosq + 12422.52 * eoc;
+
+ if (eq <= 0.715)
+ g520 = 1464.74 - 4664.75 * eq + 3763.64 * deep_arg.eosq;
+
+ else
+ g520 = -5149.66 + 29936.92 * eq - 54087.36 * deep_arg.eosq + 31324.56 * eoc;
+ }
+
+ if (eq < 0.7)
+ {
+ g533 = -919.2277 + 4988.61 * eq - 9064.77 * deep_arg.eosq + 5542.21 * eoc;
+ g521 = -822.71072 + 4568.6173 * eq - 8491.4146 * deep_arg.eosq + 5337.524 * eoc;
+ g532 = -853.666 + 4690.25 * eq - 8624.77 * deep_arg.eosq + 5341.4 * eoc;
+ }
+
+ else
+ {
+ g533 = -37995.78 + 161616.52 * eq - 229838.2 * deep_arg.eosq + 109377.94 * eoc;
+ g521 = -51752.104 + 218913.95 * eq - 309468.16 * deep_arg.eosq + 146349.42 * eoc;
+ g532 = -40023.88 + 170470.89 * eq - 242699.48 * deep_arg.eosq + 115605.82 * eoc;
+ }
+
+ sini2 = deep_arg.sinio * deep_arg.sinio;
+ f220 = 0.75 * (1 + 2 * deep_arg.cosio + deep_arg.theta2);
+ f221 = 1.5 * sini2;
+ f321 = 1.875 * deep_arg.sinio * (1 - 2 * deep_arg.cosio - 3 * deep_arg.theta2);
+ f322 = -1.875 * deep_arg.sinio * (1 + 2 * deep_arg.cosio - 3 * deep_arg.theta2);
+ f441 = 35 * sini2 * f220;
+ f442 = 39.3750 * sini2 * sini2;
+ f522 = 9.84375 * deep_arg.sinio * (sini2 * (1 - 2 * deep_arg.cosio - 5 * deep_arg.theta2) + 0.33333333 * (-2 + 4 * deep_arg.cosio + 6 * deep_arg.theta2));
+ f523 = deep_arg.sinio * (4.92187512 * sini2 * (-2 - 4 * deep_arg.cosio + 10 * deep_arg.theta2) + 6.56250012 * (1 + 2 * deep_arg.cosio-3 * deep_arg.theta2));
+ f542 = 29.53125 * deep_arg.sinio * (2 - 8 * deep_arg.cosio + deep_arg.theta2 * (-12 + 8 * deep_arg.cosio+10 * deep_arg.theta2));
+ f543 = 29.53125 * deep_arg.sinio * (-2 - 8 * deep_arg.cosio + deep_arg.theta2 * (12 + 8 * deep_arg.cosio-10 * deep_arg.theta2));
+ xno2 = PLib.Deep.xnq * PLib.Deep.xnq;
+ ainv2 = aqnv * aqnv;
+ temp1 = 3 * xno2 * ainv2;
+ temp = temp1 * PLib.root22;
+ PLib.Deep.d2201 = temp * f220 * g201;
+ PLib.Deep.d2211 = temp * f221 * g211;
+ temp1 = temp1 * aqnv;
+ temp = temp1 * PLib.root32;
+ PLib.Deep.d3210 = temp * f321 * g310;
+ PLib.Deep.d3222 = temp * f322 * g322;
+ temp1 = temp1 * aqnv;
+ temp = 2 * temp1 * PLib.root44;
+ PLib.Deep.d4410 = temp * f441 * g410;
+ PLib.Deep.d4422 = temp * f442 * g422;
+ temp1 = temp1 * aqnv;
+ temp = temp1 * PLib.root52;
+ PLib.Deep.d5220 = temp * f522 * g520;
+ PLib.Deep.d5232 = temp * f523 * g532;
+ temp = 2 * temp1 * PLib.root54;
+ PLib.Deep.d5421 = temp * f542 * g521;
+ PLib.Deep.d5433 = temp * f543 * g533;
+ PLib.Deep.xlamo = xmao + tle.xnodeo + tle.xnodeo - PLib.Deep.thgr - PLib.Deep.thgr;
+ bfact = deep_arg.xmdot + deep_arg.xnodot + deep_arg.xnodot - PLib.thdt - PLib.thdt;
+ bfact = bfact + PLib.Deep.ssl + PLib.Deep.ssh + PLib.Deep.ssh;
+ }
+
+ else
+ {
+ PLib.SetFlag(PLib.RESONANCE_FLAG);
+ PLib.SetFlag(PLib.SYNCHRONOUS_FLAG);
+
+ g200 = 1 + deep_arg.eosq * (-2.5 + 0.8125 * deep_arg.eosq);
+ g310 = 1 + 2 * deep_arg.eosq;
+ g300 = 1 + deep_arg.eosq * (-6 + 6.60937 * deep_arg.eosq);
+ f220 = 0.75 * (1 + deep_arg.cosio) * (1 + deep_arg.cosio);
+ f311 = 0.9375 * deep_arg.sinio * deep_arg.sinio * (1 + 3 * deep_arg.cosio) - 0.75 * (1 + deep_arg.cosio);
+ f330 = 1 + deep_arg.cosio;
+ f330 = 1.875 * f330 * f330 * f330;
+ PLib.Deep.del1 = 3 * PLib.Deep.xnq * PLib.Deep.xnq * aqnv * aqnv;
+ PLib.Deep.del2 = 2 * PLib.Deep.del1 * f220 * g200 * q22;
+ PLib.Deep.del3 = 3 * PLib.Deep.del1 * f330 * g300 * q33 * aqnv;
+ PLib.Deep.del1 = PLib.Deep.del1 * f311 * g310 * q31 * aqnv;
+ PLib.Deep.fasx2 = 0.13130908;
+ PLib.Deep.fasx4 = 2.8843198;
+ PLib.Deep.fasx6 = 0.37448087;
+ PLib.Deep.xlamo = xmao + tle.xnodeo + tle.omegao - PLib.Deep.thgr;
+ bfact = deep_arg.xmdot + xpidot - PLib.thdt;
+ bfact = bfact + PLib.Deep.ssl + PLib.Deep.ssg + PLib.Deep.ssh;
+ }
+
+ PLib.Deep.xfact = bfact - PLib.Deep.xnq;
+
+ PLib.Deep.xli = PLib.Deep.xlamo;
+ PLib.Deep.xni = PLib.Deep.xnq;
+ PLib.Deep.atime = 0;
+ PLib.Deep.stepp = 720;
+ PLib.Deep.stepn = -720;
+ PLib.Deep.step2 = 259200;
+
+ return;
+
+ case dpsec: /* Entrance for deep space secular effects */
+ deep_arg.xll = deep_arg.xll + PLib.Deep.ssl * deep_arg.t;
+ deep_arg.omgadf = deep_arg.omgadf + PLib.Deep.ssg * deep_arg.t;
+ deep_arg.xnode = deep_arg.xnode + PLib.Deep.ssh * deep_arg.t;
+ deep_arg.em = tle.eo + PLib.Deep.sse * deep_arg.t;
+ deep_arg.xinc = tle.xincl + PLib.Deep.ssi * deep_arg.t;
+
+ if (deep_arg.xinc < 0)
+ {
+ deep_arg.xinc = -deep_arg.xinc;
+ deep_arg.xnode = deep_arg.xnode + pi;
+ deep_arg.omgadf = deep_arg.omgadf - pi;
+ }
+
+ if (PLib.isFlagClear(PLib.RESONANCE_FLAG))
+ return;
+
+ do
+ {
+ if ((PLib.Deep.atime == 0) || ((deep_arg.t >= 0) && (PLib.Deep.atime < 0)) || ((deep_arg.t < 0) && (PLib.Deep.atime >= 0)))
+ {
+ if (deep_arg.t >= 0)
+ delt = PLib.Deep.stepp;
+ else
+ delt = PLib.Deep.stepn;
+
+ PLib.Deep.atime = 0;
+ PLib.Deep.xni = PLib.Deep.xnq;
+ PLib.Deep.xli = PLib.Deep.xlamo;
+ }
+
+ else
+ {
+ if (Math.abs(deep_arg.t) >= Math.abs(PLib.Deep.atime))
+ {
+ if (deep_arg.t > 0)
+ delt = PLib.Deep.stepp;
+ else
+ delt = PLib.Deep.stepn;
+ }
+ }
+
+ do
+ {
+ if (Math.abs(deep_arg.t - PLib.Deep.atime) >= PLib.Deep.stepp)
+ {
+ PLib.SetFlag(PLib.DO_LOOP_FLAG);
+ PLib.ClearFlag(PLib.EPOCH_RESTART_FLAG);
+ }
+
+ else
+ {
+ ft = deep_arg.t - PLib.Deep.atime;
+ PLib.ClearFlag(PLib.DO_LOOP_FLAG);
+ }
+
+ if (Math.abs(deep_arg.t) < Math.abs(PLib.Deep.atime))
+ {
+ if (deep_arg.t >= 0)
+ delt = PLib.Deep.stepn;
+ else
+ delt = PLib.Deep.stepp;
+
+ PLib.SetFlag(PLib.DO_LOOP_FLAG | PLib.EPOCH_RESTART_FLAG);
+ }
+
+ if (PLib.isFlagSet(PLib.SYNCHRONOUS_FLAG))
+ {
+ xndot = PLib.Deep.del1 * Math.sin(PLib.Deep.xli - PLib.Deep.fasx2) + PLib.Deep.del2 * Math.sin(2 * (PLib.Deep.xli - PLib.Deep.fasx4)) + PLib.Deep.del3 * Math.sin(3 * (PLib.Deep.xli - PLib.Deep.fasx6));
+ xnddt = PLib.Deep.del1 * Math.cos(PLib.Deep.xli - PLib.Deep.fasx2) + 2 * PLib.Deep.del2 * Math.cos(2 * (PLib.Deep.xli - PLib.Deep.fasx4)) + 3 * PLib.Deep.del3 * Math.cos(3 * (PLib.Deep.xli - PLib.Deep.fasx6));
+ }
+
+ else
+ {
+ xomi = PLib.Deep.omegaq + deep_arg.omgdot * PLib.Deep.atime;
+ x2omi = xomi + xomi;
+ x2li = PLib.Deep.xli + PLib.Deep.xli;
+ xndot = PLib.Deep.d2201 * Math.sin(x2omi + PLib.Deep.xli - g22) + PLib.Deep.d2211 * Math.sin(PLib.Deep.xli - g22) + PLib.Deep.d3210 * Math.sin(xomi + PLib.Deep.xli - g32) + PLib.Deep.d3222 * Math.sin(-xomi + PLib.Deep.xli - g32) + PLib.Deep.d4410 * sin(x2omi + x2li - g44) + PLib.Deep.d4422 * sin(x2li - g44) + PLib.Deep.d5220 * sin(xomi + PLib.Deep.xli - g52) + PLib.Deep.d5232 * sin(-xomi + PLib.Deep.xli - g52) + PLib.Deep.d5421 * sin(xomi + x2li - g54) + PLib.Deep.d5433 * sin(-xomi + x2li - g54);
+ xnddt = PLib.Deep.d2201 * Math.cos(x2omi + PLib.Deep.xli - g22) + PLib.Deep.d2211 * Math.cos(PLib.Deep.xli - g22) + PLib.Deep.d3210 * Math.cos(xomi + PLib.Deep.xli - g32) + PLib.Deep.d3222 * Math.cos(-xomi + PLib.Deep.xli - g32) + PLib.Deep.d5220 * cos(xomi + PLib.Deep.xli - g52) + PLib.Deep.d5232 * cos(-xomi + PLib.Deep.xli - g52) + 2 * (PLib.Deep.d4410 * cos(x2omi + x2li - g44) + PLib.Deep.d4422 * cos(x2li - g44) + PLib.Deep.d5421 * cos(xomi + x2li - g54) + PLib.Deep.d5433 * cos(-xomi + x2li - g54));
+ }
+
+ xldot = PLib.Deep.xni + PLib.Deep.xfact;
+ xnddt = xnddt * xldot;
+
+ if (PLib.isFlagSet(PLib.DO_LOOP_FLAG))
+ {
+ PLib.Deep.xli = PLib.Deep.xli + xldot * delt + xndot * PLib.Deep.step2;
+ PLib.Deep.xni = PLib.Deep.xni + xndot * delt + xnddt * PLib.Deep.step2;
+ PLib.Deep.atime = PLib.Deep.atime + delt;
+ }
+ } while (PLib.isFlagSet(PLib.DO_LOOP_FLAG) && PLib.isFlagClear(PLib.EPOCH_RESTART_FLAG));
+ } while (PLib.isFlagSet(PLib.DO_LOOP_FLAG) && PLib.isFlagSet(PLib.EPOCH_RESTART_FLAG));
+
+ deep_arg.xn = PLib.Deep.xni + xndot * ft + xnddt * ft * ft * 0.5;
+ xl = PLib.Deep.xli + xldot * ft + xndot * ft * ft * 0.5;
+ temp = -deep_arg.xnode + PLib.Deep.thgr + deep_arg.t * PLib.thdt;
+
+ if (PLib.isFlagClear(PLib.SYNCHRONOUS_FLAG))
+ deep_arg.xll = xl + temp + temp;
+ else
+ deep_arg.xll = xl - deep_arg.omgadf + temp;
+
+ return;
+
+ case dpper:
+ sinis = Math.sin(deep_arg.xinc);
+ cosis = Math.cos(deep_arg.xinc);
+
+ if (Math.abs(PLib.Deep.savtsn - deep_arg.t) >= 30)
+ {
+ PLib.Deep.savtsn = deep_arg.t;
+ zm = PLib.Deep.zmos + PLib.zns * deep_arg.t;
+ zf = zm + 2 * PLib.zes * Math.sin(zm);
+ sinzf = Math.sin(zf);
+ f2 = 0.5 * sinzf * sinzf-0.25;
+ f3 = -0.5 * sinzf * Math.cos(zf);
+ ses = PLib.Deep.se2 * f2 + PLib.Deep.se3 * f3;
+ sis = PLib.Deep.si2 * f2 + PLib.Deep.si3 * f3;
+ sls = PLib.Deep.sl2 * f2 + PLib.Deep.sl3 * f3 + PLib.Deep.sl4 * sinzf;
+ PLib.Deep.sghs = PLib.Deep.sgh2 * f2 + PLib.Deep.sgh3 * f3 + PLib.Deep.sgh4 * sinzf;
+ PLib.Deep.shs = PLib.Deep.sh2 * f2 + PLib.Deep.sh3 * f3;
+ zm = PLib.Deep.zmol + PLib.znl * deep_arg.t;
+ zf = zm + 2 * zel * Math.sin(zm);
+ sinzf = Math.sin(zf);
+ f2 = 0.5 * sinzf * sinzf - 0.25;
+ f3 = -0.5 * sinzf * Math.cos(zf);
+ sel = PLib.Deep.ee2 * f2 + PLib.Deep.e3 * f3;
+ sil = PLib.Deep.xi2 * f2 + PLib.Deep.xi3 * f3;
+ sll = PLib.Deep.xl2 * f2 + PLib.Deep.xl3 * f3 + PLib.Deep.xl4 * sinzf;
+ PLib.Deep.sghl = PLib.Deep.xgh2 * f2 + PLib.Deep.xgh3 * f3 + PLib.Deep.xgh4 * sinzf;
+ PLib.Deep.sh1 = PLib.Deep.xh2 * f2 + PLib.Deep.xh3 * f3;
+ PLib.Deep.pe = ses + sel;
+ PLib.Deep.pinc = sis + sil;
+ PLib.Deep.pl = sls + sll;
+ }
+
+ pgh = PLib.Deep.sghs + PLib.Deep.sghl;
+ ph = PLib.Deep.shs + PLib.Deep.sh1;
+ deep_arg.xinc = deep_arg.xinc + PLib.Deep.pinc;
+ deep_arg.em = deep_arg.em + PLib.Deep.pe;
+
+ if (PLib.Deep.xqncl >= 0.2)
+ {
+ ph = ph / deep_arg.sinio;
+ pgh = pgh - deep_arg.cosio * ph;
+ deep_arg.omgadf = deep_arg.omgadf + pgh;
+ deep_arg.xnode = deep_arg.xnode + ph;
+ deep_arg.xll = deep_arg.xll + PLib.Deep.pl;
+ }
+
+ else
+ {
+ sinok = Math.sin(deep_arg.xnode);
+ cosok = Math.cos(deep_arg.xnode);
+ alfdp = sinis * sinok;
+ betdp = sinis * cosok;
+ dalf = ph * cosok + PLib.Deep.pinc * cosis * sinok;
+ dbet = -ph * sinok + PLib.Deep.pinc * cosis * cosok;
+ alfdp = alfdp + dalf;
+ betdp = betdp + dbet;
+ deep_arg.xnode = FMod2p(deep_arg.xnode);
+ xls = deep_arg.xll + deep_arg.omgadf + cosis * deep_arg.xnode;
+ dls = PLib.Deep.pl + pgh - PLib.Deep.pinc * deep_arg.xnode * sinis;
+ xls = xls + dls;
+ xnoh = deep_arg.xnode;
+ deep_arg.xnode = Math.atan2(alfdp, betdp);
+
+ if (Math.abs(xnoh - deep_arg.xnode) > PLib.pi)
+ {
+ if (deep_arg.xnode < xnoh)
+ deep_arg.xnode += PLib.twopi;
+ else
+ deep_arg.xnode -= PLib.twopi;
+ }
+
+ deep_arg.xll = deep_arg.xll + PLib.Deep.pl;
+ deep_arg.omgadf = xls - deep_arg.xll - Math.cos(deep_arg.xinc) * deep_arg.xnode;
+ }
+ return;
+ }
+ },
+
+ SDP4: function(tsince, tle, pos, vel)
+ {
+ var i = 0;
+
+ var a = 0.0, axn = 0.0, ayn = 0.0, aynl = 0.0, beta = 0.0, betal = 0.0, capu = 0.0, cos2u = 0.0, cosepw = 0.0, cosik = 0.0,
+ cosnok = 0.0, cosu = 0.0, cosuk = 0.0, ecose = 0.0, elsq = 0.0, epw = 0.0, esine = 0.0, pl = 0.0, theta4 = 0.0, rdot = 0.0,
+ rdotk = 0.0, rfdot = 0.0, rfdotk = 0.0, rk = 0.0, sin2u = 0.0, sinepw = 0.0, sinik = 0.0, sinnok = 0.0, sinu = 0.0,
+ sinuk = 0.0, tempe = 0.0, templ = 0.0, tsq = 0.0, u = 0.0, uk = 0.0, ux = 0.0, uy = 0.0, uz = 0.0, vx = 0.0, vy = 0.0, vz = 0.0, xinck = 0.0, xl = 0.0,
+ xlt = 0.0, xmam = 0.0, xmdf = 0.0, xmx = 0.0, xmy = 0.0, xnoddf = 0.0, xnodek = 0.0, xll = 0.0, a1 = 0.0, a3ovk2 = 0.0, ao = 0.0, c2 = 0.0,
+ coef = 0.0, coef1 = 0.0, x1m5th = 0.0, xhdot1 = 0.0, del1 = 0.0, r = 0.0, delo = 0.0, eeta = 0.0, eta = 0.0, etasq = 0.0,
+ perigee = 0.0, psisq = 0.0, tsi = 0.0, qoms24 = 0.0, s4 = 0.0, pinvsq = 0.0, temp = 0.0, tempa = 0.0, temp1 = 0.0,
+ temp2 = 0.0, temp3 = 0.0, temp4 = 0.0, temp5 = 0.0, temp6 = 0.0, bx = 0.0, by = 0.0, bz = 0.0, cx = 0.0, cy = 0.0, cz = 0.0;
+
+ PLib.SDP4.deep_arg = PLib.SDP4.deep_arg || new PLib.deep_arg_t();
+
+ if (PLib.isFlagClear(PLib.SDP4_INITIALIZED_FLAG))
+ {
+ PLib.SetFlag(PLib.SDP4_INITIALIZED_FLAG);
+
+ a1 = Math.pow(PLib.xke / tle.xno, PLib.tothrd);
+ PLib.SDP4.deep_arg.cosio = Math.cos(tle.xincl);
+ PLib.SDP4.deep_arg.theta2 = PLib.SDP4.deep_arg.cosio * PLib.SDP4.deep_arg.cosio;
+ PLib.SDP4.x3thm1 = 3 * PLib.SDP4.deep_arg.theta2 - 1;
+ PLib.SDP4.deep_arg.eosq = tle.eo * tle.eo;
+ PLib.SDP4.deep_arg.betao2 = 1 - PLib.SDP4.deep_arg.eosq;
+ PLib.SDP4.deep_arg.betao = Math.sqrt(PLib.SDP4.deep_arg.betao2);
+ del1 = 1.5 * PLib.ck2 * PLib.SDP4.x3thm1 / (a1 * a1 * PLib.SDP4.deep_arg.betao * PLib.SDP4.deep_arg.betao2);
+ ao = a1 * (1 - del1 * (0.5 * PLib.tothrd + del1 * (1 + 134 / 81 * del1)));
+ delo = 1.5 * PLib.ck2 * PLib.SDP4.x3thm1 / (ao * ao * PLib.SDP4.deep_arg.betao * PLib.SDP4.deep_arg.betao2);
+ PLib.SDP4.deep_arg.xnodp = tle.xno / (1 + delo);
+ PLib.SDP4.deep_arg.aodp = ao / (1 - delo);
+
+ s4 = s;
+ qoms24 = PLib.qoms2t;
+ perigee = (PLib.SDP4.deep_arg.aodp * (1 - tle.eo) - PLib.ae) * PLib.xkmper;
+
+ if (perigee < 156.0)
+ {
+ if (perigee <= 98.0)
+ s4 = 20.0;
+ else
+ s4 = perigee - 78.0;
+
+ qoms24 = Math.pow((120 - s4) * PLib.ae / xkmper,4);
+ s4 = s4 / PLib.xkmper + PLib.ae;
+ }
+
+ pinvsq = 1 / (PLib.SDP4.deep_arg.aodp * PLib.SDP4.deep_arg.aodp * PLib.SDP4.deep_arg.betao2 * PLib.SDP4.deep_arg.betao2);
+ PLib.SDP4.deep_arg.sing = Math.sin(tle.omegao);
+ PLib.SDP4.deep_arg.cosg = Math.cos(tle.omegao);
+ tsi = 1 / (PLib.SDP4.deep_arg.aodp - s4);
+ eta = PLib.SDP4.deep_arg.aodp * tle.eo * tsi;
+ etasq = eta * eta;
+ eeta = tle.eo * eta;
+ psisq = Math.abs(1 - etasq);
+ coef = qoms24 * Math.pow(tsi, 4);
+ coef1 = coef / Math.pow(psisq, 3.5);
+ c2 = coef1 * PLib.SDP4.deep_arg.xnodp * (PLib.SDP4.deep_arg.aodp * (1 + 1.5 * etasq + eeta * (4 + etasq)) + 0.75 * PLib.ck2 * tsi / psisq * PLib.SDP4.x3thm1 * (8 + 3 * etasq * (8 + etasq)));
+ PLib.SDP4.c1 = tle.bstar * c2;
+ PLib.SDP4.deep_arg.sinio = Math.sin(tle.xincl);
+ a3ovk2 = -xj3 / ck2 * Math.pow(ae, 3);
+ PLib.SDP4.x1mth2 = 1 -PLib.SDP4.deep_arg.theta2;
+ PLib.SDP4.c4 = 2 * PLib.SDP4.deep_arg.xnodp * coef1 * PLib.SDP4.deep_arg.aodp * PLib.SDP4.deep_arg.betao2 * (eta * (2 + 0.5 * etasq) + tle.eo * (0.5 + 2 * etasq) - 2 * PLib.ck2 * tsi / (PLib.SDP4.deep_arg.aodp * psisq) * (-3 * PLib.SDP4.x3thm1 * (1 - 2 * eeta + etasq * (1.5 - 0.5 * eeta)) + 0.75 * PLib.SDP4.x1mth2 * (2 * etasq - eeta * (1 + etasq)) * Math.cos(2 * tle.omegao)));
+ theta4 = PLib.SDP4.deep_arg.theta2 * PLib.SDP4.deep_arg.theta2;
+ temp1 = 3 * PLib.ck2 * pinvsq * PLib.SDP4.deep_arg.xnodp;
+ temp2 = temp1 * PLib.ck2 * pinvsq;
+ temp3 = 1.25 * PLib.ck4 * pinvsq * pinvsq * PLib.SDP4.deep_arg.xnodp;
+ PLib.SDP4.deep_arg.xmdot = PLib.SDP4.deep_arg.xnodp + 0.5 * temp1 * PLib.SDP4.deep_arg.betao * PLib.SDP4.x3thm1 + 0.0625 * temp2 * PLib.SDP4.deep_arg.betao * (13 - 78 * PLib.SDP4.deep_arg.theta2 + 137 * theta4);
+ x1m5th = 1 - 5 * PLib.SDP4.deep_arg.theta2;
+ PLib.SDP4.deep_arg.omgdot = -0.5 * temp1 * x1m5th + 0.0625 * temp2 * (7 - 114 * PLib.SDP4.deep_arg.theta2 + 395 * theta4) + temp3 * (3 - 36 * PLib.SDP4.deep_arg.theta2 + 49 * theta4);
+ xhdot1 = -temp1 * PLib.SDP4.deep_arg.cosio;
+ PLib.SDP4.deep_arg.xnodot = xhdot1 + (0.5 * temp2 * (4 - 19 * PLib.SDP4.deep_arg.theta2) + 2 * temp3 * (3 - 7 * PLib.SDP4.deep_arg.theta2)) * PLib.SDP4.deep_arg.cosio;
+ PLib.SDP4.xnodcf = 3.5 * PLib.SDP4.deep_arg.betao2 * xhdot1 * PLib.SDP4.c1;
+ PLib.SDP4.t2cof = 1.5 * PLib.SDP4.c1;
+ PLib.SDP4.xlcof = 0.125 * a3ovk2 * PLib.SDP4.deep_arg.sinio * (3 + 5 * PLib.SDP4.deep_arg.cosio) / (1 + PLib.SDP4.deep_arg.cosio);
+ PLib.SDP4.aycof = 0.25 * a3ovk2 * PLib.SDP4.deep_arg.sinio;
+ PLib.SDP4.x7thm1 = 7 * PLib.SDP4.deep_arg.theta2 - 1;
+
+ Deep(dpinit, tle, PLib.SDP4.deep_arg);
+ }
+
+ xmdf = tle.xmo + PLib.SDP4.deep_arg.xmdot * tsince;
+ PLib.SDP4.deep_arg.omgadf = tle.omegao + PLib.SDP4.deep_arg.omgdot * tsince;
+ xnoddf = tle.xnodeo + PLib.SDP4.deep_arg.xnodot * tsince;
+ tsq = tsince * tsince;
+ PLib.SDP4.deep_arg.xnode = xnoddf + PLib.SDP4.xnodcf * tsq;
+ tempa = 1 - PLib.SDP4.c1 * tsince;
+ tempe = tle.bstar * PLib.SDP4.c4 * tsince;
+ templ = PLib.SDP4.t2cof * tsq;
+ PLib.SDP4.deep_arg.xn = PLib.SDP4.deep_arg.xnodp;
+
+ PLib.SDP4.deep_arg.xll = xmdf;
+ PLib.SDP4.deep_arg.t = tsince;
+
+ Deep(dpsec, tle, PLib.SDP4.deep_arg);
+
+ xmdf = PLib.SDP4.deep_arg.xll;
+ a = Math.pow(PLib.xke / PLib.SDP4.deep_arg.xn, PLib.tothrd) * tempa * tempa;
+ PLib.SDP4.deep_arg.em = PLib.SDP4.deep_arg.em - tempe;
+ xmam = xmdf + PLib.SDP4.deep_arg.xnodp * templ;
+
+ PLib.SDP4.deep_arg.xll = xmam;
+
+ Deep(PLib.dpper, tle, PLib.SDP4.deep_arg);
+
+ xmam = PLib.SDP4.deep_arg.xll;
+ xl = xmam + PLib.SDP4.deep_arg.omgadf + PLib.SDP4.deep_arg.xnode;
+ beta = Math.sqrt(1 - PLib.SDP4.deep_arg.em * PLib.SDP4.deep_arg.em);
+ PLib.SDP4.deep_arg.xn = PLib.xke / Math.pow(a, 1.5);
+
+ axn = PLib.SDP4.deep_arg.em * Math.cos(PLib.SDP4.deep_arg.omgadf);
+ temp = 1 / (a * beta * beta);
+ xll = temp * PLib.SDP4.xlcof * axn;
+ aynl = temp * PLib.SDP4.aycof;
+ xlt = xl + xll;
+ ayn = PLib.SDP4.deep_arg.em * Math.sin(PLib.SDP4.deep_arg.omgadf) + aynl;
+
+ capu = FMod2p(xlt - PLib.SDP4.deep_arg.xnode);
+ temp2 = capu;
+ i = 0;
+
+ do
+ {
+ sinepw = Math.sin(temp2);
+ cosepw = Math.cos(temp2);
+ temp3 = axn * sinepw;
+ temp4 = ayn * cosepw;
+ temp5 = axn * cosepw;
+ temp6 = ayn * sinepw;
+ epw = (capu - temp4 + temp3 - temp2) / (1 - temp5 - temp6) + temp2;
+
+ if (Math.abs(epw - temp2) <= e6a)
+ break;
+
+ temp2 = epw;
+
+ } while (i++ < 10);
+
+ ecose = temp5 + temp6;
+ esine = temp3 - temp4;
+ elsq = axn * axn + ayn * ayn;
+ temp = 1 - elsq;
+ pl = a * temp;
+ r = a * (1 - ecose);
+ temp1 = 1 / r;
+ rdot = PLib.xke * Math.sqrt(a) * esine * temp1;
+ rfdot = PLib.xke * Math.sqrt(pl) * temp1;
+ temp2 = a * temp1;
+ betal = Math.sqrt(temp);
+ temp3 = 1 / (1 + betal);
+ cosu = temp2 * (cosepw - axn + ayn * esine * temp3);
+ sinu = temp2 * (sinepw - ayn - axn * esine * temp3);
+ u = Math.atan2(sinu, cosu);
+ sin2u = 2 * sinu * cosu;
+ cos2u = 2 * cosu * cosu - 1;
+ temp = 1 / pl;
+ temp1 = PLib.ck2 * temp;
+ temp2 = temp1 * temp;
+
+ rk = r * (1 - 1.5 * temp2 * betal * PLib.SDP4.x3thm1) + 0.5 * temp1 * PLib.SDP4.x1mth2 * cos2u;
+ uk = u - 0.25 * temp2 * PLib.SDP4.x7thm1 * sin2u;
+ xnodek = PLib.SDP4.deep_arg.xnode + 1.5 * temp2 * PLib.SDP4.deep_arg.cosio * sin2u;
+ xinck = PLib.SDP4.deep_arg.xinc + 1.5 * temp2 * PLib.SDP4.deep_arg.cosio * PLib.SDP4.deep_arg.sinio * cos2u;
+ rdotk = rdot - PLib.SDP4.deep_arg.xn * temp1 * PLib.SDP4.x1mth2 * sin2u;
+ rfdotk = rfdot + PLib.SDP4.deep_arg.xn * temp1 * (PLib.SDP4.x1mth2 * cos2u + 1.5 * PLib.SDP4.x3thm1);
+
+ sinuk = Math.sin(uk);
+ cosuk = Math.cos(uk);
+ sinik = Math.sin(xinck);
+ cosik = Math.cos(xinck);
+ sinnok = Math.sin(xnodek);
+ cosnok = Math.cos(xnodek);
+ xmx = -sinnok * cosik;
+ xmy = cosnok * cosik;
+ ux = xmx * sinuk + cosnok * cosuk;
+ uy = xmy * sinuk + sinnok * cosuk;
+ uz = sinik * sinuk;
+ vx = xmx * cosuk - cosnok * sinuk;
+ vy = xmy * cosuk - sinnok * sinuk;
+ vz = sinik * cosuk;
+
+ pos.x = rk * ux;
+ pos.y = rk * uy;
+ pos.z = rk * uz;
+ vel.x = rdotk * ux + rfdotk * vx;
+ vel.y = rdotk * uy + rfdotk * vy;
+ vel.z = rdotk * uz + rfdotk * vz;
+
+ PLib.phase = xlt - PLib.SDP4.deep_arg.xnode - PLib.SDP4.deep_arg.omgadf + PLib.twopi;
+
+ if (PLib.phase < 0.0)
+ PLib.phase += PLib.twopi;
+
+ PLib.phase = PLib.FMod2p(PLib.phase);
+ },
+
+ Calculate_User_PosVel: function(time, geodetic, obs_pos, obs_vel)
+ {
+ var c = 0.0, sq = 0.0, achcp = 0.0;
+
+ geodetic.theta = PLib.FMod2p(PLib.ThetaG_JD(time) + geodetic.lon);
+ c = 1 / Math.sqrt(1 + PLib.f * (PLib.f - 2) * PLib.Sqr(Math.sin(geodetic.lat)));
+ sq = PLib.Sqr(1 - PLib.f) * c;
+ achcp = (PLib.xkmper * c + geodetic.alt) * Math.cos(geodetic.lat);
+ obs_pos.x = achcp * Math.cos(geodetic.theta);
+ obs_pos.y = achcp * Math.sin(geodetic.theta);
+ obs_pos.z = (PLib.xkmper * sq + geodetic.alt) * Math.sin(geodetic.lat);
+ obs_vel.x = -PLib.mfactor * obs_pos.y;
+ obs_vel.y = PLib.mfactor * obs_pos.x;
+ obs_vel.z = 0;
+ PLib.Magnitude(obs_pos);
+ PLib.Magnitude(obs_vel);
+ },
+
+ Calculate_LatLonAlt: function(time, pos, geodetic)
+ {
+ var r = 0.0, e2 = 0.0, phi = 0.0, c = 0.0;
+
+ geodetic.theta = Math.atan2(pos.y, pos.x);
+ geodetic.lon = PLib.FMod2p(geodetic.theta - PLib.ThetaG_JD(time));
+ r = Math.sqrt(PLib.Sqr(pos.x) + PLib.Sqr(pos.y));
+ e2 = PLib.f * (2 - PLib.f);
+ geodetic.lat = Math.atan2(pos.z, r);
+
+ do
+ {
+ phi = geodetic.lat;
+ c = 1 / Math.sqrt(1 - e2 * PLib.Sqr(Math.sin(phi)));
+ geodetic.lat = Math.atan2(pos.z + PLib.xkmper * c * e2 * Math.sin(phi), r);
+
+ } while (Math.abs(geodetic.lat - phi) >= 1E-10);
+
+ geodetic.alt = r / Math.cos(geodetic.lat) - PLib.xkmper * c;
+
+ if (geodetic.lat > PLib.pio2)
+ geodetic.lat -= PLib.twopi;
+ },
+
+ Calculate_Obs: function(time, pos, vel, geodetic, obs_set)
+ {
+ var sin_lat = 0.0, cos_lat = 0.0, sin_theta = 0.0, cos_theta = 0.0, el = 0.0, azim = 0.0, top_s = 0.0, top_e = 0.0, top_z = 0.0;
+
+ var obs_pos = new PLib.vector_t();
+ var obs_vel = new PLib.vector_t();
+ var range = new PLib.vector_t();
+ var rgvel = new PLib.vector_t();
+
+ PLib.Calculate_User_PosVel(time, geodetic, obs_pos, obs_vel);
+
+ range.x = pos.x - obs_pos.x;
+ range.y = pos.y - obs_pos.y;
+ range.z = pos.z - obs_pos.z;
+
+ rx = range.x;
+ ry = range.y;
+ rz = range.z;
+
+ rgvel.x = vel.x - obs_vel.x;
+ rgvel.y = vel.y - obs_vel.y;
+ rgvel.z = vel.z - obs_vel.z;
+
+ PLib.Magnitude(range);
+
+ sin_lat = Math.sin(geodetic.lat);
+ cos_lat = Math.cos(geodetic.lat);
+ sin_theta = Math.sin(geodetic.theta);
+ cos_theta = Math.cos(geodetic.theta);
+ top_s = sin_lat * cos_theta * range.x + sin_lat * sin_theta * range.y - cos_lat * range.z;
+ top_e = -sin_theta * range.x + cos_theta * range.y;
+ top_z = cos_lat * cos_theta * range.x+cos_lat * sin_theta * range.y + sin_lat * range.z;
+ azim = Math.atan(-top_e / top_s);
+
+ if (top_s > 0.0)
+ azim = azim + PLib.pi;
+
+ if (azim < 0.0)
+ azim = azim + PLib.twopi;
+
+ el = Math.asin(top_z / range.w);
+ obs_set.x = azim;
+ obs_set.y = el;
+ obs_set.z = range.w;
+
+ obs_set.w = PLib.Dot(range, rgvel) / range.w;
+
+ obs_set.y = el;
+
+ if (obs_set.y >= 0.0)
+ PLib.SetFlag(PLib.VISIBLE_FLAG);
+ else
+ {
+ obs_set.y = el;
+ PLib.ClearFlag(PLib.VISIBLE_FLAG);
+ }
+ },
+
+ InternalUpdate: function()
+ {
+ var tempnum;
+
+ PLib.sat.designator = PLib.sat.line1.substring(9, 17);
+ PLib.sat.catnum = PLib.sat.line1.substring(2, 7);
+ PLib.sat.year = PLib.sat.line1.substring(18, 20);
+ PLib.sat.refepoch = PLib.sat.line1.substring(20, 32);
+ tempnum = 1.0e-5 * PLib.sat.line1.substring(44, 50);
+ PLib.sat.nddot6 = tempnum / Math.pow(10.0, PLib.sat.line1.charAt(51));
+ tempnum = 1.0e-5 * PLib.sat.line1.substring(53, 59);
+ PLib.sat.bstar = tempnum / Math.pow(10.0, PLib.sat.line1.charAt(60));
+ PLib.sat.setnum = PLib.sat.line1.substring(64, 68);
+ PLib.sat.incl = PLib.sat.line2.substring(8, 16);
+ PLib.sat.raan = PLib.sat.line2.substring(17, 25);
+ PLib.sat.eccn = 1.0e-07 * PLib.sat.line2.substring(26,33);
+ PLib.sat.argper = PLib.sat.line2.substring(34, 42);
+ PLib.sat.meanan = PLib.sat.line2.substring(43, 51);
+ PLib.sat.meanmo = PLib.sat.line2.substring(52, 63);
+ PLib.sat.drag = PLib.sat.line1.substring(33, 43);
+ PLib.sat.orbitnum = PLib.sat.line2.substring(63, 68);
+ },
+
+ InitializeData: function()
+ {
+ PLib.sat = new PLib.sat_t();
+ PLib.sat.name = PLib.tleData[0];
+ PLib.sat.line1 = PLib.tleData[1];
+ PLib.sat.line2 = PLib.tleData[2];
+ PLib.InternalUpdate();
+ },
+
+ DayNum: function(m, d, y)
+ {
+ var dn = 0;
+ var mm = 0.0, yy = 0.0;
+
+ if (m < 3)
+ {
+ y--;
+ m += 12;
+ }
+
+ if (y <= 50)
+ y += 100;
+
+ yy = y;
+ mm = m;
+ dn = (Math.floor(365.25 * (yy - 80.0)) - Math.floor(19.0 + yy / 100.0) + Math.floor(4.75 + yy / 400.0) - 16.0);
+ dn += d + 30 * m + Math.floor(0.6 * mm - 0.3);
+
+ return dn;
+ },
+
+ CurrentDaynum: function()
+ {
+ var d = new Date();
+ return (d.getTime() - 315446400000) / 86400000;
+ },
+
+ FutureDaynum: function (minutes)
+ {
+ var d = new Date ();
+ return (d.getTime() - 315446400000 + minutes * 1000 * 60) / 86400000;
+ },
+
+ Daynum2Date: function(daynum)
+ {
+ var d = new Date();
+ d.setTime(daynum * 86400000 + 315446400000);
+ var x = d + 1;
+ return d;
+ },
+
+ PreCalc: function()
+ {
+ PLib.tle.sat_name = PLib.sat.name
+ PLib.tle.idesg = PLib.sat.designator;
+ PLib.tle.catnr = PLib.sat.catnum;
+ PLib.tle.epoch = (1000.0 * PLib.sat.year) + PLib.sat.refepoch * 1;
+ PLib.tle.xndt2o = PLib.sat.drag;
+ PLib.tle.xndd6o = PLib.sat.nddot6;
+ PLib.tle.bstar = PLib.sat.bstar;
+ PLib.tle.xincl = PLib.sat.incl;
+ PLib.tle.xnodeo = PLib.sat.raan;
+ PLib.tle.eo = PLib.sat.eccn;
+ PLib.tle.omegao = PLib.sat.argper;
+ PLib.tle.xmo = PLib.sat.meanan;
+ PLib.tle.xno = PLib.sat.meanmo;
+ PLib.tle.revnum = PLib.sat.orbitnum;
+
+ PLib.ClearFlag(PLib.ALL_FLAGS);
+ PLib.select_ephemeris(PLib.tle);
+ },
+
+ Calc: function()
+ {
+ var zero_vector = new PLib.vector_t();
+ var vel = new PLib.vector_t();
+ var pos = new PLib.vector_t();
+ var obs_set = new PLib.vector_t();
+ var solar_vector = new PLib.vector_t();
+ var solar_set = new PLib.vector_t();
+
+ var sat_geodetic = new PLib.geodetic_t();
+
+ PLib.jul_utc = PLib.daynum + 2444238.5;
+
+ PLib.jul_epoch = PLib.Julian_Date_of_Epoch(PLib.tle.epoch);
+ PLib.tsince = (PLib.jul_utc - PLib.jul_epoch) * PLib.xmnpda;
+ PLib.age = PLib.jul_utc - PLib.jul_epoch;
+
+ if (PLib.isFlagSet(PLib.DEEP_SPACE_EPHEM_FLAG))
+ PLib.ephem = "SDP4";
+ else
+ PLib.ephem = "SGP4";
+
+ if (PLib.isFlagSet(PLib.DEEP_SPACE_EPHEM_FLAG))
+ PLib.SDP4(PLib.tsince, PLib.tle, pos, vel);
+ else
+ PLib.SGP4(PLib.tsince, PLib.tle, pos, vel);
+
+ PLib.Convert_Sat_State(pos, vel);
+
+ PLib.Magnitude(vel);
+ PLib.sat_vel = vel.w;
+
+ PLib.Calculate_Obs(PLib.jul_utc, pos, vel, PLib.obs_geodetic, obs_set);
+
+ PLib.Calculate_LatLonAlt(PLib.jul_utc, pos, sat_geodetic);
+
+ PLib.Calculate_Solar_Position(PLib.jul_utc, solar_vector);
+ PLib.Calculate_Obs(PLib.jul_utc, solar_vector, zero_vector, PLib.obs_geodetic, solar_set);
+
+ if (PLib.Sat_Eclipsed(pos, solar_vector))
+ PLib.SetFlag(PLib.SAT_ECLIPSED_FLAG);
+ else
+ PLib.ClearFlag(PLib.SAT_ECLIPSED_FLAG);
+
+ if (PLib.isFlagSet(PLib.SAT_ECLIPSED_FLAG))
+ PLib.sat_sun_status = 0;
+ else
+ PLib.sat_sun_status = 1;
+
+ PLib.sat_azi = PLib.Degrees(obs_set.x);
+ PLib.sat_ele = PLib.Degrees(obs_set.y);
+ PLib.sat_range = obs_set.z;
+ PLib.sat_range_rate = obs_set.w;
+ PLib.sat_lat = PLib.Degrees(sat_geodetic.lat);
+ PLib.sat_lon = PLib.Degrees(sat_geodetic.lon);
+ PLib.sat_alt = sat_geodetic.alt;
+
+ PLib.fk = 12756.33 * Math.acos(PLib.xkmper / (PLib.xkmper + PLib.sat_alt));
+ PLib.fm = PLib.fk / 1.609344;
+
+ PLib.rv = Math.floor((PLib.tle.xno * PLib.xmnpda / PLib.twopi + PLib.age * PLib.tle.bstar * PLib.ae) * PLib.age + PLib.tle.xmo / PLib.twopi) + parseInt(PLib.tle.revnum);
+
+ PLib.sun_azi = PLib.Degrees(solar_set.x);
+ PLib.sun_ele = PLib.Degrees(solar_set.y);
+
+ PLib.irk = PLib.roundTo (PLib.sat_range, 2);
+ PLib.isplat = PLib.roundTo (PLib.sat_lat, 2);
+ PLib.isplong = PLib.roundTo (360.0 - PLib.sat_lon, 2);
+ PLib.iaz = PLib.roundTo (PLib.sat_azi, 2);
+ PLib.iel = PLib.roundTo (PLib.sat_ele, 2);
+ PLib.ma256 = Math.round(256.0 * (PLib.phase / PLib.twopi));
+
+ if (PLib.sat_sun_status)
+ {
+ if (PLib.sun_ele <= -12.0 && PLib.sat_ele >= 0.0)
+ PLib.findsun = '+';
+ else
+ PLib.findsun = '*';
+ }
+ else
+ PLib.findsun = ' ';
+ },
+
+ AosHappens: function()
+ {
+ var lin = 0.0, sma = 0.0, apogee = 0.0;
+
+ if (PLib.sat.meanmo == 0.0)
+ return 0;
+ else
+ {
+ lin = PLib.sat.incl;
+
+ if (lin >= 90.0)
+ lin = 180.0 - lin;
+
+ sma = 331.25 * Math.exp(Math.log(1440.0 / PLib.sat.meanmo) * (2.0 / 3.0));
+ apogee = sma * (1.0 + PLib.sat.eccn) - PLib.xkmper;
+
+ if ((Math.acos(PLib.xkmper / (apogee + PLib.xkmper)) + (lin * PLib.deg2rad)) > Math.abs(PLib.qth.stnlat * PLib.deg2rad))
+ return 1;
+ else
+ return 0;
+ }
+ },
+
+ Decayed: function(time)
+ {
+ var satepoch = 0.0;
+
+ if (time == 0.0)
+ time = PLib.CurrentDaynum();
+
+ satepoch = PLib.DayNum(1, 0, PLib.sat.year) + PLib.sat.refepoch;
+
+ if (satepoch + ((16.666666 - PLib.sat.meanmo) / (10.0 * Math.abs(PLib.sat.drag))) < time)
+ return 1;
+ else
+ return 0;
+ },
+
+ Geostationary: function()
+ {
+ if (Math.abs(PLib.sat.meanmo - 1.0027) < 0.0002)
+ return 1;
+ else
+ return 0;
+ },
+
+ FindAOS: function()
+ {
+ PLib.aostime = 0.0;
+
+ if (PLib.AosHappens() && PLib.Geostationary() == 0 && PLib.Decayed(indx, PLib.daynum) == 0)
+ {
+ PLib.Calc();
+
+ while (PLib.sat_ele < -1.0)
+ {
+ PLib.daynum -= 0.00035 * (PLib.sat_ele * (((PLib.sat_alt / 8400.0) + 0.46)) - 2.0);
+ PLib.Calc();
+ }
+
+ while (PLib.aostime == 0.0)
+ {
+ if (Math.abs(PLib.sat_ele) < 0.03)
+ PLib.aostime = PLib.daynum;
+ else
+ {
+ PLib.daynum -= PLib.sat_ele * Math.sqrt(PLib.sat_alt) / 530000.0;
+ PLib.Calc();
+ }
+ }
+ }
+
+ return PLib.aostime;
+ },
+
+ FindLOS: function()
+ {
+ PLib.lostime = 0.0;
+
+ if (PLib.Geostationary() == 0 && PLib.AosHappens() == 1 && PLib.Decayed(indx, PLib.daynum) == 0)
+ {
+ PLib.Calc();
+
+ do
+ {
+ PLib.daynum += PLib.sat_ele * Math.sqrt(PLib.sat_alt) / 502500.0;
+ PLib.Calc();
+
+ if (Math.abs(PLib.sat_ele) < 0.03)
+ PLib.lostime = PLib.daynum;
+
+ } while (PLib.lostime == 0.0);
+ }
+
+ return PLib.lostime;
+ },
+
+ // calculate preview for the next minutes in orbit
+ // @return: array with [longitude, latitude] value
+ calculateTrack: function (minutes)
+ {
+ var points = new Array ();
+ var longitude;
+
+ PLib.PreCalc ();
+ for (var i = 0; i < minutes; i++)
+ {
+ PLib.daynum = PLib.FutureDaynum (i);
+ PLib.Calc ();
+ longitude = 360 - PLib.isplong;
+ if (longitude > 180)
+ longitude = -PLib.isplong;
+ points.push ([longitude, PLib.isplat]);
+ }
+ // document.getElementById ("debug").innerHTML = PLib.Daynum2Date (PLib.daynum);
+ return points;
+ },
+
+ QuickFind: function(satname)
+ {
+ var satInfo = new Object();
+
+ if ((PLib.sat.name == satname) || (satname == PLib.sat.catnum))
+ {
+ PLib.daynum = PLib.CurrentDaynum();
+ PLib.PreCalc();
+ PLib.Calc();
+
+ if (PLib.Decayed(PLib.daynum) == 0)
+ {
+ satInfo.dateTime = PLib.Daynum2Date(PLib.daynum);
+ satInfo.elevation = PLib.iel;
+ satInfo.azimuth = PLib.iaz;
+ satInfo.orbitalPhase = PLib.ma256;
+ satInfo.latitude = PLib.isplat;
+ satInfo.altitude = Math.round (PLib.sat_alt);
+
+ var lng = 360 - PLib.isplong;
+ if (lng > 180)
+ lng = -PLib.isplong;
+ satInfo.longitude = lng;
+
+ satInfo.slantRange = PLib.irk;
+ satInfo.orbitNumber = PLib.rv;
+ satInfo.visibility = PLib.findsun;
+ }
+ }
+ return satInfo;
+ },
+
+ formatDateOnly: function(dt)
+ {
+ var months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];
+ return months[dt.getMonth()] + " " + dt.getDate();
+ },
+
+ formatTimeOnly: function(dt)
+ {
+ var h = dt.getHours();
+ var m = dt.getMinutes();
+
+ var amPm = h < 12 ? "AM" : "PM"
+
+ h = h > 12 ? h - 12 : h;
+ h = h == 0 ? h = 12 : h;
+ m = m < 10 ? "0" + m : m;
+
+ return h + ":" + m + amPm;
+ },
+
+ extractDate: function(dt)
+ {
+ var d = new Date();
+ d.setTime(dt.valueOf());
+ d.setHours(0);
+ d.setMinutes(0);
+ d.setSeconds(0);
+ d.setMilliseconds(0);
+
+ return d;
+ },
+
+ addDay: function(dt)
+ {
+ var d = new Date(dt.getTime() + 86400000);
+ return d;
+ },
+
+ getTodaysPasses: function()
+ {
+ var satInfoColl = new Array();
+ var arrIdx = 0;
+ var x = 0, y = 0, z = 0, lastel = 0;
+ var start = 0, now = 0;
+
+ now = (3651.0 + PLib.CurrentDaynum()) * 86400.0;
+
+ if (start == 0)
+ start = now;
+
+ if ((start >= now - 31557600) && (start <= now + 31557600))
+ {
+ PLib.daynum = (start / 86400.0) - 3651.0;
+ PLib.PreCalc();
+ PLib.Calc();
+
+ var d = new Date();
+ var passNo = 1;
+
+ if (PLib.AosHappens() && PLib.Geostationary() == 0 && PLib.Decayed(PLib.daynum) == 0)
+ {
+ PLib.daynum = PLib.FindAOS();
+
+ while (PLib.Daynum2Date(PLib.daynum) < PLib.addDay(d))
+ {
+ var satInfo = new Object();
+
+ satInfo.number = z + 1;
+ satInfo.name = PLib.sat.name;
+ satInfo.passNo = passNo++;
+ satInfo.dateTimeStart = PLib.Daynum2Date(PLib.daynum);
+ satInfo.peakElevation = PLib.iel;
+ satInfo.riseAzimuth
+ = satInfo.peakAzimuth
+ = PLib.iaz;
+ satInfo.orbitalPhase = PLib.ma256;
+ satInfo.latitude = PLib.isplat;
+
+ var lng = 360 - PLib.isplong;
+ if (lng > 180) lng = -PLib.isplong;
+ satInfo.longitude = lng;
+
+ satInfo.riseRange
+ = satInfo.peakRange
+ = PLib.irk;
+ satInfo.orbitNumber = PLib.rv;
+
+ var plusCount = 0;
+ var asteriskCount = 0;
+
+ while (PLib.iel >= 0)
+ {
+ if (PLib.iel > satInfo.peakElevation)
+ {
+ satInfo.peakElevation = PLib.iel;
+ satInfo.peakAzimuth = PLib.iaz;
+ satInfo.peakRange = PLib.irk;
+ }
+
+ if (PLib.findsun == '+')
+ plusCount++;
+ else if (PLib.findsun == '*')
+ asteriskCount++;
+
+ lastel = PLib.iel;
+ PLib.daynum += Math.cos((PLib.sat_ele - 1.0) * PLib.deg2rad) * Math.sqrt(PLib.sat_alt) / 25000.0;
+ PLib.Calc();
+ }
+
+ if (lastel != 0)
+ {
+ PLib.daynum = PLib.FindLOS();
+ PLib.Calc();
+ }
+
+ satInfo.dateTimeEnd = PLib.Daynum2Date(PLib.daynum);
+ satInfo.decayAzimuth = PLib.iaz;
+ satInfo.decayRange = PLib.irk;
+
+ if ((plusCount > 3) || (plusCount > 2 && asteriskCount > 2))
+ {
+ satInfo.visibility = '+';
+ }
+ else if (asteriskCount > 2)
+ {
+ satInfo.visibility = '*';
+ }
+
+ satInfoColl[arrIdx++] = satInfo;
+
+ PLib.daynum += (1 / 24 / 6);
+ PLib.daynum = PLib.FindAOS();
+ }
+ }
+ }
+
+ return satInfoColl;
+ },
+
+ configureGroundStation: function(lat, lng, alt, name)
+ {
+ PLib.qth.stnlat = lat;
+ PLib.qth.stnalt = alt;
+ PLib.qth.name = name;
+
+ if (lng < 0) PLib.qth.stnlong = -lng;
+ else PLib.qth.stnlong = 360 - lng;
+
+ PLib.obs_geodetic.lat = PLib.qth.stnlat * PLib.deg2rad;
+ PLib.obs_geodetic.lon = -PLib.qth.stnlong * PLib.deg2rad;
+ PLib.obs_geodetic.alt = PLib.qth.stnalt / 1000.0;
+ PLib.obs_geodetic.theta = 0.0;
+ },
+
+ // FIXME: find a better way to round
+ roundTo: function (num, dec)
+ {
+ return Math.round (Math.round (num * Math.pow (10, dec + 1) / 10.0)) / Math.pow (10, dec);
+ }
+ };
+
+PLib.obs_geodetic = new PLib.geodetic_t();
+PLib.tle = new PLib.tle_t();
+
+// vim: ts=2 tw=0 expandtab
diff --git a/tools/mmd/tracker.wsgi b/tools/mmd/tracker.wsgi
new file mode 100644
index 0000000..cd64971
--- /dev/null
+++ b/tools/mmd/tracker.wsgi
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+
+from cgi import escape
+from urlparse import parse_qs
+
+def application (environ, response):
+ """
+ beginning of WSGI/python application for
+ MURSAT1 Tracker
+ """
+
+ body = '''
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>MURSAT1 tracker</title>
+ <link rel="stylesheet" type="text/css" href="http://hofos.at/mmd/static/mmd.css" />
+ <script src="http://www.openlayers.org/api/OpenLayers.js"></script>
+ <script src="static/predictlib.js" type="text/javascript"></script>
+ <script src="static/tle.js" type="text/javascript"></script>
+ <script src="static/orbtrak.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ function load()
+ {{
+ Orb.startOSMTracking(90, {longitude}, {latitude}, {altitude}, '{name}');
+ }}
+ </script>
+</head>
+<body onload="load ()">
+ <div class="groundstation">
+ <span id="gsName"></span>,
+ Lon:
+ <span id="gsLongitude"></span>,
+ Lat:
+ <span id="gsLatitude"></span>,
+ Alt:
+ <span id="gsAltitude"></span>
+ </div>
+ <div id="osm"></div>
+ <table class="current">
+ <tr>
+ <th class="telemetry">Longitude</th>
+ <th class="telemetry">Latitude</th>
+ <th class="telemetry">Azimuth</th>
+ <th class="telemetry">Elevation</th>
+ <th class="telemetry">Altitude</th>
+ </tr>
+ <tr>
+ <td class="telemetry" id="longitude">
+ </td>
+ <td class="telemetry" id="latitude">
+ </td>
+ <td class="telemetry" id="azimuth">
+ </td>
+ <td class="telemetry" id="elevation">
+ </td>
+ <td class="telemetry" id="altitude">
+ </td>
+ </tr>
+ </table>
+ <div class="telemetry">Set refresh rate to <span>
+ <select class="telemetry" name="refresh" id="refresh">
+ <option value="100">0.1</option>
+ <option value="500">0.5</option>
+ <option value="1000">1.0</option>
+ <option value="2000">2.0</option>
+ <option value="5000" selected="selected">5.0</option>
+ </select> seconds</span>
+ </div>
+ <div class="telemetry">
+ <input class="telemetry" type="submit" value="update" id="setPreviewMinutes" onClick="Orb.createSatelliteTrack ()" />
+ preview for the next <input class="telemetry" type="text" name="previewMinutes" id="previewMinutes" value="30" size="5" />
+ minutes
+ </div>
+ <pre id="debug"></pre>
+</body>
+'''
+
+ qs = parse_qs (environ['QUERY_STRING'], True)
+ if qs.has_key ('longitude') and qs.has_key ('latitude') and qs.has_key ('altitude'):
+ query = {
+ 'longitude': escape (qs.get ('longitude')[0]),
+ 'latitude': escape (qs.get ('latitude')[0]),
+ 'altitude': escape (qs.get ('altitude')[0])
+ }
+ if qs.has_key ('name'):
+ query ['name'] = escape (qs.get ('name')[0])
+ else:
+ query ['name'] = 'unknown set'
+ else:
+ query = {
+ 'longitude': 15.44226,
+ 'latitude': 47.06576,
+ 'altitude': 376,
+ 'name': 'Graz'
+ }
+
+ body = body.format (**query)
+ headers = ([('Content-Type', 'text/html'), ('Content-Length', str (len (body)))])
+ response ('200 OK', headers)
+
+ return [body]
+
+# vim: tw=0 ts=2 expandtab
+# EOF