This tutorial demonstrates how to use Beebotte to track the position of the International Space Station (ISS)
in real-time.
We will use the two-line element set (TLE)
to compute the position of the ISS in real-time using PyEphem
astrophysics library.
Tutorial contents:
At the end of this tutorial, we will be able to display the position of the ISS in real-time in Google Maps:
We will retrieve the TLE data of the ISS from CelesTrak
.
A two-line element set (TLE) is a data format used to convey sets of orbital elements that describe the orbits of Earth-orbiting satellites [Wikipedia].
The TLE data from CelesTrak looks as follows:
ISS (ZARYA) 1 25544U 98067A 14361.11356206 .00017231 00000-0 28015-3 0 6359 2 25544 51.6460 222.7302 0007398 178.4506 330.5659 15.52766391921266 TIANGONG 1 1 37820U 11053A 14361.07836743 .00050955 00000-0 49300-3 0 6993 2 37820 42.7683 229.1478 0014000 23.8878 134.9459 15.65491102186336 CHASQUI-1 ... ...
As you can see, the first three lines are related to the ISS. So we will extract these 3 lines as follows:
import urllib2 req = urllib2.Request(url) response = urllib2.urlopen(req) data = response.read() tle = data.split("\n")[0:3] line1 = tle[0] line2 = tle[1] line3 = tle[2]
We will now use the PyEphem library to compute the position of the ISS:
PyEphem can be installed using pip
like this:
pip install pyephem
import datetime import ephem iss = ephem.readtle(line1, line2, line3) now = datetime.datetime.utcnow() iss.compute(now) ### transform longitude and latitude to degrees print("longitude: %f - latitude: %f" % (degrees(iss.sublong), degrees(iss.sublat)))
Now we have the latitude & longitude of the ISS and we can start having fun.
We will use Beebotte Python SDK to publish ISS position. We need to specify the API and secret keys of our account,and to indicate the names of a channel and resource to publish to. We will use "ISS"
as channel name and "position"
as resource name.
Beebotte Python SDK can be installed using pip
like this:
pip install beebotte
We will publish
ISS position to Beebotte. Published data is transient and will not be persisted (see documentation
for details):
from beebotte import * from math import degrees ### Replace API_KEY and SECRET_KEY with those of your account bbt = BBT('API_KEY', 'SECRET_KEY') ### Change channel name and resource names as suits you iss_position = Resource(bbt, "ISS", "position") iss_position.publish({ "timestamp": round(time.time()), "position": { ### transform longitude and latitude to degrees "long": degrees(iss.sublong), "lat": degrees(iss.sublat) } })
ISS
speed is about 28000 km/h
! It moves very fast, we need to update its position frequently to have a reasonable accuracy (once per second gives an accuracy of about ~8km):
while True: ### update the TLE data once per hour if count > 3600: update_tle() count = 0 count += 1 try: ### compute the ISS position now = datetime.datetime.utcnow() iss.compute(now) print('longitude: %f - latitude: %f' % (degrees(iss.sublong), degrees(iss.sublat))) #Send temperature to Beebotte iss_position_resource.publish({ "timestamp": round(time.time()), "position": { ### transform longitude and latitude to degrees "long": degrees(iss.sublong), "lat": degrees(iss.sublat) } }) ### catch the exceptions darling :) except Exception as inst: print type(inst) # the exception instance print inst.args # arguments stored in .args print inst # #Sleep one second time.sleep( 1 )
We used the API documentation of Google maps and in particular:
Markers
and in particular this examplePolylines
and in particular this exampleTo initialize the map we will use:
var map, marker, isInitialized = false; function InitializeMap(pos) { var options = { zoom: 4, center: pos, mapTypeId: google.maps.MapTypeId.TERRAIN }; // Assuming we have a div with id 'map' in our HTML code map = new google.maps.Map(document.getElementById('map'), options); // Add a marker at the center of the map marker = new google.maps.Marker({ position: map.center, icon: { path: google.maps.SymbolPath.CIRCLE, scale: 5 }, draggable: false, }); marker.setMap( map ); }
To draw the ISS trajectory and update its position marker we will use:
var flightPath = []; // array of positions to draw the trajectory function drawPath (pos) { flightPath.push( pos ); map.setCenter( pos ) var traject = new google.maps.Polyline({ path: flightPath, geodesic: true, strokeColor: '#FF0000', strokeOpacity: 1.0, strokeWeight: 2 }); traject.setMap(map); marker.setPosition( map.center ); // update the position of the marker }
In order to display the position of the ISS in google maps, we need to subscribe
to published position data:
var bbt; // Replace API_KEY with that of your account function init() { bbt = new BBT('API_KEY'); bbt.subscribe( {channel: 'ISS', resource: 'position', read: true, write: false}, function(msg){ var newposition = new google.maps.LatLng( msg.data.position.lat, msg.data.position.long ); if( !isInitialized ) { // Initialize the map InitializeMap( newposition ); } else { // update map with newposition drawPath( newposition ); } }); } google.maps.event.addDomListener(window, 'load', init);
Now every time a position is published (see above), the position of the marker and the trajectory will be updated.
In this tutorial we learned how to compute the real-time position of the ISS, publish it to Beebotte, and display it in Google maps.
You can fork the code on Github
to build awesome apps.