sgp4go

package module
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 15, 2025 License: MIT Imports: 5 Imported by: 0

README

SGP4Go

Yet another SGP4 port. This is a Go implementation of the NORAD SGP4/SDP4 orbital propagation models, translated from the original code by David Vallado & Dr. TS Kelso.

Beta version

Features

  • Complete SGP4/SDP4 Implementation: Full translation of the NORAD orbital models
  • TLE Parsing: Parse standard Two-Line Element sets
  • Simple Propagation API: Single function with optional units parameter
  • Flexible Units: Optional units parameter - Earth radii (default) or kilometers
  • Testing: Unit tests and validation against known results
  • Go Idioms: Go error handling, type safety, and modern Go coding patterns

Installation

go get github.com/TrainedTrex/sgp4go

Quick Start

package main

import (
    "fmt"
    "time"
    "github.com/TrainedTrex/sgp4go"
)

func main() {
    // Parse a TLE
    line1 := "1 25544U 98067A   25224.47423135  .00010254  00000+0  18430-3 0  9994"
    line2 := "2 25544  51.6349  28.0780 0001172 181.8871 178.2114 15.50477111523893"
    
    tle, err := sgp4.ParseTLE(line1, line2)
    if err != nil {
        panic(err)
    }

    // Access TLE fields
    fmt.Printf("Satellite: %s\n", tle.SatelliteNumber)
    fmt.Printf("Epoch: %f\n", tle.Epoch)
    fmt.Printf("Julian Epoch: %f\n", tle.JulianEpoch)
    fmt.Printf("Inclination: %f degrees\n", tle.Inclination)
    fmt.Printf("Orbital Period: %f minutes\n", tle.GetOrbitalPeriod())

    // Propagate using different methods
    now := time.Now()
    
    // Convert time to Julian date for propagation
    jd := sgp4.TimeToJulianDate(now)
    
    // Method 1: Earth radii (default)
    pos, vel, err := sgp4.PropagateSatellite(tle, jd)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Position (Earth radii): X=%f, Y=%f, Z=%f\n", pos.X, pos.Y, pos.Z)
    
    // Method 2: Kilometers (with "km" parameter)
    posKm, velKm, err := sgp4.PropagateSatellite(tle, jd, "km")
    if err != nil {
        panic(err)
    }
    fmt.Printf("Position (km): X=%f, Y=%f, Z=%f\n", posKm.X, posKm.Y, posKm.Z)
    fmt.Printf("Velocity (km/s): X=%f, Y=%f, Z=%f\n", velKm.X, velKm.Y, velKm.Z)
}

API Reference

TLE Struct
type TLE struct {
    SatelliteNumber   string  // Satellite catalog number
    Epoch             float64 // TLE epoch (year + day of year)
    JulianEpoch       float64 // Julian date of epoch
    MeanMotionDot     float64 // First derivative of mean motion
    MeanMotionDDot    float64 // Second derivative of mean motion
    MeanMotionDDotExp int     // Exponent for MeanMotionDDot
    BStar             float64 // B* drag term
    BStarExp          int     // Exponent for BStar
    ElementSet        string  // Element set number
    Inclination       float64 // Inclination (degrees)
    RightAscension    float64 // Right ascension of ascending node (degrees)
    Eccentricity      float64 // Eccentricity
    ArgumentPerigee   float64 // Argument of perigee (degrees)
    MeanAnomaly       float64 // Mean anomaly (degrees)
    MeanMotion        float64 // Mean motion (revolutions per day)
}

Convenience Methods:

  • GetJulianEpoch() float64 - Returns Julian epoch
  • GetEpoch() float64 - Returns TLE epoch
  • GetSatelliteNumber() string - Returns satellite number
  • GetElementSet() string - Returns element set number
  • GetOrbitalPeriod() float64 - Returns orbital period in minutes
SatelliteData Struct

All fields are publicly accessible:

type SatelliteData struct {
    TLE TLE // Original TLE data
    
    // Converted orbital elements
    XMO, XNodeO, OmegaO, EO, XIncl, XNO, XNDT2O, XNDD6O, BStar float64
    JulianEpoch, XKE                                           float64
    
    // Model flags
    IFlag, IDeep int
    
    // Derived constants for SGP4
    EQSQ, SINIQ, COSIQ, RTEQSQ, AO, COSQ2, SINOMO, COSOMO float64
    BSQ, XLLDOT, OMGDT, XNODOT, XNODP                     float64
    
    // Deep space variables
    XLL, OMGASM, XNODES, EM, XINC, XN, T float64
    QOMS2T                               float64
}

Convenience Methods:

  • GetJulianEpoch() float64 - Returns Julian epoch
  • GetOrbitalPeriod() float64 - Returns orbital period in minutes
  • IsDeepSpace() bool - Returns true if deep space model is needed
  • GetInclination() float64 - Returns inclination in degrees
  • GetEccentricity() float64 - Returns eccentricity
  • GetMeanMotion() float64 - Returns mean motion in revs/day
Main Functions
TLE Parsing
func ParseTLE(line1, line2 string) (*TLE, error)
func ParseFloat(s string) (float64, error)
Satellite Data Conversion
func ConvertSatelliteData(tle *TLE) (*SatelliteData, error)
Propagation (High-Level)
func PropagateSatellite(tle *TLE, time float64, units ...string) (Vector, Vector, error)

Note: The units parameter is optional. Pass "km" to get results in kilometers, or omit for Earth radii (default). For time.Time objects, use TimeToJulianDate() to convert first.

Propagation (Low-Level)
func SGP(time float64, sat *SatelliteData) (Vector, Vector, error)
func SGP4(tsince float64, sat *SatelliteData) (Vector, Vector, error)
func SDP4(tsince float64, sat *SatelliteData) (Vector, Vector, error)
Time Conversions
func JulianDateOfEpoch(epoch float64) float64
func JulianDate(year, month, day int) float64
func JulianDateToTime(jd float64) time.Time
func TimeToJulianDate(t time.Time) float64
func DaysSinceEpoch(julianEpoch, julianDate float64) float64
func MinutesSinceEpoch(julianEpoch, julianDate float64) float64
Mathematical Functions
func Sign(arg float64) int
func Square(arg float64) float64
func Cube(arg float64) float64
func Power(arg, pwr float64) float64
func Radians(arg float64) float64
func Degrees(arg float64) float64
func Tan(arg float64) float64
func ArcSin(arg float64) float64
func ArcCos(arg float64) float64
func Modulus(arg1, arg2 float64) float64
func Fmod2p(arg float64) float64
func AcTan(sinx, cosx float64) float64
Vector Operations
func Magnitude(v *Vector)
func VecAdd(v1, v2 Vector) Vector
func VecSub(v1, v2 Vector) Vector
func ScalarMultiply(k float64, v Vector) Vector
func Dot(v1, v2 Vector) float64
func Angle(v1, v2 Vector) float64
func Cross(v1, v2 Vector) Vector
func Normalize(v *Vector)
Unit Conversions
func ConvertPositionToKilometers(pos *Vector)
func ConvertVelocityToKilometersPerSecond(vel *Vector)
func ConvertPositionAndVelocityToKilometers(pos, vel *Vector)

Examples

See the examples/ directory for complete examples:

  • main.go - Basic usage example

Testing

Run the test suite:

go test ./tests/...

Implementation Notes

This is a direct translation from the original SGP4/SDP4 implementation by David Vallado and Dr. TS Kelso. The code maintains the same algorithms and numerical operations as the original while taking advantage of Go's type safety and error handling.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Original SGP4/SDP4 implementation by David Vallado & Dr. TS Kelso
  • Based on NORAD SGP4 orbital models
  • Translation maintains fidelity to the original algorithms

Documentation

Index

Constants

View Source
const (
	// Earth constants
	AE     = 1.0          // Earth equatorial radius in Earth radii
	TOTHRD = 2.0 / 3.0    // 2/3
	XKMPER = 6378.135     // Earth equatorial radius - kilometers (WGS '72)
	F      = 1.0 / 298.26 // Earth flattening (WGS '72)
	GE     = 398600.8     // Earth gravitational constant (WGS '72)

	// Harmonic coefficients
	J2 = 1.0826158e-3 // J2 harmonic (WGS '72)
	J3 = -2.53881e-6  // J3 harmonic (WGS '72)
	J4 = -1.65597e-6  // J4 harmonic (WGS '72)

	// Derived constants
	CK2 = J2 / 2.0        // J2/2
	CK4 = -3.0 * J4 / 8.0 // -3*J4/8
	XJ3 = J3              // J3

	// Atmospheric constants
	QO = AE + 120.0/XKMPER // Atmospheric boundary
	S  = AE + 78.0/XKMPER  // Atmospheric boundary

	// Numerical constants
	E6A = 1e-6 // Small number for numerical stability

	// Deep space model flags
	DPINIT = 1 // Deep-space initialization code
	DPSEC  = 2 // Deep-space secular code
	DPPER  = 3 // Deep-space periodic code

	// Time constants
	TWOPI  = 2.0 * PI // 2π
	XMNPDA = 1440.0   // Minutes per day
)

Physical constants from WGS-72 model

View Source
const (
	WGS72OLD = 1
	WGS72    = 2
	WGS84    = 3
	PI_C     = 3.14159265358979323846
	TWOPI_C  = 2.0 * PI_C
	DEG2RAD  = PI_C / 180.0
)

Constants from the C code

View Source
const MAX_SATS = 250

Maximum number of satellites that can be stored

View Source
const (
	PI = 3.14159265358979323846264338327950288419716939937510582097494459 // https://oeis.org/A000796
)

Mathematical constants

Variables

This section is empty.

Functions

func AcTan

func AcTan(sinx, cosx float64) float64

AcTan returns the arctangent of sinx/cosx, handling quadrant correctly

func Angle

func Angle(v1, v2 Vector) float64

Angle returns the angle between two vectors in radians

func ArcCos

func ArcCos(arg float64) float64

ArcCos returns the arccosine of a number

func ArcSin

func ArcSin(arg float64) float64

ArcSin returns the arcsine of a number

func CalculateXKE

func CalculateXKE() float64

CalculateXKE calculates the Earth's gravitational parameter in Earth radii^3/min^2

func ConvertPositionAndVelocityToKilometers

func ConvertPositionAndVelocityToKilometers(pos, vel *Vector)

ConvertPositionAndVelocityToKilometers converts both position and velocity to kilometers

func ConvertPositionToKilometers

func ConvertPositionToKilometers(pos *Vector)

ConvertPositionToKilometers converts position from Earth radii to kilometers

func ConvertSatState

func ConvertSatState(pos, vel *Vector)

ConvertSatState converts position and velocity from Earth radii to kilometers

func ConvertVelocityToKilometersPerSecond

func ConvertVelocityToKilometersPerSecond(vel *Vector)

ConvertVelocityToKilometersPerSecond converts velocity from Earth radii/minute to kilometers/second

func Cube

func Cube(arg float64) float64

Cube returns the cube of a number

func DaysSinceEpoch

func DaysSinceEpoch(julianEpoch, julianDate float64) float64

DaysSinceEpoch calculates the number of days since the TLE epoch

func Degrees

func Degrees(arg float64) float64

Degrees converts radians to degrees

func Dot

func Dot(v1, v2 Vector) float64

Dot returns the dot product of two vectors

func Dpper added in v0.1.3

func Dpper(e3, ee2, peo, pgho, pho, pinco, plo, se2, se3, sgh2, sgh3, sgh4, sh2, sh3, si2, si3, sl2, sl3, sl4, t, xgh2, xgh3, xgh4, xh2, xh3, xi2, xi3, xl2, xl3, xl4, zmol, zmos float64, init byte, rec *ElsetRec, opsmode byte)

Dpper provides deep space long period periodic contributions - exact replica from C code

func Dscom added in v0.1.3

func Dscom(epoch, ep, argpp, tc, inclp, nodep, np float64, rec *ElsetRec)

Dscom provides deep space common items - exact replica from C code

func Dsinit added in v0.1.3

func Dsinit(tc, xpidot float64, rec *ElsetRec)

Dsinit provides deep space contributions to mean motion dot - exact replica from C code

func Dspace added in v0.1.3

func Dspace(tc float64, rec *ElsetRec)

Dspace provides deep space contributions to mean elements - exact replica from C code

func Fmod2p

func Fmod2p(arg float64) float64

Fmod2p returns the modulus of arg with respect to 2π

func GetGravConst added in v0.1.3

func GetGravConst(whichconst int, rec *ElsetRec)

GetGravConst sets gravitational constants based on whichconst

func Gstime added in v0.1.3

func Gstime(jdut1 float64) float64

Gstime finds the Greenwich sidereal time

func InitL added in v0.1.3

func InitL(epoch float64, rec *ElsetRec)

InitL initializes the SGP4 propagator - exact replica of initl from C code

func JulianDate

func JulianDate(year, month, day int) float64

JulianDate calculates the Julian date for a given year, month, and day Based on Astronomical Formulae for Calculators, Jean Meeus, pages 23-25

func JulianDateOfEpoch

func JulianDateOfEpoch(epoch float64) float64

JulianDateOfEpoch converts a TLE epoch (year + day of year) to Julian date

func JulianDateToTime

func JulianDateToTime(jd float64) time.Time

JulianDateToTime converts a Julian date to a Go time.Time Based on Astronomical Formulae for Calculators, Jean Meeus, pages 26-27 and the Pascal implementation in SGP_TIME.PAS

func JulianToTimeAstronomical

func JulianToTimeAstronomical(jd float64) time.Time

Alternative implementation using astronomical algorithm This is more accurate for dates far from the modern era

func Magnitude

func Magnitude(v *Vector)

Magnitude calculates the magnitude of a vector

func Max

func Max(arg1, arg2 int) int

Max returns the maximum of two integers

func Min

func Min(arg1, arg2 int) int

Min returns the minimum of two integers

func MinutesSinceEpoch

func MinutesSinceEpoch(julianEpoch, julianDate float64) float64

MinutesSinceEpoch calculates the number of minutes since the TLE epoch

func Modulus

func Modulus(arg1, arg2 float64) float64

Modulus returns the remainder of arg1 divided by arg2

func Normalize

func Normalize(v *Vector)

Normalize normalizes a vector to unit length

func ParseFloat

func ParseFloat(s string) (float64, error)

ParseFloat parses a float from a string, handling various formats

func Power

func Power(arg, pwr float64) float64

Power returns arg raised to the power pwr

func PropagateSatellite

func PropagateSatellite(tle *TLE, time float64, units ...string) (Vector, Vector, error)

PropagateSatellite is a wrapper function that uses the C implementation This is the combined SGP4/SDP4 model that handles both near-earth and deep-space cases

func RMax

func RMax(arg1, arg2 float64) float64

RMax returns the maximum of two floats

func RMin

func RMin(arg1, arg2 float64) float64

RMin returns the minimum of two floats

func Radians

func Radians(arg float64) float64

Radians converts degrees to radians

func SGP4

func SGP4(satrec *ElsetRec, tsince float64, r, v []float64) bool

SGP4 is the main SGP4 prediction model - exact replica from C code This is the combined version that handles both near-earth and deep-space cases

func SGP4Init added in v0.1.3

func SGP4Init(opsmode byte, satrec *ElsetRec) bool

SGP4Init initializes the SGP4 propagator - exact replica of sgp4init from C code

func Sign

func Sign(arg float64) int

Sign returns the sign of a number (-1, 0, or 1)

func Square

func Square(arg float64) float64

Square returns the square of a number

func Tan

func Tan(arg float64) float64

Tan returns the tangent of an angle

func TimeToJulianDate

func TimeToJulianDate(t time.Time) float64

TimeToJulianDate converts a Go time.Time to Julian date

Types

type ElsetRec added in v0.1.3

type ElsetRec struct {
	// Basic satellite information
	WhichConst, EpochYr, EpochTynumrev, Error int
	SatID                                     [6]byte
	OperationMode, Init, Method               byte

	// Orbital elements
	A, Altp, Alta, EpochDays, Jdsatepoch, JdsatepochF float64
	Nddot, Ndot, Bstar, Rcse, Inclo, Nodeo, Ecco      float64
	Argpo, Mo, NoKozai                                float64

	// Additional TLE fields
	Classification byte
	Intldesg       [12]byte
	Ephtype        int
	Elnum, Revnum  int64

	// Unkozai'd variable
	NoUnkozai float64

	// Singly averaged variables
	Am, Em, Im, Om, Om2, Mm, Nm, T float64

	// Constant parameters
	Tumin, Mu, Radiusearthkm, Xke, J2, J3, J4, J3oj2 float64

	// Additional elements
	DiaMm              int64
	PeriodSec, RcsM2   float64
	Active, NotOrbital byte

	// Temporary variables
	Ep, Inclp, Nodep, Argpp, Mp float64

	// Near earth variables
	Isimp                                      int
	Aycof, Con41, Cc1, Cc4, Cc5, D2, D3, D4    float64
	Delmo, Eta, Argpdot, Omgcof, Sinmao        float64
	T2cof, T3cof, T4cof, T5cof, X1mth2, X7thm1 float64
	Mdot, Nodedot, Xlcof, Xmcof, Nodecf        float64

	// Deep space variables
	Irez                                                                 int
	D2201, D2211, D3210, D3222, D4410, D4422, D5220, D5232, D5421, D5433 float64
	Dedt, Del1, Del2, Del3, Didt, Dmdt, Dnodt, Domdt                     float64
	E3, Ee2, Peo, Pgho, Pho, Pinco, Plo, Se2, Se3, Sgh2, Sgh3, Sgh4      float64
	Sh2, Sh3, Si2, Si3, Sl2, Sl3, Sl4, Gsto, Xfact                       float64
	Xgh2, Xgh3, Xgh4, Xh2, Xh3, Xi2, Xi3, Xl2, Xl3, Xl4                  float64
	Xlamo, Zmol, Zmos, Atime, Xli, Xni                                   float64
	Snodm, Cnodm, Sinim, Cosim, Sinomm, Cosomm                           float64
	Day, Emsq, Gam, Rtemsq                                               float64
	S1, S2, S3, S4, S5, S6, S7                                           float64
	Ss1, Ss2, Ss3, Ss4, Ss5, Ss6, Ss7                                    float64
	Sz1, Sz2, Sz3, Sz11, Sz12, Sz13, Sz21, Sz22, Sz23, Sz31, Sz32, Sz33  float64
	Z1, Z2, Z3, Z11, Z12, Z13, Z21, Z22, Z23, Z31, Z32, Z33              float64
	Argpm, Inclm, Nodem, Dndt, Eccsq                                     float64

	// For initl
	Ainv, Ao, Con42, Cosio, Cosio2, Omeosq, Posq, Rp, Rteosq, Sinio float64
}

ElsetRec represents the satellite record structure from the C code This is an exact replica of the C ElsetRec struct from SGP4.h

type PropagationResult

type PropagationResult struct {
	Time     time.Time
	Position Vector
	Velocity Vector
	Error    error
}

PropagationResult represents the result of orbital propagation

type Satellite

type Satellite struct {
	Name     string
	Data     SatelliteData
	Selected bool
}

Satellite represents a satellite with its data and state

type SatelliteData

type SatelliteData struct {
	// Original TLE data
	TLE TLE

	// Converted orbital elements
	XMO, XNodeO, OmegaO, EO, XIncl, XNO, XNDT2O, XNDD6O, BStar float64
	JulianEpoch, XKE                                           float64

	// Model flags
	IFlag, IDeep int

	// Derived constants for SGP4
	EQSQ, SINIQ, COSIQ, RTEQSQ, AO, COSQ2, SINOMO, COSOMO float64
	BSQ, XLLDOT, OMGDT, XNODOT, XNODP                     float64

	// Deep space variables
	XLL, OMGASM, XNODES, EM, XINC, XN, T float64
	QOMS2T                               float64
}

SatelliteData represents the internal satellite data used by SGP4

func ConvertSatelliteData

func ConvertSatelliteData(tle *TLE) (*SatelliteData, error)

ConvertSatelliteData converts TLE data to the internal format used by SGP4

func (*SatelliteData) GetEccentricity

func (s *SatelliteData) GetEccentricity() float64

GetEccentricity returns the eccentricity

func (*SatelliteData) GetInclination

func (s *SatelliteData) GetInclination() float64

GetInclination returns the inclination in degrees

func (*SatelliteData) GetJulianEpoch

func (s *SatelliteData) GetJulianEpoch() float64

GetJulianEpoch returns the Julian epoch

func (*SatelliteData) GetMeanMotion

func (s *SatelliteData) GetMeanMotion() float64

GetMeanMotion returns the mean motion in revolutions per day

func (*SatelliteData) GetOrbitalPeriod

func (s *SatelliteData) GetOrbitalPeriod() float64

GetOrbitalPeriod returns the orbital period in minutes

func (*SatelliteData) IsDeepSpace

func (s *SatelliteData) IsDeepSpace() bool

IsDeepSpace returns true if this satellite requires the deep space model (SDP4)

type SatelliteDatabase

type SatelliteDatabase struct {
	Satellites []Satellite
	Epoch      time.Time
}

SatelliteDatabase represents a collection of satellites

type State

type State struct {
	Position Vector
	Velocity Vector
}

State represents position and velocity vectors

type TLE

type TLE struct {
	SatelliteNumber   string
	Epoch             float64
	JulianEpoch       float64
	GregorianEpoch    time.Time
	MeanMotionDot     float64
	MeanMotionDDot    float64
	MeanMotionDDotExp int
	BStar             float64
	BStarExp          int
	ElementSet        string
	Inclination       float64
	RightAscension    float64
	Eccentricity      float64
	ArgumentPerigee   float64
	MeanAnomaly       float64
	MeanMotion        float64
}

TLE represents a Two-Line Element set

func ParseTLE

func ParseTLE(line1, line2 string) (*TLE, error)

ParseTLE parses a two-line element set and returns a TLE struct

func (*TLE) GetElementSet

func (t *TLE) GetElementSet() string

GetElementSet returns the element set number

func (*TLE) GetEpoch

func (t *TLE) GetEpoch() float64

GetEpoch returns the TLE epoch in the original format

func (*TLE) GetJulianEpoch

func (t *TLE) GetJulianEpoch() float64

GetJulianEpoch returns the Julian epoch (equivalent to jdsatepoch in other packages)

func (*TLE) GetOrbitalPeriod

func (t *TLE) GetOrbitalPeriod() float64

GetOrbitalPeriod returns the orbital period in minutes

func (*TLE) GetSatelliteNumber

func (t *TLE) GetSatelliteNumber() string

GetSatelliteNumber returns the satellite number

type Vector

type Vector struct {
	X, Y, Z, Magnitude float64
}

Vector represents a 3D vector with magnitude

func Cross

func Cross(v1, v2 Vector) Vector

Cross returns the cross product of two vectors

func ScalarMultiply

func ScalarMultiply(k float64, v Vector) Vector

ScalarMultiply multiplies a vector by a scalar

func VecAdd

func VecAdd(v1, v2 Vector) Vector

VecAdd adds two vectors and stores result in v3

func VecSub

func VecSub(v1, v2 Vector) Vector

VecSub subtracts v2 from v1 and stores result in v3

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL