Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 15:44 08 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MMX/RPI/DOS - sun-synchronous satellites

Author Message
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 10:13am 02 Aug 2017
Copy link to clipboard 
Print this post

This post describes one of the computer programs I wrote for designing sun-synchronous Earth orbits. These are special orbits that use "natural" perturbations to our advantage. The main perturbation is due to the non-spherical shape of the Earth. Like me as I get older, the Earth too has an equatorial bulge and somewhat flat at the poles. We can also account for the gravitational perturbations due to the Sun and Moon during the orbit design. The mission objective is to design an Earth orbit that maintains a fixed orientation with respect to the Sun.

This MMBASIC version of sunsync1.bas was ported from versions written in FORTRAN, MATLAB and QuickBASIC.

Here's a typical user interaction with the software and the numerical results.


program sunsync1

sun-synchronous orbits - j2 solution
------------------------------------

<1> input mean semimajor axis and eccentricity

<2> input mean perigee and apogee altitudes

? 2

please input the mean perigee altitude (kilometers)
? 350

please input the mean apogee altitude (kilometers)
? 1000


program sunsync1

sun-synchronous orbits - j2 solution
------------------------------------

mean perigee altitude 350.0000 kilometers

mean apogee altitude 1000.0000 kilometers

mean semimajor axis 7053.1400 kilometers

mean orbital eccentricity 0.0460787678

mean orbital inclination 98.0571 degrees

number of iterations 3


Here's the MMBASIC source code listing for sunsync1.bas.


' program sunsync1.bas August 2, 2017

' mean orbital inclination of sun-synchronous orbits

' Kozai j2 perturbations

' MMX/RasPi/DOS versions of MMBASIC

'''''''''''''''''''''''''''''''''''

option default float

option base 1

' astrodynamic and utility constants

const pi2 = 2.0 * pi

' conversion factor - degrees to radians

const dtr = pi / 180.0

' conversion factor - radians to degrees

const rtd = 180.0 / pi

' Earth gravitational constant (km**3/sec**2)

const xmu = 398600.4415

' equatorial radius of the Earth (kilometers)

const req = 6378.14

' Earth oblateness coefficient

const xj2 = 0.00108263

' begin main program

print " "
print "program sunsync1"
print " "
print "sun-synchronous orbits - j2 solution"
print "------------------------------------"

do

print " "
print "<1> input mean semimajor axis and eccentricity"
print " "
print "<2> input mean perigee and apogee altitudes"
print " "

input iselect%

if (iselect% = 1 or iselect% = 2) then exit do

loop

if (iselect% = 1) then

print " "
print "please input the mean semimajor axis (kilometers)"
print " "

input sma

print " "
print "please input the mean orbital eccentricity"
print " "

input ecc

' compute perigee and apogee altitudes (kilometers)

hp = sma * (1.0 - ecc) - req

ha = sma * (1.0 + ecc) - req

elseif (iselect% = 2) then

print " "
print "please input the mean perigee altitude (kilometers)"

input hp

print " "
print "please input the mean apogee altitude (kilometers)"

input ha

' compute perigee and apogee geocentric radii

rp = req + hp

ra = req + ha

' compute semimajor axis and eccentricity

sma = 0.5 * (rp + ra)

ecc = (ra - rp) / (ra + rp)

end if

' required nodal regression rate (radians/second)

drdt = dtr * (360.0 / 365.2422) / 86400.0

' Keplerian mean motion (radians/second)

xmm = sqr(xmu / (sma * sma * sma))

' orbital semiparameter (kilometers)

slr = sma * (1.0 - ecc * ecc)

' inclination initial guess

xipar0 = - (2.0 / 3.0) * slr * slr * drdt / (xj2 * req * req * xmm)

' check for possible solution

if (abs(xipar0) > 1.0) then

print " "
print "no sun-synchronous solution !!"
print " "

end

else

' perform iteration

xinc0 = acos(xipar0)

niter% = 0

do

niter% = niter% + 1

' perturbed mean motion (radians/second)

pmm = xmm * (1.0 + 1.5 * xj2 * req * req * sqr(1.0 - ecc * ecc) * (1.0 - 1.5 * sin(xinc0) * sin(xinc0)) / (slr * slr))

' updated inclination

xinc1 = acos(-(2.0 / 3.0) * slr * slr * drdt / (xj2 * req * req * pmm))

' check for convergence or more than 100 iterations

if (abs(xinc1 - xinc0) < 1.0e-9 or niter% > 100) then exit do

' reset inclination

xinc0 = xinc1

loop

end if

' print results

print " "
print " "
print "program sunsync1"
print " "
print "sun-synchronous orbits - j2 solution"
print "------------------------------------"
print " "
print "mean perigee altitude ", str$(hp, 0, 4) + " kilometers"
print " "
print "mean apogee altitude ", str$(ha, 0, 4) + " kilometers"
print " "
print "mean semimajor axis ", str$(sma, 0, 4) + " kilometers"
print " "
print "mean orbital eccentricity ", str$(ecc, 0, 10)
print " "
print "mean orbital inclination ", str$(xinc1 * rtd, 0, 4) + " degrees"
print " "
print "number of iterations ", niter%
print " "

end


Here's the PDF document that describes this and other computer programs in the sun-sync series.

2017-08-02_195758_sunsync1.zip
 
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 06:23am 06 Aug 2017
Copy link to clipboard 
Print this post

This version, sunsync2.bas, uses a slightly more sophisticated gravity for the orbit design.


program sunsync2

sun-synchronous orbits - j2 + j4 solution
-----------------------------------------

<1> input mean semimajor axis and eccentricity

<2> input mean perigee and apogee altitudes

? 2

please input the mean perigee altitude (kilometers)
? 350

please input the mean apogee altitude (kilometers)
? 1000


program sunsync2

sun-synchronous orbits - j2 + j4 solution
-----------------------------------------

mean perigee altitude 350.0000 kilometers

mean apogee altitude 1000.0000 kilometers

mean semimajor axis 7053.1400 kilometers

mean orbital eccentricity 0.0460787678

mean orbital inclination 98.0306 degrees



' program sunsync2.bas August 6, 2017

' mean orbital inclination of sun-synchronous orbits

' Kozai j2 + j4 iterative solution

' MMX/RasPi/DOS versions of MMBASIC

'''''''''''''''''''''''''''''''''''

option default float

option base 1

' global constants

dim xmm, drdt0, req2, req4, slr2, slr4, ecc2

' astrodynamic and utility constants

const pi2 = 2.0 * pi

const pidiv2 = 0.5 * pi

' conversion factor - degrees to radians

const dtr = pi / 180.0

' conversion factor - radians to degrees

const rtd = 180.0 / pi

' Earth gravitational constant (km**3/sec**2)

const xmu = 398600.4415

' equatorial radius of the Earth (kilometers)

const req = 6378.14

' Earth gravity coefficients (non-dimensional)

const xj2 = 0.00108263

const xj4 = 0.0000016109876

const xj22 = 0.0000015747419

' begin main program

print " "
print "program sunsync2"
print " "
print "sun-synchronous orbits - j2 + j4 solution"
print "-----------------------------------------"

do

print " "
print "<1> input mean semimajor axis and eccentricity"
print " "
print "<2> input mean perigee and apogee altitudes"
print " "

input iselect%

if (iselect% = 1 or iselect% = 2) then exit do

loop

if (iselect% = 1) then

print " "
print "please input the mean semimajor axis (kilometers)"
print " "

input sma

print " "
print "please input the mean orbital eccentricity"
print " "

input ecc

' compute perigee and apogee altitudes (kilometers)

hp = sma * (1.0 - ecc) - req

ha = sma * (1.0 + ecc) - req

elseif (iselect% = 2) then

print " "
print "please input the mean perigee altitude (kilometers)"

input hp

print " "
print "please input the mean apogee altitude (kilometers)"

input ha

' compute perigee and apogee geocentric radii

rp = req + hp

ra = req + ha

' compute semimajor axis and eccentricity

sma = 0.5 * (rp + ra)

ecc = (ra - rp) / (ra + rp)

end if

' required nodal regression rate (radians/second)

drdt0 = dtr * (360.0 / 365.2422) / 86400.0

' Keplerian mean motion (radians/second)

xmm = sqr(xmu / (sma * sma * sma))

' orbital semiparameter (kilometers)

slr = sma * (1.0 - ecc * ecc)

' inclination initial guess

xipar0 = - (2.0 / 3.0) * slr * slr * drdt / (xj2 * req * req * xmm)

' check for possible solution

if (abs(xipar0) > 1.0) then

print " "
print "no sun-synchronous solution !!"
print " "

else

' perform iteration

slr2 = slr * slr

slr4 = slr2 * slr2

req2 = req * req

req4 = req2 * req2

ecc2 = ecc * ecc

' compute inclination bounds

xinc1 = xinc0 - 1.0 * dtr

if (xinc1 < pidiv2) then xinc1 = pidiv2

xinc2 = xinc0 + 1.0 * dtr

if (xinc2 > pi) then xinc2 = pi

' solve nonlinear equation

tol = 1.0e-10

root(xinc1, xinc2, tol, xroot, froot)

end if

' print results

print " "
print " "
print "program sunsync2"
print " "
print "sun-synchronous orbits - j2 + j4 solution"
print "-----------------------------------------"
print " "
print "mean perigee altitude ", str$(hp, 0, 4) + " kilometers"
print " "
print "mean apogee altitude ", str$(ha, 0, 4) + " kilometers"
print " "
print "mean semimajor axis ", str$(sma, 0, 4) + " kilometers"
print " "
print "mean orbital eccentricity ", str$(ecc, 0, 10)
print " "
print "mean orbital inclination ", str$(xroot * rtd, 0, 4) + " degrees"
print " "

end

'''''''''''''''''
'''''''''''''''''

sub ss2_func(x, fx)

' delta-raan rate objective function

' input

' x = current orbital inclination (radians)

' output

' fx = objective function

''''''''''''''''''''''''''

local sinc, cinc

local pmm, pmm1, pmm2, pmm3, pmm4, pmm5, pmm6

local drdt, drdt1, drdt2, drdt3, drdt4, drdt5

sinc = sin(x)

cinc = cos(x)

' Kozai j2 + j4 perturbed mean motion (radians/second)

pmm1 = 1.0 + 1.5 * xj2 * req2 * sqr(1.0 - ecc2) * (1.0 - 1.5 * sinc^2) / slr2

pmm2 = (3.0 / 128.0) * xj22 * req4 * sqr(1.0 - ecc2) / slr4

pmm3 = 16.0 * sqr(1.0 - ecc2) + 25.0 * (1.0 - ecc2) - 15.0

pmm4 = (30.0 - 96.0 * sqr(1.0 - ecc2) - 90.0 * (1.0 - ecc2)) * cinc^2

pmm5 = (105.0 + 144.0 * sqr(1.0 - ecc2) + 25.0 * (1.0 - ecc2)) * cinc^4

pmm6 = - (45.0 / 128.0) * xj4 * req4 * sqr(1.0 - ecc2) * ecc2 * (3.0 - 30.0 * cinc^2 + 35.0 * cinc^4) / slr4

pmm = xmm * (pmm1 + pmm2 * (pmm3 + pmm4 + pmm5) + pmm6)

' raan time rate of change

drdt1 = -1.5 * req2 * xj2 * pmm * cinc / slr2

drdt2 = 1.5 * req2 * xj2 / slr2

drdt3 = 1.5 + ecc2 / 6.0 - 2.0 * sqr(1.0 - ecc2)

drdt4 = - ((5.0 / 3.0) - (5.0 / 24.0) * ecc2 - 3.0 * sqr(1.0 - ecc2)) * sinc * sinc

drdt5 = - (35.0 / 8.0) * req4 * xj4 * xmm * (1.0 + 1.5 * ecc2) * ((12.0 - 21.0 * sinc * sinc) / 14.0) * cinc / slr4

drdt = drdt1 * (1.0 + drdt2 * (drdt3 + drdt4)) - drdt5

' calculate the objective function as the difference
' between the desired and current raan rate

fx = drdt - drdt0

end sub

'''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''

sub root(x1, x2, tol, xroot, froot)

' real root of a single non-linear function subroutine

' input

' x1 = lower bound of search interval
' x2 = upper bound of search interval
' tol = convergence criter%ia

' output

' xroot = real root of f(x) = 0
' froot = function value

' note: requires subroutine ss2_func

''''''''''''''''''''''''''''''''''''

local eps, a, b, c, d, e, fa, fb, fcc, tol1

local xm, p, q, r, s, xmin, tmp

eps = 2.23e-16

e = 0.0

a = x1

b = x2

ss2_func(a, fa)

ss2_func(b, fb)

fcc = fb

for iter% = 1 to 50

if (fb * fcc > 0.0) then

c = a

fcc = fa

d = b - a

e = d

end if

if (abs(fcc) < abs(fb)) then

a = b

b = c

c = a

fa = fb

fb = fcc

fcc = fa

end if

tol1 = 2.0 * eps * abs(b) + 0.5 * tol

xm = 0.5 * (c - b)

if (abs(xm) <= tol1 or fb = 0.0) then exit for

if (abs(e) >= tol1 and abs(fa) > abs(fb)) then

s = fb / fa

if (a = c) then

p = 2.0 * xm * s

q = 1.0 - s

else

q = fa / fcc

r = fb / fcc

p = s * (2.0 * xm * q * (q - r) - (b - a) * (r - 1.0))

q = (q - 1.0) * (r - 1.0) * (s - 1.0)

end if

if (p > 0.0) then q = -q

p = abs(p)

min = abs(e * q)

tmp = 3.0 * xm * q - abs(tol1 * q)

if (min < tmp) then min = tmp

if (2.0 * p < min) then

e = d

d = p / q

else

d = xm

e = d

end if

else

d = xm

e = d

end if

a = b

fa = fb

if (abs(d) > tol1) then

b = b + d

else

b = b + sgn(xm) * tol1

end if

ss2_func(b, fb)

next iter%

froot = fb

xroot = b

end sub
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024