Synchronization¶
Synchronization between simulated devices is modeled by Trigger Models. Simulated device instances sharing the same Trigger Model instance are considered time-synchronized with each other, but not with other simulated devices that do not share the same Trigger Model.
%%{init: {"flowchart":{"useMaxWidth": false}}}%% flowchart LR subgraph Synchronization direction TB trigger[TriggerModel] --> trigger_realization[TriggerRealization] end device_a[Simulated Device] device_b[ ⋮ ]:::invis device_c[Simulated Device] trigger_realization --> device_a trigger_realization --> device_b trigger_realization --> device_c classDef invis fill-opacity:0,stroke-opacity:0,font-weight:bold; click trigger href "simulation.synchronization.TriggerModel.html" click trigger_realization href "simulation.synchronization.TriggerRealization.html" click device_a href "simulation.simulated_device.html" click device_b href "simulation.simulated_device.html" click device_c href "simulation.simulated_device.html"
During the generation of each simulation drop, the Trigger Model instance is realized once for all simulated devices sharing the same instance, resulting in a single Trigger Realization.
Note that, as the name suggests, HermesPy’s synchronization model is considered to be at the trigger level of transmitting and receiving devices, meaning propagation delays due to channel models linking synchronized devices must still be compensated by appropriate equalization routines. The currently available Trigger Model implementations are:
Trigger Model |
Description |
---|---|
Random triggering within a given time interval. |
|
Static triggering at a given sample offset. |
|
Static triggering at a given time offset. |
|
Static triggering with no offset. This is the default. |
Consider a scenario featuring four wireless devices, with two devices respectively linked, interfering with each other on partially overlapping frequency bands.
1# Create a new simulation featuring two sets of two linked, synchronized devices
2simulation = Simulation()
3
4# Create devices
5device_A_Tx = simulation.new_device(carrier_frequency=3.7e9)
6device_A_Rx = simulation.new_device(carrier_frequency=3.7e9)
7device_B_Tx = simulation.new_device(carrier_frequency=3.9e9)
8device_B_Rx = simulation.new_device(carrier_frequency=3.9e9)
The exchanged waveforms are identical, however, devices are considered to be only synchronized to their linked partners.
1# Link devices
2link_A = SimplexLink(waveform=deepcopy(waveform))
3link_B = SimplexLink(waveform=deepcopy(waveform))
4device_A_Tx.transmitters.add(link_A)
5device_A_Rx.receivers.add(link_A)
6device_B_Tx.transmitters.add(link_B)
7device_B_Rx.receivers.add(link_B)
8
9# Specify trigger models
10trigger_model_A = TriggerModel()
11device_A_Tx.trigger_model = trigger_model_A
12device_A_Rx.trigger_model = trigger_model_A
13
14trigger_model_B = TriggerModel()
15device_B_Tx.trigger_model = trigger_model_B
16device_B_Rx.trigger_model = trigger_model_B
Of course, the abstract TriggerModel in the above snippet must be replaced by the desired implementation from the list above. By generating a single drop of the simulation and plotting the bit error rates of the two devices, we may visualize the impact of partially overlapping commuication frames in time-domain due to the interference in between the two links.
1# Configure BER evaluators for each link
2ber_A = BitErrorEvaluator(link_A, link_A)
3ber_B = BitErrorEvaluator(link_B, link_B)
4
5# Generate drop
6_ = simulation.scenario.drop()
7
8# Visualize BERs that should spike at the frame overlaps
9ber_A.evaluate().visualize(title='Link A Bit Error Rate')
10ber_B.evaluate().visualize(title='Link B Bit Error Rate')