[Mount] Converting between equatorial coordinates and horizontal coordinates

The first problem that emerges in the design of the mount is the conversion between the equatorial coordinate system (Right Ascension – declination system) and the horizontal coordinate system (altitude – azimuth).

The reason why this is important is essentially the following:

The circular path of stars is a result of the rotation of the earth. But due to the inclination angle of the rotational axis of the earth, there is a small angle between the earth’s north pole and the celestial sphere’s north pole. In the equatorial coordinate system (same as the horizontal coordinate system, but for the celestial sphere instead of the earth), keeping track of the stars would be easy: we only need to rotate one axis (the Right Ascension), because the positions of the stars on the celestial sphere is fixed, and we only need to rotate around the axis of the celestial sphere at the same speed (namely 24 hour/rotation, the rate of the earth’s rotation) to catch up with the celestial sphere and hence the stars on it.

This is how most traditional equatorial mounts work — to have the two axels inclined such that one of them is aligned with the celestial polar axis. This is also why in the previous design I had, I tilted the frame on which the telescope was set up.

However, in this design, I would like to simplify the mount structurally as much as possible. Plus I am going to motorize both axels anyways, it’s possible to calculate the equivalent motions in altitude and azimuth in the horizontal coordinate system, and keep track of the stars this way. To do this, we first need to be able to convert between the two systems (maybe only in one way: from equatorial to horizontal, but just in case).

There are two major methods to do this. The first one is to do some trigonometrical operations on what is called the Astronomical Triangle (the indices of which being the zenith, the celestial north pole, and the star being observed) (see here for more details), and the second one is to perform some transformations using matrices (see here for more details). After reading both articles, I decided to use the first one. The specific algorithm is pretty clearly explained in that article so… Here goes the code (If you don’t see the code below, click here):

# Created July 4, 2016
# Last Major Modification July 15, 2016
# Author Sibo W
import datetime
import pytz
import math
def get_lst(long, time):
'''Takes in: long observer's longitude in degrees, east as positive
time the time to be calculated in datetime type
use 'NOW' if current time is wanted
Returns Local (Mean) Sidereal Time.
The observer's east longitude has been neglected.'''
# Define subclsss UTC of tzinfo
UTC = pytz.timezone('UTC')
# Initialize current time if necessary
if time == 'NOW':
time = datetime.datetime.utcnow().replace(tzinfo = UTC)
# Calculate number of days since J2000
J2000 = datetime.datetime(2000, 1, 1, 11, 58, 55, 816000, UTC)
# Note that J2000.0 = January 1, 2000, 12:00:00.000 Terrestrial Time
# = January 1, 2000, 11:58:55.816 UTC
days = (time J2000).total_seconds() / 86400
gst = days * 360.98562628 + 280.46061837
# Note that the earth rotates 366.25 * 360 / 365.25 = 360.98562628
# degrees each solar day
# Add the sidereal angle at J2000.0 at Prime Meridian 280.46061837
lst = (gst + long) % 360
return lst
def equatorial2horizontal(ra, dec, lst, lat):
'''Given Right Ascension ra in degrees
Declinition dec in degrees
Local Sidereal Time lst in degrees
Observer's latitude lat0 in degrees
Returns tuple (altitude, azimuth), both in degrees
'''
ra = math.radians(ra)
dec = math.radians(dec)
lst = math.radians(lst)
lat = math.radians(lat)
hour_angle = (lst ra)
# calculates hour angle (lst – ra)
temp = math.sin(dec) * math.sin(lat) + \
math.cos(dec) * math.cos(lat) * math.cos(hour_angle)
# where temp = sin(altitude)
altitude = math.asin(temp)
# gets altitude and converts it into degrees
temp = math.sin(hour_angle) * math.cos(dec) / math.cos(altitude)
# where temp = sin(azimuth)
altitude = math.degrees(altitude)
azimuth = math.degrees(math.asin(temp))
# gets altitude and converts it into degrees
azimuth %= 360
return altitude, azimuth
def horizontal2equatorial(alt, azi, lst, lat):
'''Given Azimuth azi in degrees
Altitude alt in degrees
Local Sidereal Time lst in hours
Observer's latitude lat0 in degrees
Returns tuple (Right Ascension, declination), both in degrees
'''
azi = math.radians(azi)
alt = math.radians(alt)
lst = math.radians(lst)
lat = math.radians(lat)
temp = math.sin(alt) * math.sin(lat) + \
math.cos(alt) * math.cos(lat) * math.cos(azi)
# where temp = sin(declination)
declination = math.asin(temp)
# gets declination and converts it into degrees
temp = math.sin(azi) * math.cos(alt) / math.cos(declination)
# where temp = sin(hour angle)
declination = math.degrees(declination)
hour_angle = math.degrees(math.asin(temp))
# gets hour angle and converts it into degrees
ra = math.degrees(lst) hour_angle
# gets Right Ascension from hour angle and lst
return (ra, declination)
# TEST CASES
# UTC = pytz.timezone('UTC')
# test = datetime.datetime(2016, 7, 15, 7, 0, 0, 0, UTC)
# lst = get_lst(172, test)
# print(lst)
#
# print(equatorial2horizontal(120, 20, lst, 33))
#
# print(horizontal2equatorial(10.17, 287.33, lst, 33))

view raw
coord_transfer.py
hosted with ❤ by GitHub

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s