Tracking the Space Station with Python to Take a Space Selfie

How do I look from on orbit?

Posted by Space Cadet on Jan. 7, 2017, noon

First Look

When I first purchased my Epson BT-200 augmented reality glasses they got me thinking: "I wonder if there is some kind of video feed of the Earth from space? Wouldn't it be cool to put on these glasses and have a view out over the Earth from space like you were up there flying?" Well, it turns out that there is just such a thing and after a quick search on YouTube I was able to find some HD videos (some of them live) of the Earth captured from the International Space Station (ISS): NASA HDEV

There is an ongoing experiment on the ISS known as the High Definition Earth Viewing System or HDEV for short. It has 4 cameras that look down at the Earth. They look either forward towards the direction the station is orbiting, directly down at the Earth, or backwards (known in space-lingo as "nadir"). NASA provides a video feed from these cameras that can be live streamed via the Internet. You can find that video stream here: USTREAM: ISS HD Earth Viewing Experiment.

So watching Earth from the camera on the Internet is very relaxing, especially using augmented reality glasses. These provide the impression that you're actually up there flying along with the station and its astronauts. But this got me thinking... Where exactly is the station flying over? There are several websites and even a few mobile apps that allow you to track the station in real-time. This allowed me to cross-reference the video I was seeing from the station with maps on the ground. Very cool!

Snapping A Space-Selfie (Manually)

After a few weeks of watching this feed and tracking the station here and there using an app, I started to anticipate when it would fly over Los Angeles (where I live) and then snap a screenshot if I noticed it was close. This was fun but it was also kind of a tedious process. If I noticed the space station was close to LA I would then try to run to my computer and be ready in time to snap a screenshot just as it flys over. I only managed to do it only once. Usually the station would be fly right by and that would be it.

Los Angeles, California (October 14, 2016)
Photo from HDEV Experiment

Hacking Tracking The Station

Taking space-selfies manually is not a very efficient process because it is rare that you will notice right before the space station flies over your head. Since there are many apps and websites that track the station (like this one: HDEV Live - Spaceflight101 Live) I figured that there must be a much more programatic way to do it. If there is a programatic way to do something chances are there is a Python module that can do it for you. So I took to Google to see if I could find some leads. A few quick searches turned up some promising results. It turns out there is a Python package for tracking satellites, called "PyEphem", but also some very helpful blog articles explaining how it works.

Orbital Mechanics

Using these blog posts as a guide I began to build my own scripts for tracking the station. The first thing I wanted to do was plot the orbits where the station will be flying over a point on the ground that is close to my home in Los Angeles, California. Here is code to graph the next 30 passes where the space station will be visible from Los Angeles somewhere on the horizon. It will graph darker lines when the station will pass closer to directly over LA:

from mpl_toolkits.basemap import Basemap
from geopy.distance import great_circle
from matplotlib import colors
from pyorbital import tlefile
import matplotlib.pyplot as plt
import numpy as np
import math
import ephem

tlefile.TLE_URLS = (
    'http://celestrak.com/NORAD/elements/stations.txt',
)
iss_tle = tlefile.read('ISS (ZARYA)')
iss = ephem.readtle("ISS (ZARYA)", iss_tle.line1, iss_tle.line2)
obs = ephem.Observer()
# Marina del Rey
mdr_lat = 33.9803
mdr_lon = -118.4517
obs.lat = str(mdr_lat)
obs.long = str(mdr_lon)
# set up orthographic map projection
map = Basemap(projection='ortho', lat_0=mdr_lat, lon_0=mdr_lon, resolution='l')
# draw coastlines, country boundaries, fill continents.
map.drawcoastlines(linewidth=0.25)
map.drawcountries(linewidth=0.25)
map.fillcontinents(color='coral',lake_color='aqua')
# draw the edge of the map projection region (the projection limb)
map.drawmapboundary(fill_color='aqua')
# draw lat/lon grid lines every 30 degrees.
map.drawmeridians(np.arange(0,360,30))
map.drawparallels(np.arange(-90,90,30))
# plot
passes = 30
for p in range(passes):
    coords = []
    dists = []
    tr, azr, tt, altt, ts, azs = obs.next_pass(iss)
    while tr < ts:
        obs.date = tr
        iss.compute(obs)
        iss_lat = math.degrees(iss.sublat)
        iss_lon = math.degrees(iss.sublong)
        dist = great_circle((mdr_lat, mdr_lon), (iss_lat, iss_lon)).miles
        coords.append([iss_lon, iss_lat])
        dists.append(dist)
        tr = ephem.Date(tr + 30.0 * ephem.second)
    md = min(dists)
    imd = 1 - (float(md) / 1400)
    hue = float(240) / float(360)
    clr = colors.hsv_to_rgb([hue, imd, 1])
    map.drawgreatcircle(coords[0][0], coords[0][1], coords[-1][0], coords[-1][1], linewidth=2, color=clr)
    obs.date = tr + ephem.minute
plt.title('Next '+ str(passes)+ ' ISS Passes Visible From Los Angeles')
plt.show()

Here is the result when running this program on Saturday, January 7, 2017:

Automatic Space-Selfies

Once it was possible to track when the space station would be overhead I adapted the script to filter out the passes that were too far away (> 250 miles, not including verical distance). Then I added the "livestreamer" program to automatically record HDEV streams when the station is going to fly over. In order to trigger the recording I built a shell script that is triggered by the Unix "at" daemon. This also required that passes be filtered for when the area being observed, in this case Los Angeles, is illuminiated during daylight hours. The cameras on the HDEV are not able to see anything during night time, which the station enters about every 45 minutes on each ~90 minute orbit around the Earth.

Viewing More Cities

After taking a few "space-selfies" of Los Angeles it occured to me that the space station flies all over the place. All I needed to do was expand my script to predict when the station would fly over other cities, during daylight hours of course, and then record the streams as the station flies over those areas. These are the cities which I added to my list to be recorded: Los Angeles, Columbus, Cleveland, New York, Chicago, Las Vegas, San Francisco, Miami, Denver, Honolulu, Jerusalem, Hong Kong, Rome, Athens, Cairo, Cape Town, London, Beijing, Tokyo, Paris, Perth & Moscow.

It turns out that some cities are much easier than others to take photos of because they are either close to the Earth's south pole which means the station flys close to them very frequently, or they are in an area close to the desert which doesn't usually have a lot of cloud cover. Cities next to water are also much easier to find on these flyovers. It turns out the many other cities are just too cloudly to get good pictures of most of the time, but with this script it is easy to keep trying until the space station flys over them on a sunny day.

Here are some pictures that I've captured of various cities:

Final Thoughts

It's been lots of fun tracking the space station on orbit and photographing the Earth from space. I wanted to give a shout out to NASA, Roscosmos and friends for building and successfully operating the International Space Station. Another shout out to the dedicated Expedition 50 crew members! Also, much thanks to the HDEV project team for creating a wonderful experiment. Good work! Maybe next time this experiment can be improved with even more high-resolution cameras. (4K would be amazing!). In the meantime, we'll keep watching as the space station flies over.

The source code for all of the space station tracking scripts are available on GitHub: