3
3
import logging
4
4
from abc import ABC , abstractmethod
5
5
from copy import copy
6
- from itertools import combinations
6
+ from itertools import permutations
7
7
from typing import TYPE_CHECKING
8
8
9
9
import numpy as np
@@ -47,7 +47,7 @@ def link_satellites(self, satellites: list["Satellite"]) -> None:
47
47
48
48
@abstractmethod # pragma: no cover
49
49
def communication_pairs (self ) -> list [tuple ["Satellite" , "Satellite" ]]:
50
- """List pairs of satellite that should share data.
50
+ """List pairs of satellite that should share data, in the form (sender, recipient) .
51
51
52
52
To define a new communication type, this method must be implemented.
53
53
"""
@@ -68,12 +68,13 @@ def communicate(self) -> None:
68
68
f"Communicating data between { len (communication_pairs )} pairs of satellites"
69
69
)
70
70
71
- if len (communication_pairs ) == comb (len (self .satellites ), 2 ):
71
+ if len (communication_pairs ) == 2 * comb (len (self .satellites ), 2 ):
72
72
self ._communicate_all ()
73
73
else :
74
- for sat_1 , sat_2 in communication_pairs :
75
- sat_1 .data_store .stage_communicated_data (sat_2 .data_store .data )
76
- sat_2 .data_store .stage_communicated_data (sat_1 .data_store .data )
74
+ for sat_sender , sat_receiver in communication_pairs :
75
+ sat_receiver .data_store .stage_communicated_data (
76
+ sat_sender .data_store .data
77
+ )
77
78
for satellite in self .satellites :
78
79
satellite .data_store .update_with_communicated_data ()
79
80
@@ -116,7 +117,7 @@ def __init__(self, *args, **kwargs) -> None:
116
117
117
118
def communication_pairs (self ) -> list [tuple ["Satellite" , "Satellite" ]]:
118
119
"""Return all possible communication pairs."""
119
- return list (combinations (self .satellites , 2 ))
120
+ return list (permutations (self .satellites , 2 ))
120
121
121
122
122
123
class LOSCommunication (CommunicationMethod ):
@@ -177,6 +178,7 @@ def communication_pairs(self) -> list[tuple["Satellite", "Satellite"]]:
177
178
for sat_2 , logger in logs .items ():
178
179
if any (logger .hasAccess ):
179
180
pairs .append ((sat_1 , sat_2 ))
181
+ pairs .append ((sat_2 , sat_1 ))
180
182
return pairs
181
183
182
184
def communicate (self ) -> None :
@@ -208,7 +210,7 @@ def communication_pairs(self) -> list[tuple["Satellite", "Satellite"]]:
208
210
pairs = []
209
211
n_components , labels = connected_components (graph , directed = False )
210
212
for comp in range (n_components ):
211
- for i_sat_1 , i_sat_2 in combinations (np .where (labels == comp )[0 ], 2 ):
213
+ for i_sat_1 , i_sat_2 in permutations (np .where (labels == comp )[0 ], 2 ):
212
214
pairs .append ((self .satellites [i_sat_1 ], self .satellites [i_sat_2 ]))
213
215
return pairs
214
216
@@ -222,4 +224,30 @@ class LOSMultiCommunication(MultiDegreeCommunication, LOSCommunication):
222
224
pass
223
225
224
226
227
+ class BroadcastCommunication (CommunicationMethod ):
228
+ def communication_pairs (self ) -> list [tuple ["Satellite" , "Satellite" ]]:
229
+ """Return pairs of satellites that used broadcast action."""
230
+ broadcasters = []
231
+ for satellite in self .satellites :
232
+ if any (
233
+ hasattr (act , "broadcast_pending" ) and act .broadcast_pending
234
+ for act in satellite .action_builder .action_spec
235
+ ):
236
+ broadcasters .append (satellite )
237
+
238
+ pairs = super ().communication_pairs ()
239
+ pairs = [
240
+ (sat_sender , sat_receiver )
241
+ for sat_sender , sat_receiver in pairs
242
+ if sat_sender in broadcasters
243
+ ]
244
+
245
+ for satellite in broadcasters :
246
+ for act in satellite .action_builder .action_spec :
247
+ if hasattr (act , "broadcast_pending" ):
248
+ act .broadcast_pending = False
249
+
250
+ return pairs
251
+
252
+
225
253
__all__ = []
0 commit comments