///|
pub struct GroundStation {
name : String
location : Geodetic
min_elevation_rad : Double
} derive(Debug, Eq)
///|
pub struct VisibilitySample {
epoch : Epoch
look : LookAngle
visible : Bool
} derive(Debug, Eq)
///|
pub struct VisibilityWindow {
start : Epoch
end : Epoch
max_elevation_rad : Double
closest_range_km : Double
} derive(Debug, Eq)
///|
pub fn GroundStation::new(
name : String,
latitude_rad : Double,
longitude_rad : Double,
altitude_km? : Double = 0.0,
min_elevation_rad? : Double = radians(5.0),
) -> GroundStation {
{
name,
location: Geodetic::new(latitude_rad, longitude_rad, altitude_km),
min_elevation_rad,
}
}
///|
pub fn sample_visibility(
station : GroundStation,
epoch : Epoch,
satellite_eci_km : Vec3,
) -> VisibilitySample {
let look = look_angle_from_eci(station.location, epoch, satellite_eci_km)
{ epoch, look, visible: look.elevation_rad >= station.min_elevation_rad }
}
///|
pub fn sample_kepler_visibility(
mu : Double,
station : GroundStation,
start : Epoch,
elements : ClassicalElements,
step_s : Double,
count : Int,
) -> Array[VisibilitySample] {
let samples : Array[VisibilitySample] = []
for k in 0.. Array[VisibilityWindow] {
let windows : Array[VisibilityWindow] = []
let mut active = false
let mut start = Epoch::j2000()
let mut end = Epoch::j2000()
let mut max_el = -half_pi
let mut min_range = 1.0e30
for sample in samples {
if sample.visible {
if !active {
active = true
start = sample.epoch
max_el = sample.look.elevation_rad
min_range = sample.look.range_km
}
end = sample.epoch
if sample.look.elevation_rad > max_el {
max_el = sample.look.elevation_rad
}
if sample.look.range_km < min_range {
min_range = sample.look.range_km
}
} else if active {
windows.push({
start,
end,
max_elevation_rad: max_el,
closest_range_km: min_range,
})
active = false
}
}
if active {
windows.push({
start,
end,
max_elevation_rad: max_el,
closest_range_km: min_range,
})
}
windows
}
///|
pub fn is_line_of_sight_clear(site_ecef : Vec3, satellite_ecef : Vec3) -> Bool {
let rho = satellite_ecef.sub(site_ecef)
let projection = site_ecef.dot(rho)
projection > 0.0
}