Sunlight and Eclipse Periods Analysis for a SSO orbit
credit: Photo by Kevin Stadnyk on Unsplash
Code can be found here
Introduction
It is critical for mission planning to know the times for eclipse and sunlight for power management and thermal control. Solar-powered satellites draw energy whenever they are out of sunlight because onboard batteries will sustain power during an eclipse while in the shadow of the Earth. The actual frequency and time duration of eclipses can change according to the orbit of the satellite.
This blog post is based on the computation of sunlight and eclipse hours for a satellite using Python and the Skyfield library. A Sun-Synchronous Orbit with varying Right Ascension of the Ascending Node (RANN) values and computing the aggregate sunlight and eclipse hours for 31 days (744 hours) will done.
Methodology
Step 1: Define the Satellite Orbit
We define a satellite with the following orbital parameters for a SSO orbit:
- Semi-major axis (sma): 6878 km (500 km altitude)
- Eccentricity (ecc): 0.03
- Inclination (inc): 97.4°
- Argument of Perigee (aop): 0.0°
- Mean Anomaly: 0.0°
- Epoch: January 1, 2025, 12:00 UTC
Generate a Two-Line Element (TLE) set based on these parameters:
from skyfield.api import load, EarthSatellite, wgs84
from datetime import datetime
from pytz import utc
import math
= load.timescale()
ts
= {
base_params 'sma': 6878.0,
'ecc': 0.03,
'inc': 97.4,
'aop': 0.0,
'mean_anomaly': 0.0,
'epoch': datetime(2025, 1, 1, 12, 0, 0, tzinfo=utc)
}
def create_tle(satellite_name, raan):
= 3.986004418e5 # Earth's gravitational parameter (km^3/s^2)
mu = base_params['sma']
sma_km = math.sqrt(mu / (sma_km ** 3))
n_rad_s = n_rad_s * 86400 / (2 * math.pi)
n_rev_per_day = f"{n_rev_per_day:11.8f}"
mean_motion
= f"1 00001U 00000A 25001.50000000 .00000000 00000-0 00000-0 0 0001"
line1 = f"2 00001 {base_params['inc']:8.4f} {raan:8.4f} {base_params['ecc'] * 1e7:07.0f} {base_params['aop']:8.4f} {base_params['mean_anomaly']:8.4f} {mean_motion} 00"
line2
return EarthSatellite(line1, line2, satellite_name, ts)
Step 2: Computing Sunlight and Eclipse Durations
Using Skyfield, determine if the satellite is illuminated by the Sun in order to find out when it is in eclipse. The function calculates the total period of sunlight and eclipse for one month.
from skyfield.searchlib import find_discrete
def total_eclipse_sunlight(satellite):
= load('de421.bsp')
eph = ts.utc(2025, 1, 1)
start_time = ts.utc(2025, 2, 1)
end_time
def is_eclipse(t):
= satellite.at(t).is_sunlit(eph)
sunlit return ~sunlit # Returns True if in eclipse, False if in sunlight
= 0.0005
is_eclipse.step_days = find_discrete(start_time, end_time, is_eclipse)
times, events
= 0.0
total_eclipse = 0.0
total_sunlight = start_time
previous_time = is_eclipse(start_time)
previous_state
for ti, state in zip(times, events):
= (ti - previous_time) * 24
duration_hours if previous_state:
+= duration_hours
total_eclipse else:
+= duration_hours
total_sunlight = ti
previous_time = state
previous_state
= (end_time - previous_time) * 24
final_duration
if previous_state:
+= final_duration
total_eclipse else:
+= final_duration
total_sunlight
print(f"Total sunlight: {total_sunlight:.2f} hours")
print(f"Total eclipse: {total_eclipse:.2f} hours")
Step 3: Running the Analysis for Different RAAN Values
The responsible factor for influencing eclipse duration is the position of the right ascension of the ascending node (RAAN) with respect to the orientation of the orbit concerning the Sun; there are three values possible for RAAN:
= [50.0, 120.0, 240.0]
raan_values
for raan in raan_values:
= create_tle(f"Sat_RAAN_{raan}", raan)
satellite print(f"\nRAAN: {raan}°")
total_eclipse_sunlight(satellite)
Results
Eclipse and Sunlight Durations
RAAN (°) | Total Sunlight (hours) | Total Eclipse (hours) |
---|---|---|
50.0 | 526.27 | 217.73 |
120.0 | 465.76 | 278.24 |
240.0 | 484.98 | 259.02 |
Observations
- The total excursion in eclipse lies under RAAN and varies substantially and in a given month could range from 217.73 to 278.24 hours.
- Maximum eclipse time is a recorded observation when RAAN = 120°, which goes to minimum for RAAN = 50° (217.73 hours).
- It implies an almost 60-hour difference in eclipse per month with respect to the RAAN, evidencing the dependence of the sunlight exposure on the orbit orientation.
- These eclipse durations give an average eclipse duration per orbit somewhere around 27 to 35 minutes, while the duration for each might be longer or shorter.
Conclusion
An analysis describing the computation of sunlight and eclipse durations experienced by satellites using Python and Skyfield is given. Indeed, eclipse prediction becomes a critical measure in power management, thermal control, and most importantly, general mission planning for the satellite.
Major Points:
- Periods of shadow are experienced by satellites, thus requiring them to fly battery-powered.
- Total eclipse duration is affected by RAAN, but small variations can generally found for Sun-Synchronous Orbits.
- Python and Skyfield provide powerful open-source tools to analyze orbital illumination conditions.
- Mission planners need to optimize battery storage and solar panel efficiency to ensure that operations are continuous through eclipse phases.
By understanding the eclipse patterns, engineers can describe as well as design resilient power systems for satellites that continue functional even during long shadow periods.