Skip to main content

leodos_protocols/network/isl/routing/algorithm/
gateway.rs

1use crate::network::isl::geo::LatLon;
2use crate::network::isl::projection::Projection;
3use crate::network::isl::shell::Shell;
4use crate::network::isl::torus::Point;
5
6/// Maps ground station IDs to geographic positions and
7/// resolves the best gateway satellite via line-of-sight.
8pub struct GatewayTable<const N: usize> {
9    stations: heapless::Vec<(u8, LatLon), N>,
10    min_elevation_deg: f32,
11}
12
13impl<const N: usize> GatewayTable<N> {
14    /// Creates an empty gateway table.
15    pub fn new(min_elevation_deg: f32) -> Self {
16        Self {
17            stations: heapless::Vec::new(),
18            min_elevation_deg,
19        }
20    }
21
22    /// Registers a ground station with its geographic position.
23    pub fn add_station(&mut self, station: u8, position: LatLon) {
24        self.stations.push((station, position)).ok();
25    }
26
27    /// Finds the gateway satellite for a ground station at
28    /// the given time using line-of-sight calculation.
29    ///
30    /// Returns `None` if the station ID is unknown or no
31    /// satellite has LOS.
32    pub fn gateway(
33        &self,
34        shell: &Shell,
35        station: u8,
36        time_s: u32,
37    ) -> Option<Point> {
38        let (_, pos) = self
39            .stations
40            .iter()
41            .find(|(id, _)| *id == station)?;
42        let proj = Projection::new(*shell);
43        proj.find_gateway(*pos, time_s as f32, self.min_elevation_deg)
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50    use crate::network::isl::torus::Torus;
51
52    #[test]
53    fn gateway_for_known_station() {
54        let torus = Torus::new(20, 72);
55        let shell = Shell::new(torus, 550_000.0, 87.0);
56
57        let mut table = GatewayTable::<4>::new(5.0);
58        table.add_station(0, LatLon::new(0.0, 0.0));
59
60        let gw = table.gateway(&shell, 0, 0);
61        assert!(gw.is_some(), "should find gateway at t=0");
62    }
63
64    #[test]
65    fn gateway_for_unknown_station() {
66        let torus = Torus::new(20, 72);
67        let shell = Shell::new(torus, 550_000.0, 87.0);
68
69        let table = GatewayTable::<4>::new(5.0);
70        let gw = table.gateway(&shell, 99, 0);
71        assert!(gw.is_none());
72    }
73}