-
Notifications
You must be signed in to change notification settings - Fork 1
/
sim_for_mobile_joining_node.py
133 lines (102 loc) · 6.25 KB
/
sim_for_mobile_joining_node.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import math
import multiprocessing
import os
import random
import sqlite3
from multiprocessing.pool import Pool
from pandas import Timedelta
from ieee802154.tsch.joining_phase_simulator import JoiningPhaseSimulator, EBSchedulingMethod
from ieee802154.node import Node, NodeType
from ieee802154.node_group import NodeGroup, NodeGroupProperties
from ieee802154.pan_coordinator import PANCoordinator
from ieee802154.tsch import timeslot_template
def main(scheduling_method, atp_enabled=False):
db_name = "{}{}".format(scheduling_method.name, ("_with_ATP" if atp_enabled else ""))
db_conn = sqlite3.connect(os.path.join("statistics", "mobile_joining_node", "{}.db".format(db_name)))
c = db_conn.cursor()
c.execute('''CREATE TABLE mobile_node_joining_time_samples (advertisers INTEGER, time REAL)''')
db_conn.commit()
node_groups_samples_per_test = 1000
rejoin_attemps = 100
multislotframe_length = 5 # in slotframes. It is identical to the Enhanced Beacon Interval (EBI)
slotframe_length = 101
scanning_duration = (
2 * multislotframe_length * slotframe_length
* timeslot_template.defaultTimeslotTemplateFor2450MHzBand.mac_ts_timeslot_length
)
num_channels = 16
eb_length = 50 # in bytes
randomIns = random.Random()
channel_switching_time = Timedelta(200, unit="us")
tx_power = 0 # dBm
sensitivity = -100 # dBm
# According to the path loss model that is used (see the function __rx_power in the class JoiningPhaseSimulator),
# with tx_power = 0 and sensitivity = -100 the guaranteed range is 17m and the max possible distance of a receiver
# is 60m.
for num_advertisers in range(10, 151, 10):
# Note that we assume that all the advertisers are fixed nodes
node_group_samples = 0
while node_group_samples < node_groups_samples_per_test:
# Note that, the ids of advertisers affect only (E)CFAS
if scheduling_method in {EBSchedulingMethod.ECFASH, EBSchedulingMethod.ECFASV}:
# ids for advertisers except the PAN coordinator
num_available_ids = (math.ceil(
(num_advertisers - 1) / ((num_channels - 1) * multislotframe_length * (2 if atp_enabled else 1)))
* multislotframe_length * (num_channels - 1) * (2 if atp_enabled else 1))
else:
# ids for advertisers including the PAN coordinator
num_available_ids = (math.ceil(
num_advertisers / (num_channels * multislotframe_length * (2 if atp_enabled else 1)))
* multislotframe_length * num_channels * (2 if atp_enabled else 1))
available_ids = randomIns.sample(range(num_available_ids), k=num_available_ids) # in random order
ng = NodeGroup(NodeGroupProperties(250000, (100, 100)))
pc_id = (available_ids.pop() if scheduling_method not in {EBSchedulingMethod.ECFASH,
EBSchedulingMethod.ECFASV} else num_available_ids)
PANCoordinator(pc_id, (ng.properties.area_dimensions[0] * randomIns.random(),
ng.properties.area_dimensions[1] * randomIns.random()), tx_power, sensitivity,
Timedelta(0), channel_switching_time, ng)
# create fixed-nodes/advertisers (except the PAN coordinator)
for i in range(1, num_advertisers):
while True:
# find a random position that is in the guaranteed range of an already created (fixed) node
position = (ng.properties.area_dimensions[0] * randomIns.random(),
ng.properties.area_dimensions[1] * randomIns.random())
# check if at least one (fixed) node has this position in its range
if not all(node.distance_from_point(position) > 17 for node in ng):
break
Node(available_ids.pop(), position, False, NodeType.FFD, tx_power, sensitivity,
Timedelta(randomIns.random() * 100, unit="s"), channel_switching_time, ng)
# create a mobile node
initial_pos = (ng.properties.area_dimensions[0] * randomIns.random(),
ng.properties.area_dimensions[1] * randomIns.random())
# The mobile node is not an advertiser. We select an id that does not collide with the advertisers' ids
mobile_node_id = num_available_ids + 1
mobile_node = Node(mobile_node_id, initial_pos, True, NodeType.RFD, tx_power, sensitivity,
Timedelta(randomIns.random() * 100, unit="s"), channel_switching_time, ng)
simulator = JoiningPhaseSimulator(
ng, scheduling_method, timeslot_template.defaultTimeslotTemplateFor2450MHzBand,
slotframe_length, eb_length, num_channels, scanning_duration, multislotframe_length, atp_enabled)
simulator.execute()
# collect samples from the mobile node
for _ in range(rejoin_attemps):
res = simulator.rejoining_attempt(mobile_node, Timedelta(randomIns.random() * 100, unit="s"))
c.execute('''INSERT INTO mobile_node_joining_time_samples(advertisers, time) VALUES(?, ?)''',
(num_advertisers, res.total_seconds()))
db_conn.commit()
node_group_samples += 1
db_conn.close()
if __name__ == '__main__':
PROCESSES_TO_USE = multiprocessing.cpu_count()
# create a folder for statistics
os.makedirs(os.path.join("statistics", "mobile_joining_node"), exist_ok=True)
simulations = [
# (EBSchedulingMethod.ECV,), (EBSchedulingMethod.ECH,),
# (EBSchedulingMethod.Minimal6TiSCH,), (EBSchedulingMethod.ECFASV, False), (EBSchedulingMethod.ECFASV, True),
# (EBSchedulingMethod.CFASV, False), (EBSchedulingMethod.CFASV, True),
(EBSchedulingMethod.CFASH, False), (EBSchedulingMethod.CFASH, True),
# (EBSchedulingMethod.ECFASH, False), (EBSchedulingMethod.ECFASH, True),
# (EBSchedulingMethod.MAC_BASED_AS,),
# (EBSchedulingMethod.EMAC_BASED_AS,)
]
with Pool(processes=PROCESSES_TO_USE) as pool:
pool.starmap(main, simulations)