Satellite Tracker
After learning how to find satellites, I wanted as many as possible. I was combing through passes to find ones with a high enough elevation, sorting them by azimuth to see which location I would go to, planning outings with passes close together, and beginning to realize a problem. I felt I was spending more time finding the passes than actually doing them. AmSat is nice for pass data, but I wanted the data filtered way more than they offered. I also wanted visuals. What does the pass look like on a plot of azimuth and elevation? How far would I be able to reach with the satellite’s repeater?
I had already figured out the math required to track satellites from my Antenna Pointer project, so I decided to develop that work into a program to meet my requirements. I chose Python as my language of choice because I wanted to become more familiar with it and it had several options for 2D and 3D plots I liked. Once I had translated my math from MATLAB to Python, it was time to add features.
A major issue with the Antenna Pointer is the Keplerian elements have to be manually updated, so the first thing I worked on was ensuring I wouldn’t have to do that. I found a website called CelesTrak that gives two-line elements sets not just for amateur radio satellites, but any.
I set about making visuals of a satellite pass. Once you can find the current location of a satellite, predicting its future location is not much harder and I was easily about to find its path and filter by positive elevation. I took the array of points and used MatPlotLib to create polar graphs.
I noticed my graphs were off from what AmSat predicted and started debugging the problem. I checked my new work first, but it turns out it was my analysis. My and AmSat’s numbers were the same at first, but drifted apart as our predictions got further out in time. This was the first time I used my math to get future locations, so I had not noticed this issue in my previous project.
I do not account for atmospheric drag in my analysis, but many of the satellites I track are low enough to be affected, so I am guessing this is the reason for the issue. My predictions are still within a few degrees after a few days, so it won’t affect finding them with an antenna, but I need to go back and do some more work so it stays accurate for longer.
The polar plots were nice references to have during the satellite passes, but the 2D format did not cover other features I wanted, so I moved on. I used VPython for 3D graphics and was able to plot a curve by removing the end part of my analysis.
Up to this point, my program had been taking specific inputs in VS Code, so I added a command line in the Vpython window. I did this by creating a label at the origin, which works well until you move where the screen is centered. It’s not ideal, but I didn’t see a clean way to put it outside the graphics window, so I added it to my fix list and moved on with adding commands.
The first command I added is what I most commonly filter for– a minimum elevation and within a certain time frame. It works with negative elevation, so it’s possible to see a full pass.

When testing this, I realized a problem. The pass fully lines up with itself, which is not what I would see on Earth. I had put everything into ECI coordinates, which worked fine for azimuth and elevation. In 3D, the Earth would have to be rotating for accuracy and this would involve adding a changable time. I just wanted to focus on space for now, so I added a view in ECEF.

I had already figured out the conversion from ECEF to ECI and shifting the other way was as simple as using the inverse of the rotation matrix. I added buttons to switch between the two systems and this is where a shift occured in my project.
I had intended for this project to be used to help me plan satellite contacts, but I found myself way more interested in how different orbits looked between the two systems than in the filtering system I planned to work on. To aid me in looking at different orbits, I added labels and different colors. I also created a list of displayed passes and added commands to hide and delete plotted passes.

I added another filter based on the number of passes instead of the amount of time. This led to some interesting comparisons between ECEF and ECI I hadn’t realized where the satellite is in slightly different parts of its orbit when passing overhead.

Now I focused on another requirement– seeing satellite range. It would be cool to know how far I could theoretically reach while the satellite was overhead, so I included a satellite footprint. I had a false start when programming it and ended up figuring out the correct solution on paper during a car ride. Once I got home again, I added it to my program to make a cone coming from the satellite and projecting onto the Earth. The footprint is not quite accurate as the Earth is assumed to be a perfect sphere, but it still gives a nice visual range.

This is what I was able to complete during the summer and it’s a little awkward to end this because the project isn’t really done. I still have a bunch of features I want to add to both make this more useful for amateur radio and to explore other aspects of satellites. There are still two unused numbers in the TLE– the first and second derivatives of mean motion. I believe they come into effect when satellites fall out of orbit, but I’ll need to do some research and find a way to incorporate it into the project. For now, it’s been a fun way to expand my previous work with with visuals and to continue my series of satellite projects.