Path: blob/main/latex-templates/templates/aerospace/satellite_coverage.tex
51 views
unlisted
\documentclass[a4paper, 11pt]{article}1\usepackage[utf8]{inputenc}2\usepackage[T1]{fontenc}3\usepackage{amsmath, amssymb}4\usepackage{graphicx}5\usepackage{siunitx}6\usepackage{booktabs}7\usepackage{algorithm2e}8\usepackage{subcaption}9\usepackage[makestderr]{pythontex}1011% Theorem environments for technical report style12\newtheorem{definition}{Definition}13\newtheorem{theorem}{Theorem}14\newtheorem{remark}{Remark}1516\title{Satellite Coverage Analysis: Ground Coverage, Revisit Times, and Constellation Design\\17\large A Comprehensive Study of Earth Observation and Communication Systems}18\author{Space Systems Division\\Computational Science Templates}19\date{\today}2021\begin{document}22\maketitle2324\begin{abstract}25This technical report presents a comprehensive analysis of satellite ground coverage for Earth observation and communication missions. We compute instantaneous coverage footprints, revisit times for single satellites and constellations, and analyze Walker constellation parameters for global coverage. The analysis includes elevation angle constraints, slant range calculations, and coverage optimization for various orbital configurations.26\end{abstract}2728\section{Executive Summary}29Satellite coverage analysis is critical for mission design in Earth observation, communications, and navigation applications. This report analyzes coverage characteristics for various orbital configurations and provides design guidelines for constellation optimization.3031\section{Mathematical Framework}3233\begin{definition}[Coverage Half-Angle]34The Earth-central angle from the sub-satellite point to the coverage edge:35\begin{equation}36\rho = \arccos\left(\frac{R_E}{R_E + h}\cos\varepsilon_{min}\right) - \varepsilon_{min}37\end{equation}38where $\varepsilon_{min}$ is the minimum elevation angle and $h$ is orbital altitude.39\end{definition}4041\subsection{Coverage Area}42The instantaneous coverage area on Earth's surface:43\begin{equation}44A_{cov} = 2\pi R_E^2 (1 - \cos\rho)45\end{equation}4647\subsection{Slant Range}48The distance from satellite to ground target:49\begin{equation}50d = R_E \left[\sqrt{\left(\frac{R_E + h}{R_E}\right)^2 - \cos^2\varepsilon} - \sin\varepsilon\right]51\end{equation}5253\subsection{Revisit Time}54\begin{theorem}[Single Satellite Revisit]55For a circular orbit, the maximum revisit time at latitude $\phi$:56\begin{equation}57T_{revisit} \approx \frac{2\pi R_E \cos\phi}{W \cdot n_{orbits/day}}58\end{equation}59where $W$ is the swath width and $n_{orbits/day}$ is the number of orbits per day.60\end{theorem}6162\subsection{Walker Constellation}63A Walker Delta pattern is described by notation $i:T/P/F$:64\begin{itemize}65\item $i$ = Inclination66\item $T$ = Total number of satellites67\item $P$ = Number of equally-spaced orbital planes68\item $F$ = Relative phasing factor69\end{itemize}7071\section{Computational Analysis}7273\begin{pycode}74import numpy as np75import matplotlib.pyplot as plt76from matplotlib.patches import Circle77plt.rc('text', usetex=True)78plt.rc('font', family='serif')7980np.random.seed(42)8182# Constants83R_earth = 6371 # km84mu = 398600 # km^3/s^285omega_E = 7.2921e-5 # rad/s (Earth rotation rate)8687# Function to compute coverage parameters88def coverage_params(h, elev_min_deg):89elev_min = np.deg2rad(elev_min_deg)9091# Earth central half-angle92sin_lambda = R_earth / (R_earth + h) * np.cos(elev_min)93lambda_0 = np.arcsin(sin_lambda)94rho = np.pi/2 - elev_min - lambda_09596# Coverage area97area = 2 * np.pi * R_earth**2 * (1 - np.cos(rho))9899# Swath width100swath = 2 * R_earth * rho # Arc length approximation101102# Slant range103slant = R_earth * np.sin(rho) / np.cos(elev_min + rho)104105# Nadir angle106nadir = np.arcsin(R_earth / (R_earth + h) * np.sin(np.pi/2 + elev_min))107108return np.rad2deg(rho), area, swath, slant, np.rad2deg(nadir)109110# Orbital configurations111altitudes = [400, 600, 800, 1200, 2000] # km112elev_angles = [5, 10, 15, 20, 30] # degrees113114# Coverage analysis for different altitudes115coverage_data = {}116for h in altitudes:117rho, area, swath, slant, nadir = coverage_params(h, 10)118T = 2 * np.pi * np.sqrt((R_earth + h)**3 / mu)119n_orbits = 86400 / T120coverage_data[h] = {121'rho': rho, 'area': area, 'swath': swath,122'slant': slant, 'nadir': nadir, 'period': T/60,123'orbits_per_day': n_orbits124}125126# Ground track simulation127def ground_track(h, inc_deg, duration_hours=3, n_points=1000):128a = R_earth + h129T = 2 * np.pi * np.sqrt(a**3 / mu)130t = np.linspace(0, duration_hours * 3600, n_points)131132n = np.sqrt(mu / a**3)133inc = np.deg2rad(inc_deg)134135# Simplified ground track (circular orbit)136lat = np.rad2deg(np.arcsin(np.sin(inc) * np.sin(n * t)))137# Longitude accounting for Earth rotation138lon_inertial = np.rad2deg(np.arctan2(np.cos(inc) * np.sin(n * t),139np.cos(n * t)))140lon = lon_inertial - np.rad2deg(omega_E * t)141lon = ((lon + 180) % 360) - 180142143return lat, lon, T144145# Constellation configurations146constellations = {147'Starlink (Shell 1)': {'T': 1584, 'P': 72, 'h': 550, 'i': 53.0},148'OneWeb': {'T': 648, 'P': 18, 'h': 1200, 'i': 87.9},149'GPS': {'T': 24, 'P': 6, 'h': 20180, 'i': 55.0},150'Iridium': {'T': 66, 'P': 6, 'h': 780, 'i': 86.4},151'Galileo': {'T': 24, 'P': 3, 'h': 23222, 'i': 56.0}152}153154# Revisit time calculation155def revisit_time(h, lat_deg, swath_km):156T = 2 * np.pi * np.sqrt((R_earth + h)**3 / mu)157n_orbits = 86400 / T158159lat = np.deg2rad(abs(lat_deg))160161# Ground track spacing per day162circumference_at_lat = 2 * np.pi * R_earth * np.cos(lat)163track_spacing = circumference_at_lat / n_orbits164165if swath_km <= 0:166return float('inf')167168# Days to cover169days_to_cover = track_spacing / swath_km170171return days_to_cover * 24 # hours172173# Elevation angle effects174elev_results = {}175for elev in elev_angles:176rho, area, swath, slant, nadir = coverage_params(800, elev)177elev_results[elev] = {'rho': rho, 'area': area, 'swath': swath, 'slant': slant}178179# Create comprehensive visualization180fig = plt.figure(figsize=(14, 12))181182# Plot 1: Coverage vs altitude183ax1 = fig.add_subplot(2, 3, 1)184alts = list(coverage_data.keys())185swaths = [coverage_data[h]['swath'] for h in alts]186areas = [coverage_data[h]['area']/1e6 for h in alts]187188ax1.plot(alts, swaths, 'bo-', linewidth=2, markersize=6, label='Swath (km)')189ax1_twin = ax1.twinx()190ax1_twin.plot(alts, areas, 'rs-', linewidth=2, markersize=6, label='Area (M km$^2$)')191ax1.set_xlabel('Altitude (km)')192ax1.set_ylabel('Swath Width (km)', color='blue')193ax1_twin.set_ylabel('Coverage Area (M km$^2$)', color='red')194ax1.set_title('Coverage vs Altitude ($\\varepsilon_{min}=10^\\circ$)')195ax1.legend(loc='upper left', fontsize=8)196ax1_twin.legend(loc='lower right', fontsize=8)197ax1.grid(True, alpha=0.3)198199# Plot 2: Elevation angle effects200ax2 = fig.add_subplot(2, 3, 2)201elevs = list(elev_results.keys())202swath_by_elev = [elev_results[e]['swath'] for e in elevs]203slant_by_elev = [elev_results[e]['slant'] for e in elevs]204205x = np.arange(len(elevs))206width = 0.35207ax2.bar(x - width/2, swath_by_elev, width, label='Swath (km)', color='steelblue')208ax2_twin = ax2.twinx()209ax2_twin.bar(x + width/2, slant_by_elev, width, label='Slant Range (km)', color='coral')210ax2.set_xlabel('Min Elevation (deg)')211ax2.set_ylabel('Swath Width (km)', color='steelblue')212ax2_twin.set_ylabel('Slant Range (km)', color='coral')213ax2.set_xticks(x)214ax2.set_xticklabels([f'{e}' for e in elevs])215ax2.set_title('Elevation Angle Effects (h=800 km)')216ax2.legend(loc='upper left', fontsize=7)217ax2_twin.legend(loc='upper right', fontsize=7)218219# Plot 3: Ground track220ax3 = fig.add_subplot(2, 3, 3)221lat, lon, T = ground_track(700, 98.2, duration_hours=3)222# Handle discontinuities223split_idx = np.where(np.abs(np.diff(lon)) > 180)[0] + 1224segments = np.split(np.arange(len(lon)), split_idx)225for seg in segments:226if len(seg) > 1:227ax3.plot(lon[seg], lat[seg], 'b-', linewidth=1.5, alpha=0.7)228ax3.set_xlim(-180, 180)229ax3.set_ylim(-90, 90)230ax3.set_xlabel('Longitude (deg)')231ax3.set_ylabel('Latitude (deg)')232ax3.set_title('Sun-Sync Ground Track (3 hrs)')233ax3.grid(True, alpha=0.3)234235# Plot 4: Constellation comparison236ax4 = fig.add_subplot(2, 3, 4)237const_names = list(constellations.keys())238n_sats = [constellations[c]['T'] for c in const_names]239heights = [constellations[c]['h']/1000 for c in const_names] # Convert to thousands240241x = np.arange(len(const_names))242width = 0.35243bars1 = ax4.bar(x - width/2, n_sats, width, label='Satellites', color='steelblue', alpha=0.8)244ax4_twin = ax4.twinx()245bars2 = ax4_twin.bar(x + width/2, heights, width, label='Alt (1000 km)', color='coral', alpha=0.8)246ax4.set_xlabel('Constellation')247ax4.set_ylabel('Number of Satellites', color='steelblue')248ax4_twin.set_ylabel('Altitude (1000 km)', color='coral')249ax4.set_xticks(x)250ax4.set_xticklabels([c.split()[0] for c in const_names], rotation=45, ha='right')251ax4.set_title('Major Constellations')252ax4.legend(loc='upper left', fontsize=7)253ax4_twin.legend(loc='upper right', fontsize=7)254255# Plot 5: Revisit time vs latitude256ax5 = fig.add_subplot(2, 3, 5)257lats = np.linspace(0, 80, 50)258for h in [400, 800, 1200]:259swath = coverage_data.get(h, coverage_data[800])['swath']260revisits = [revisit_time(h, lat, swath) for lat in lats]261ax5.plot(lats, revisits, linewidth=2, label=f'{h} km')262ax5.set_xlabel('Latitude (deg)')263ax5.set_ylabel('Revisit Time (hours)')264ax5.set_title('Single Satellite Revisit Time')265ax5.legend(fontsize=8)266ax5.grid(True, alpha=0.3)267ax5.set_ylim([0, 150])268269# Plot 6: Coverage footprint comparison270ax6 = fig.add_subplot(2, 3, 6)271theta = np.linspace(0, 2*np.pi, 100)272for h in [400, 800, 1200, 2000]:273rho_deg = coverage_data[h]['rho']274# Footprint as circle275x_fp = rho_deg * np.cos(theta)276y_fp = rho_deg * np.sin(theta)277ax6.plot(x_fp, y_fp, linewidth=2, label=f'{h} km')278ax6.plot(0, 0, 'ko', markersize=8)279ax6.set_xlabel('Degrees from nadir')280ax6.set_ylabel('Degrees from nadir')281ax6.set_title('Coverage Footprint Size')282ax6.legend(fontsize=8)283ax6.grid(True, alpha=0.3)284ax6.set_aspect('equal')285286plt.tight_layout()287plt.savefig('satellite_coverage_plot.pdf', bbox_inches='tight', dpi=150)288print(r'\begin{center}')289print(r'\includegraphics[width=\textwidth]{satellite_coverage_plot.pdf}')290print(r'\end{center}')291plt.close()292293# Key results294h_ref = 800295ref_data = coverage_data[h_ref]296\end{pycode}297298\section{Algorithm}299300\begin{algorithm}[H]301\SetAlgoLined302\KwIn{Orbital altitude $h$, minimum elevation $\varepsilon_{min}$}303\KwOut{Coverage parameters: $\rho$, $A_{cov}$, swath width, slant range}304$\sin\lambda_0 \leftarrow \frac{R_E}{R_E + h} \cos\varepsilon_{min}$\;305$\rho \leftarrow \pi/2 - \varepsilon_{min} - \arcsin(\sin\lambda_0)$\;306$A_{cov} \leftarrow 2\pi R_E^2 (1 - \cos\rho)$\;307$W \leftarrow 2 R_E \rho$\;308$d \leftarrow R_E \sin\rho / \cos(\varepsilon_{min} + \rho)$\;309\Return{$\rho, A_{cov}, W, d$}310\caption{Satellite Coverage Calculation}311\end{algorithm}312313\section{Results and Discussion}314315\subsection{Altitude Trade-offs}316317\begin{pycode}318print(r'\begin{table}[h]')319print(r'\centering')320print(r'\caption{Coverage Parameters vs Altitude ($\varepsilon_{min}=10^\circ$)}')321print(r'\begin{tabular}{cccccc}')322print(r'\toprule')323print(r'Altitude & Period & Swath & Coverage & Slant & Orbits/ \\')324print(r'(km) & (min) & (km) & (M km$^2$) & (km) & day \\')325print(r'\midrule')326for h in altitudes:327d = coverage_data[h]328print(f"{h} & {d['period']:.1f} & {d['swath']:.0f} & {d['area']/1e6:.2f} & {d['slant']:.0f} & {d['orbits_per_day']:.1f} \\\\")329print(r'\bottomrule')330print(r'\end{tabular}')331print(r'\end{table}')332\end{pycode}333334For the reference altitude of \py{h_ref} km:335\begin{itemize}336\item Coverage half-angle: \py{f"{ref_data['rho']:.1f}"}$^\circ$337\item Swath width: \py{f"{ref_data['swath']:.0f}"} km338\item Instantaneous coverage: \py{f"{ref_data['area']/1e6:.2f}"} million km$^2$339\item Orbital period: \py{f"{ref_data['period']:.1f}"} minutes340\item Orbits per day: \py{f"{ref_data['orbits_per_day']:.1f}"}341\end{itemize}342343\begin{remark}[Altitude Selection Trade-offs]344Higher altitudes provide larger coverage footprints but at the cost of:345\begin{itemize}346\item Increased slant range (reduced resolution)347\item Higher launch cost348\item Longer signal delay (latency)349\end{itemize}350LEO constellations like Starlink use lower altitudes (550 km) for low latency, while GPS uses MEO (20,180 km) for fewer satellites to achieve global coverage.351\end{remark}352353\subsection{Elevation Angle Effects}354355\begin{pycode}356print(r'\begin{table}[h]')357print(r'\centering')358print(r'\caption{Effect of Minimum Elevation Angle (h=800 km)}')359print(r'\begin{tabular}{cccc}')360print(r'\toprule')361print(r'$\varepsilon_{min}$ (deg) & Swath (km) & Slant Range (km) & Coverage (M km$^2$) \\')362print(r'\midrule')363for elev in elev_angles:364d = elev_results[elev]365print(f"{elev} & {d['swath']:.0f} & {d['slant']:.0f} & {d['area']/1e6:.2f} \\\\")366print(r'\bottomrule')367print(r'\end{tabular}')368print(r'\end{table}')369\end{pycode}370371\begin{remark}[Elevation Angle Selection]372Lower elevation angles increase coverage but degrade link quality due to:373\begin{itemize}374\item Longer atmospheric path (attenuation, scintillation)375\item Higher multipath interference376\item Increased geometric dilution of precision (GDOP) for navigation377\end{itemize}378Typical values: 5-10$^\circ$ for communications, 10-15$^\circ$ for navigation, 20-30$^\circ$ for high-precision applications.379\end{remark}380381\subsection{Constellation Design}382383\begin{pycode}384print(r'\begin{table}[h]')385print(r'\centering')386print(r'\caption{Major Constellation Configurations}')387print(r'\begin{tabular}{lcccc}')388print(r'\toprule')389print(r'Constellation & Satellites & Planes & Altitude (km) & Inclination \\')390print(r'\midrule')391for name, params in constellations.items():392print(f"{name} & {params['T']} & {params['P']} & {params['h']} & {params['i']:.1f}$^\\circ$ \\\\")393print(r'\bottomrule')394print(r'\end{tabular}')395print(r'\end{table}')396\end{pycode}397398\section{Design Guidelines}399400\subsection{Mission-Specific Recommendations}401\begin{itemize}402\item \textbf{Earth Observation}: Sun-synchronous LEO (600-800 km), consistent lighting403\item \textbf{Communications (Global)}: MEO or large LEO constellations404\item \textbf{Navigation}: MEO (20,000+ km) for geometric diversity405\item \textbf{Broadband Internet}: Dense LEO for low latency406\item \textbf{Polar Coverage}: High-inclination or Molniya orbits407\end{itemize}408409\subsection{Constellation Sizing}410Minimum satellites for continuous global coverage:411\begin{equation}412N_{min} \approx \frac{4\pi}{\Omega_{sat}} = \frac{2}{1 - \cos\rho}413\end{equation}414where $\Omega_{sat}$ is the solid angle covered by one satellite.415416\section{Limitations and Extensions}417418\subsection{Model Limitations}419\begin{enumerate}420\item \textbf{Spherical Earth}: Does not account for Earth oblateness421\item \textbf{No terrain}: Ignores terrain masking effects422\item \textbf{Circular orbits}: Eccentric orbits not considered423\item \textbf{Simplified overlap}: Inter-satellite links not modeled424\end{enumerate}425426\subsection{Possible Extensions}427\begin{itemize}428\item J2 perturbation for realistic orbit propagation429\item Terrain masking with digital elevation models430\item Monte Carlo analysis for coverage statistics431\item Inter-satellite link topology optimization432\end{itemize}433434\section{Conclusion}435This analysis demonstrates the key trade-offs in satellite coverage design:436\begin{itemize}437\item Higher altitudes increase coverage but reduce resolution438\item Lower elevation angles expand coverage but degrade link quality439\item Constellation design must balance satellite count against coverage needs440\item Modern mega-constellations (Starlink, OneWeb) use hundreds of LEO satellites for continuous global coverage with low latency441\end{itemize}442443\section*{References}444\begin{itemize}445\item Wertz, J. R., \& Larson, W. J. (1999). \textit{Space Mission Analysis and Design}. Microcosm Press.446\item Walker, J. G. (1984). Satellite constellations. Journal of the British Interplanetary Society.447\item Maral, G., \& Bousquet, M. (2009). \textit{Satellite Communications Systems}. Wiley.448\end{itemize}449450\end{document}451452453