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 Trigger

Random triggering within a given time interval.

Sample Offset Trigger

Static triggering at a given sample offset.

Time Offset Trigger

Static triggering at a given time offset.

Static Trigger

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.

1device_A_Tx = simulation.new_device(carrier_frequency=3.7e9, bandwidth=400e6, oversampling_factor=4)
2device_A_Rx = simulation.new_device(carrier_frequency=3.7e9, bandwidth=400e6, oversampling_factor=4)
3device_B_Tx = simulation.new_device(carrier_frequency=3.9e9, bandwidth=400e6, oversampling_factor=4)
4device_B_Rx = simulation.new_device(carrier_frequency=3.9e9, bandwidth=400e6, oversampling_factor=4)

The exchanged waveforms are identical, however, devices are considered to be only synchronized to their linked partners.

1trigger_model_A = TriggerModel()
2device_A_Tx.trigger_model = trigger_model_A
3device_A_Rx.trigger_model = trigger_model_A
4
5trigger_model_B = TriggerModel()
6device_B_Tx.trigger_model = trigger_model_B
7device_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')