leodos_protocols/network/isl/routing/algorithm/
distance_minimizing.rs1use core::f32::consts::PI;
4
5use crate::network::isl::address::Address;
6use crate::network::isl::routing::algorithm::RoutingAlgorithm;
7use crate::network::isl::routing::algorithm::gateway::GatewayTable;
8use crate::network::isl::shell::Shell;
9use crate::network::isl::torus::{Direction, Hop};
10use crate::network::isl::torus::Point;
11
12pub struct DistanceMinimizing<const N: usize> {
16 shell: Shell,
17 gateway_table: GatewayTable<N>,
18}
19
20impl<const N: usize> DistanceMinimizing<N> {
21 pub fn new(
23 shell: Shell,
24 gateway_table: GatewayTable<N>,
25 ) -> Self {
26 Self { shell, gateway_table }
27 }
28
29 fn cross_plane_factor(&self, anomaly: f32) -> f32 {
34 let cos_theta = libm::cosf(anomaly);
35 let sin_theta = libm::sinf(anomaly);
36 let cos_inc = libm::cosf(self.shell.inclination_rad);
37 libm::sqrtf(
38 cos_theta * cos_theta
39 + cos_inc * cos_inc * sin_theta * sin_theta,
40 )
41 }
42
43 fn effective_anomaly(
46 &self,
47 orb: u8,
48 time_s: u32,
49 ) -> f32 {
50 let num_orbs = self.shell.torus.num_orbs as f32;
51 let base = 2.0 * PI * (orb as f32) / num_orbs;
52 base + 2.0 * PI * time_s as f32
53 / self.shell.orbital_period_s()
54 }
55
56 fn route_to_point(
57 &self,
58 current: Point,
59 target: Point,
60 time_s: u32,
61 ) -> Direction {
62 let torus = &self.shell.torus;
63
64 if current.orb == target.orb {
65 return torus.direction_to_sat(
66 current, target,
67 );
68 }
69
70 if current.sat == target.sat {
71 return torus.direction_to_orb(
72 current, target,
73 );
74 }
75
76 let v_dir =
77 torus.direction_to_orb(current, target);
78 let toward_orb = match v_dir {
79 Direction::East => torus.next_orb(current),
80 _ => torus.prev_orb(current),
81 };
82
83 let curr_anomaly =
84 self.effective_anomaly(current.orb, time_s);
85 let toward_anomaly =
86 self.effective_anomaly(toward_orb, time_s);
87
88 let curr_factor = self.cross_plane_factor(curr_anomaly);
89 let toward_factor =
90 self.cross_plane_factor(toward_anomaly);
91
92 if toward_factor < curr_factor {
93 v_dir
94 } else {
95 torus.direction_to_sat(current, target)
96 }
97 }
98}
99
100impl<const N: usize> RoutingAlgorithm for DistanceMinimizing<N> {
101 fn route(
102 &self,
103 current: Point,
104 target: Address,
105 time_s: u32,
106 ) -> Hop {
107 let (target_point, local_hop) = match target {
108 Address::Satellite(p) => (p, Hop::Local),
109 Address::Ground { station } => {
110 let gw = self
111 .gateway_table
112 .gateway(&self.shell, station, time_s)
113 .unwrap_or(Point {
114 orb: 0,
115 sat: station,
116 });
117 (gw, Hop::Ground)
118 }
119 Address::ServiceArea { orb } => (
120 Point { orb: current.orb, sat: orb },
121 Hop::Local,
122 ),
123 };
124 if current == target_point {
125 return local_hop;
126 }
127 Hop::Isl(self.route_to_point(current, target_point, time_s))
128 }
129}