Introduction

The goal of this project was simple - create a visualization to display the current position of the ISS in real-time. This was my first major attempt to create a display to be used on my new 64x32 RGB matrix from Adafruit.

The red dot on the image above represents the ISS and the green dot shows my current location. Displayed on the left there is time, ISS latitude, ISS longitude, and the number of astronauts on board (one coloured square for each).

The source code for this project can be found here.

# Parts

The following are the parts that I used to build this project. Most of them were purchased from Adafruit.

- 64x32 RGB LED Matrix - 3mm pitch
- Adafruit RGB Matrix Bonnet for Raspberry Pi
- 5V 10A switching power supply
- SD/MicroSD Memory Card (8 GB SDHC)
- Raspberry Pi 4 Model B
- Official Raspberry Pi Power Supply 5.1V 3A with USB C

# The Spinning Globe

To get this to work, I needed to brush up on my linear algebra skills. I used this video as a starting point for my code. It explains how to convert from a spherical coordinate system to a Cartesian coordinate system, initialize a numpy matrix to store the coordinates for the sphere, and how to apply a rotation matrix. The video describes how to use this to draw an ASCII Earth with pygame, but I managed to adapt it to work with the RGB matrix.

## Generating the nodes

First, for each latitude (north/south) I iterated over a number of longitudes (east/west) and converted the latitude/longitude pair to a xyz coordinate. These coordinates were then converted to a numpy matrix. The `add_nodes()`

and `convert_coords()`

methods were written to achieve this.

Converting from spherical to Cartesian coordinates is done using the following equations:

$x=rsinθcosφ $

$y=rcosθ $

$z=rsinθsinφ $

When given standard latitude and longitude values as input, $θ$ is the complement of the latitude, or co-latitude, and $φ$ is the complement of the longitude. $r$ is the radius of the sphere. The following image from the Wikipedia article helps illustrate this.

Note

I switched the equations for y and z to allow y to represent the vertical axis.

Here is the code the implements this:

## Drawing the nodes

Once the nodes have been initialized they can be drawn to the screen. Drawing is done using the PIL library. On each frame, a 64x32 PIL image is created and sent to the RGB matrix to be drawn. To create the frame, each node is iterated over and the pixel at the `x`

and `y`

coordinate is drawn (only if `z > 1`

to only draw nodes in the foreground).

This is what the result looks like before a bitmap of the Earth is applied. The resolution can easily be increased by changing the `MAP_WIDTH`

and `MAP_HEIGHT`

variables before the nodes get created. The resolution below is lower than what is used in the final result. The higher the resolution the more computations are needed when rotating and drawing the sphere.

## Making it spin

Making the sphere spin is relatively easy with a little more linear algebra. On every frame, before it gets drawn, all we have to do is apply a rotation matrix to the node array that rotates each node by some angle $θ$. This can be done with the `matmul()`

function provided by numpy. The matrix used in the code will spin the nodes around the vertical axis.

This will produce the following result:

## Adding the Earth bitmap

To actually make the sphere look like the Earth I took a black and white image of the Earth and reduced its size to `MAP_WIDTH`

by `MAP_HEIGHT`

. I then converted the image to an array of bits, 1 for a white pixel and 0 for a black pixel. When drawing the Earth I then check the array at the index for the corresponding node and only draw the pixel if the bit is 1. The following image is converted with the code below:

## Drawing the ISS

Drawing the ISS on the sphere is very similar to drawing the nodes for the Earth. Every 5 seconds I’m sending a request to an API which returns the current latitude and longitude for the ISS. I take this information and generate a node matrix with a single node for the ISS. The rotation matrix is applied to this new ISS matrix as well. Then when drawing the frame, I change the pixel for where the ISS is to red.

I do the same process to draw the green dot for my location.

# Final result

A video of the final ISS tracking display running on the RGB matrix can be found here.

This was a really fun project that forced me to brush up on my linear algebra. It is a cool visualization to leave running in the background.