Notes on Celestial Navigation

CNSUMNER - Calculate the Observer's Position Using Sumner's Method

Description: The program calculates the latitude and longitude of the observer's position from two sights, either simultaneous (\(DMG = 0\)) or as a running fix (\(DMG > 0\)), using Sumner's method.

Inputs:

Dr LatThe DR latitude of the observer
EW sight 1Sight 1 east (E) or west (W)
GHA sight 1GHA of the celestial object from sight 1
Dec sight 1Declination of the celestial object from sight 1
H sight 1Height/Altitude of the celestial object from sight 1
DMGDistance made good between sights 1 and 2 (running fix)
CMGCourse made good between sights (\(DMG > 0\))
EW sight 2Sight 2 east (E) or west (W)
GHA sight 2GHA of the celestial object from sight 2
Dec sight 2Declination of the celestial object from sight 2
H sight 2Height/Altitude of the celestial object from sight 2

Outputs:

LatThe calculated latitude of the observer
LonThe calculated longitude of the observer

Sample execution:

DR Lat sight 1? 38,30
Sight 1 E or W? e
GHA sight 1? 13,22
Dec sight 1? 20,03.3
H sight 1? 66,49.7
DMG (NM)? 30
CMG (d,m)? 25,0
Sight 2 E or W? w
GHA sight 2? 43,22
Dec sight 2? 20,02.3
H sight 2? 67,11

Lat = 39° 12.1'
Lon = -28° 56.5'

(For explanation of notation, conventions etc, see python-programs).



Copyright (C) 2024 Ian Staniforth

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.


# CNSUMNER - Calculate a fix from 2 Sights using Sumner's Method

from math import *
from CN_LIB import *

# Longitude by Chronometer

def lonchron(lat,gha,dec,h,ew):
    p = aCos((Sin(h)-Sin(lat)*Sin(dec))/(Cos(lat)*Cos(dec)))
    if ew.startswith("e"): p = 360-p
    lon = p-gha
    if lon > 180: lon-= 360
    if lon < -180: lon+= 360
    return(lon)

lat = stod("DR Lat sight 1? ")
lat1 = floor(lat)
lat2 = lat1+1.0

# First sight

ew1 = input("Sight 1 E or W? ").lower()
gha1 = stod("GHA sight 1? ")
dec1 = stod("Dec sight 1? ")
h1 = stod("H sight 1? ")

lon11 = lonchron(lat1,gha1,dec1,h1,ew1)
lon12 = lonchron(lat2,gha1,dec1,h1,ew1)

# Running fix?

dmg = float(input("DMG (NM)? "))
if (dmg > 0):
    cmg = stod("CMG (d,m)? ")
    dlat = dmg*Cos(cmg)/60
    dlon = dmg*Sin(cmg)/Cos(lat)/60
    e = -(lon12-lon11)*dlat+dlon
    lon11 = lon11+e
    lon12 = lon12+e

# Second sight

ew2 = input("Sight 2 E or W? ").lower()
gha2 = stod("GHA sight 2? ")
dec2 = stod("Dec sight 2? ")
h2 = stod("H sight 2? ")

lon21 = lonchron(lat1,gha2,dec2,h2,ew2)
lon22 = lonchron(lat2,gha2,dec2,h2,ew2)

# Intersection of Sumner Lines

y1 = 0
y2 = lat2-lat1
x11 = 0
x12 = lon12-lon11
x21 = lon21-lon11
x22 = lon22-lon11


x = (x12*x21)/(x12+x21-x22)
y = (y2/x12)*x

lat = y+lat1
lon = x+lon11

print("")
print("Lat = "+dtos(lat))
print("Lon = "+dtos(lon))