Walker constellations are satellite constellations designed for optimal coverage using symmetric orbital plane distributions. Named after John Walker, who formalized the notation in 1984, these patterns are fundamental to modern satellite system design.
Walker Delta distributes planes around the full 360° of RAAN, providing global coverage. This is the pattern used by GPS, Galileo, and GLONASS.
Walker Star distributes planes across only 180° of RAAN, concentrating coverage at polar regions. This pattern is used by Iridium for its polar LEO constellation.
importbraheasbhbh.initialize_eop()# Create epoch for constellationepoch=bh.Epoch.from_datetime(2024,1,1,12,0,0.0,0.0,bh.TimeSystem.UTC)# Create a GPS-like 24:6:2 Walker Delta constellation# T:P:F = 24:6:2 means:# - T = 24 total satellites# - P = 6 orbital planes# - F = 2 phasing factorwalker=bh.WalkerConstellationGenerator(t=24,p=6,f=2,semi_major_axis=bh.R_EARTH+20200e3,# GPS altitudeeccentricity=0.0,inclination=55.0,# GPS inclinationargument_of_perigee=0.0,reference_raan=0.0,reference_mean_anomaly=0.0,epoch=epoch,angle_format=bh.AngleFormat.DEGREES,pattern=bh.WalkerPattern.DELTA,).with_base_name("GPS")# Print constellation propertiesprint(f"Total satellites: {walker.total_satellites}")print(f"Number of planes: {walker.num_planes}")print(f"Satellites per plane: {walker.satellites_per_plane}")print(f"Phasing factor: {walker.phasing}")print(f"Pattern: {walker.pattern}")# Get orbital elements for the first satellite in each planeprint("\nFirst satellite in each plane:")forplaneinrange(walker.num_planes):elements=walker.satellite_elements(plane,0,bh.AngleFormat.DEGREES)print(f" Plane {plane}: RAAN = {elements[3]:.1f} deg, MA = {elements[5]:.1f} deg")# Generate Keplerian propagators for all satellitespropagators=walker.as_keplerian_propagators(60.0)# 60 second step sizeprint(f"\nGenerated {len(propagators)} Keplerian propagators")print(f"First propagator name: {propagators[0].get_name()}")print(f"Last propagator name: {propagators[-1].get_name()}")# Expected output:# Total satellites: 24# Number of planes: 6# Satellites per plane: 4# Phasing factor: 2# Pattern: DELTA## First satellite in each plane:# Plane 0: RAAN = 0.0 deg, MA = 0.0 deg# Plane 1: RAAN = 60.0 deg, MA = 30.0 deg# Plane 2: RAAN = 120.0 deg, MA = 60.0 deg# Plane 3: RAAN = 180.0 deg, MA = 90.0 deg# Plane 4: RAAN = 240.0 deg, MA = 120.0 deg# Plane 5: RAAN = 300.0 deg, MA = 150.0 deg## Generated 24 Keplerian propagators# First propagator name: GPS-P0-S0# Last propagator name: GPS-P5-S3
usebraheasbh;usebh::utils::Identifiable;fnmain(){bh::initialize_eop().unwrap();// Create epoch for constellationletepoch=bh::time::Epoch::from_datetime(2024,1,1,12,0,0.0,0.0,bh::TimeSystem::UTC);// Create a GPS-like 24:6:2 Walker Delta constellation// T:P:F = 24:6:2 means:// - T = 24 total satellites// - P = 6 orbital planes// - F = 2 phasing factorletwalker=bh::orbits::WalkerConstellationGenerator::new(24,// T = 24 total satellites6,// P = 6 orbital planes2,// F = 2 phasing factorbh::constants::R_EARTH+20200e3,// GPS altitude0.0,// eccentricity55.0,// inclination (degrees)0.0,// argument of perigee0.0,// reference RAAN0.0,// reference mean anomalyepoch,bh::constants::AngleFormat::Degrees,bh::orbits::WalkerPattern::Delta,).with_base_name("GPS");// Print constellation propertiesprintln!("Total satellites: {}",walker.total_satellites);println!("Number of planes: {}",walker.num_planes);println!("Satellites per plane: {}",walker.satellites_per_plane());println!("Phasing factor: {}",walker.phasing);println!("Pattern: {:?}",walker.pattern);// Get orbital elements for the first satellite in each planeprintln!("\nFirst satellite in each plane:");forplanein0..walker.num_planes{letelements=walker.satellite_elements(plane,0);letraan_deg=elements[3]*bh::constants::RAD2DEG;letma_deg=elements[5]*bh::constants::RAD2DEG;println!(" Plane {}: RAAN = {:.1} deg, MA = {:.1} deg",plane,raan_deg,ma_deg);}// Generate Keplerian propagators for all satellitesletpropagators=walker.as_keplerian_propagators(60.0);// 60 second step sizeprintln!("\nGenerated {} Keplerian propagators",propagators.len());println!("First propagator name: {}",propagators[0].get_name().unwrap_or_default());println!("Last propagator name: {}",propagators.last().unwrap().get_name().unwrap_or_default());// Expected output:// Total satellites: 24// Number of planes: 6// Satellites per plane: 4// Phasing factor: 2// Pattern: Delta//// First satellite in each plane:// Plane 0: RAAN = 0.0 deg, MA = 0.0 deg// Plane 1: RAAN = 60.0 deg, MA = 30.0 deg// Plane 2: RAAN = 120.0 deg, MA = 60.0 deg// Plane 3: RAAN = 180.0 deg, MA = 90.0 deg// Plane 4: RAAN = 240.0 deg, MA = 120.0 deg// Plane 5: RAAN = 300.0 deg, MA = 150.0 deg//// Generated 24 Keplerian propagators// First propagator name: GPS-P0-S0// Last propagator name: GPS-P5-S3}
importbraheasbhbh.initialize_eop()# Create epoch for constellationepoch=bh.Epoch.from_datetime(2024,1,1,12,0,0.0,0.0,bh.TimeSystem.UTC)# Create a GPS-like 24:6:2 Walker Delta constellationwalker=bh.WalkerConstellationGenerator(t=24,p=6,f=2,semi_major_axis=bh.R_EARTH+20200e3,# GPS altitudeeccentricity=0.0,inclination=55.0,# GPS inclinationargument_of_perigee=0.0,reference_raan=0.0,reference_mean_anomaly=0.0,epoch=epoch,angle_format=bh.AngleFormat.DEGREES,pattern=bh.WalkerPattern.DELTA,).with_base_name("GPS")print(f"Created {walker.total_satellites} satellite Walker Delta constellation")print(f"Orbital planes: {walker.num_planes}")print(f"RAAN spacing: 360/{walker.num_planes} = {360/walker.num_planes:.0f} degrees")# Generate Keplerian propagators and propagate for one orbitpropagators=walker.as_keplerian_propagators(60.0)# Propagate each satellite for one complete orbitforpropinpropagators:# Get semi-major axis from Keplerian elements [a, e, i, raan, argp, M]koe=prop.state_koe_osc(prop.initial_epoch,bh.AngleFormat.RADIANS)orbital_period=bh.orbital_period(koe[0])prop.propagate_to(prop.initial_epoch+orbital_period)print(f"\nPropagated all {len(propagators)} satellites for one orbital period")# Create interactive 3D plot with Earth texturefig=bh.plot_trajectory_3d([{"trajectory":prop.trajectory,"mode":"markers","size":2,"label":prop.get_name(),}forpropinpropagators],units="km",show_earth=True,earth_texture="natural_earth_50m",backend="plotly",view_azimuth=45.0,view_elevation=30.0,view_distance=2.0,)# ============================================================================# Plot Output Section (for documentation generation)# ============================================================================# ruff: noqa: E402importosimportpathlibimportsys# Add plots directory to path for importing brahe_themesys.path.insert(0,str(pathlib.Path(__file__).parent.parent.parent/"plots"))frombrahe_themeimportsave_themed_html# ConfigurationSCRIPT_NAME=pathlib.Path(__file__).stemOUTDIR=pathlib.Path(os.getenv("BRAHE_FIGURE_OUTPUT_DIR","./docs/figures/"))os.makedirs(OUTDIR,exist_ok=True)# Save the figure as themed HTMLlight_path,dark_path=save_themed_html(fig,OUTDIR/SCRIPT_NAME)print(f"\n✓ Generated {light_path}")print(f"✓ Generated {dark_path}")
importbraheasbhbh.initialize_eop()# Create epoch for constellationepoch=bh.Epoch.from_datetime(2024,1,1,12,0,0.0,0.0,bh.TimeSystem.UTC)# Create an Iridium-like 66:6:2 Walker Star constellationwalker=bh.WalkerConstellationGenerator(t=66,p=6,f=2,semi_major_axis=bh.R_EARTH+780e3,# Iridium altitudeeccentricity=0.0,inclination=86.4,# Near-polar inclinationargument_of_perigee=0.0,reference_raan=0.0,reference_mean_anomaly=0.0,epoch=epoch,angle_format=bh.AngleFormat.DEGREES,pattern=bh.WalkerPattern.STAR,# 180 deg RAAN spread).with_base_name("IRIDIUM")print(f"Created {walker.total_satellites} satellite Walker Star constellation")print(f"Orbital planes: {walker.num_planes}")print(f"RAAN spacing: 180/{walker.num_planes} = {180/walker.num_planes:.0f} degrees")# Generate Keplerian propagators and propagate for one orbitpropagators=walker.as_keplerian_propagators(60.0)# Propagate each satellite for one complete orbitforpropinpropagators:# Get semi-major axis from Keplerian elements [a, e, i, raan, argp, M]koe=prop.state_koe_osc(prop.initial_epoch,bh.AngleFormat.RADIANS)orbital_period=bh.orbital_period(koe[0])prop.propagate_to(prop.initial_epoch+orbital_period)print(f"\nPropagated all {len(propagators)} satellites for one orbital period")# Create interactive 3D plot with Earth texturefig=bh.plot_trajectory_3d([{"trajectory":prop.trajectory,"mode":"markers","size":2,"label":prop.get_name(),}forpropinpropagators],units="km",show_earth=True,earth_texture="natural_earth_50m",backend="plotly",view_azimuth=45.0,view_elevation=30.0,view_distance=2.0,)# ============================================================================# Plot Output Section (for documentation generation)# ============================================================================# ruff: noqa: E402importosimportpathlibimportsys# Add plots directory to path for importing brahe_themesys.path.insert(0,str(pathlib.Path(__file__).parent.parent.parent/"plots"))frombrahe_themeimportsave_themed_html# ConfigurationSCRIPT_NAME=pathlib.Path(__file__).stemOUTDIR=pathlib.Path(os.getenv("BRAHE_FIGURE_OUTPUT_DIR","./docs/figures/"))os.makedirs(OUTDIR,exist_ok=True)# Save the figure as themed HTMLlight_path,dark_path=save_themed_html(fig,OUTDIR/SCRIPT_NAME)print(f"\n✓ Generated {light_path}")print(f"✓ Generated {dark_path}")