80 lines
2.9 KiB
Rust
80 lines
2.9 KiB
Rust
//! The link geometry type and the state of a link.
|
|
|
|
use apsis_math::Vec3;
|
|
|
|
/// The geometry of a link between two satellites.
|
|
///
|
|
/// The range is the straight line distance, which a link budget uses for the
|
|
/// free space path loss. The two pointing vectors are the directions each
|
|
/// terminal must aim, expressed in the frame the positions were given in.
|
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
pub struct LinkGeometry {
|
|
/// The distance between the two satellites, in kilometers.
|
|
pub range_km: f64,
|
|
/// The unit vector from the first satellite toward the second.
|
|
pub direction_first_to_second: Vec3,
|
|
/// The unit vector from the second satellite toward the first.
|
|
pub direction_second_to_first: Vec3,
|
|
/// The closest the line between the two passes to the centre of the
|
|
/// body, in kilometers.
|
|
///
|
|
/// This is the quantity that decides whether the link is blocked. It is
|
|
/// reported because a link that clears the limb by a small margin is
|
|
/// fragile: atmospheric refraction and the oblateness of the body both
|
|
/// eat into the margin.
|
|
pub centre_distance_km: f64,
|
|
}
|
|
|
|
impl LinkGeometry {
|
|
/// Returns the grazing margin of the link, in kilometers.
|
|
///
|
|
/// This is how far the line between the two satellites clears the
|
|
/// surface, measured at the closest point. A negative value means the
|
|
/// link is blocked.
|
|
pub fn surface_clearance(&self, body_radius: f64) -> f64 {
|
|
self.centre_distance_km - body_radius
|
|
}
|
|
|
|
/// Returns `true` when the link clears the body.
|
|
pub fn is_clear(&self, body_radius: f64) -> bool {
|
|
self.centre_distance_km >= body_radius
|
|
}
|
|
}
|
|
|
|
/// The state of a link at one instant.
|
|
///
|
|
/// A link is either carrying traffic or not. The reasons a link can be
|
|
/// unavailable are kept separate, because routing across a constellation has
|
|
/// to distinguish a link that is geometrically blocked from one that is
|
|
/// merely not established yet.
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
pub enum LinkState {
|
|
/// The link is geometrically clear and may be used.
|
|
Available,
|
|
/// The Earth blocks the line between the two satellites.
|
|
Blocked,
|
|
/// The Sun is within the field of view of one of the terminals, so an
|
|
/// optical link cannot be used.
|
|
SunInField,
|
|
/// The link is clear but is not established, for example because it has
|
|
/// not yet been acquired or its capacity is exhausted.
|
|
NotEstablished,
|
|
}
|
|
|
|
impl LinkState {
|
|
/// Returns `true` when the link may carry traffic.
|
|
pub const fn is_usable(self) -> bool {
|
|
matches!(self, Self::Available)
|
|
}
|
|
|
|
/// Returns a short name for the state.
|
|
pub const fn name(self) -> &'static str {
|
|
match self {
|
|
Self::Available => "available",
|
|
Self::Blocked => "blocked",
|
|
Self::SunInField => "sun in field",
|
|
Self::NotEstablished => "not established",
|
|
}
|
|
}
|
|
}
|