Press "Enter" to skip to content

Category: Space

Musing on Star Trackers

Several years back, I was intrigued by the concept of the “PicoSat” form factor, which is smaller than a CubeSats that instead of costing the same as a house to launch, only cost approximately the price of a car to launch. A few had launched as sub-payloads on a Dnepr, including the $50 Satellite (Eagle-2) which operated for a surprisingly long time.

Gears in my head immediately began churning for a thought exercise on how small you could make things to fit on a PicoSat — Maxon EC10 flat based reaction wheels, miniaturised ablative plasma thrusters, tiny mirror-based zoom lenses, and as the title suggest, star trackers.

Remote sensing satellites need extremely good pointing accuracy in order to take images of what they need to on the ground. While other small scientific missions can typically make do with basic orientation based on sun detection, earth/horizon detection or even passively through gravity gradients, using magnets and hysteresis rods, to be able to take a decent resolution image of anything on the earth, you need better pointing accuracy. that’s where star trackers come in.

Since the stars are relatively stationary in the sky, as with the old days of sail, they can be used for navigation and specifically for highly precise orientation of satellites. The positions of stars in the sky are very well known, including their small relative motion.

As a thought exercise, and as a way to learn some more Python, I wrote a small star tracker program that assumed an input from a 640×480 imager with a small lens in front. I didn’t do any work into determining the actual SNR of the stars as my focus was primarily on the algorithm. Detecting faint stars in orbit is a challenge in and of itself which I won’t address in too much detail in this post. This was all done years ago, so I’m writing mostly off of memory and comments I left scattered around my Python code…

I downloaded the publicly available Hipparcos star catalogue as a basis for my star tracker, which contains the position at the epoch of measurement, as well as their relative motion so I could adjust their positions to the current date.  This catalogue was processed to make a unique catalogue for the star tracker, which included not only position but also relational data comparing each star to neighbouring stars.

For test images, I simply used Stellarium with a representative rectilinear lens configuration. I output the screenshot, loaded it into python and ran the algorithm.

Before I go any further, I want to point to the references at the bottom, as they were used to guide the process of development of this code, notably reference 1 is a great resource and worth a read if you’re interested in learning more about star trackers! A lot of the methods outlined in that document are what I used to develop this code.

The methodology I used was as follows. The code was written to eventually be translated to C for a small microcontroller, so I avoided use of libraries in the core algorithm which wouldn’t have simple, high-performance comparable libraries in the embedded C world.

  1. Detect centers of stars using a weighted average blobing algorithm
  2. Step through stars in order from brightest to least bright, and calculate a “triad” for each:
    1. Find two next brightest stars within a specified distance
    2. Based on the two vectors made up by the two stars centered on the origin star, create a unique relational triad for comparison
  3. After all triads are computed, compare to the catalogue to find the closest match and identify stars and their positions
    1. Perform this iteratively, as multiple hits per star are gained, and there are false alarms
    2. Sort detected stars based on how close the calculated triad was to the matched catalogue value
  4. Starting with the closest match, perform vector space rotation to determine exact match. Refine calculated orientation by running through subsequent matches.
Sample Results, Centred on HIP59928
Sample Results, Centered on HIP59928

Results of the full algorithm. Stars found by blobbing are circled in green, with a red dot in their centre and with a yellow index number assigned. Red lines indicate all the triads considered in the match, and the detected star Hipparcos catalogue numbers are shown in white/blue. Only stars in the center yellow rectangle were used as the basis for triads, as anything outside of that risked having the next adjacent bright star out of frame, leading to erroneous results. Pretty accurate overall!

Algorithm Outputs Centred on HIP3821
Algorithm Outputs Centred on HIP3821

Now, this algorithm isn’t sufficient for a real star tracker, as several problems would still need to be addressed:

  • Planets
  • Noise in image due to low SNR
  • Real star-trackers are often de-focused to create larger blurry stars to aide with centroiding. This would require adjustments.
  • How to deal with bright objects (e.g. sun). Usually accomplished with shrouds
  • Rotational accuracy is usually not great with star trackers, requiring two pointing in different directions to get peak accuracy
  • etc….


  1. Raveesh Kandylil – Attitude Determination Software for a Star Sensor
  2. Wiley J. Larson and James R. Wertz, Space Mission Analysis and Design (There’s a newer version: Space Mission Engineering: The new SMAD)
Leave a Comment