-
Notifications
You must be signed in to change notification settings - Fork 2
/
measurements.py
206 lines (173 loc) · 6.14 KB
/
measurements.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#!/usr/bin/python3
"""
Collect helper functions to load data from sqlite files and apply different
calibration values.
"""
import sqlite3
import json
MODEL_RX_TX_COMPENSATION_OUR = {
# Based on our measurements in an anechoic chamber
'iPhone7': [3.0, -5.0],
'iPhoneXR': [0.5, 0.0],
'iPhoneXS': [0.0, 1.0],
'iPhone11': [0.0, 1.0], # no i11 - i11 measurements
'iPhone11Pro': [0.0, 0.0],
'SM-G973F': [-3.0, -24.0],
'SM-G970F': [-5.0, -23.0],
'SM-A405FN': [4.0, -24.0],
'SM-A515F': [-7, -23.0],
'SM-A908B': [-2.0, -20.0],
'SM-G981B/DS': [3.0, -25.5]
}
MODEL_RX_TX_COMPENSATION = { # date: 201214
# Official Google calibration of 20/12/14
'iPhone7': [0.0, 3.0],
'iPhoneXR': [0.0, 0.0],
'iPhoneXS': [0.0, 3.0],
'iPhone11': [0.0, 1.0],
'iPhone11Pro': [0.0, 3.0],
'SM-G973F': [2.0, -29.0],
'SM-G970F': [5.0, -25.0],
'SM-A405FN': [2.0, -23.0],
'SM-A515F': [2.0, -28.0],
'SM-A908B': [5.0, -25.0],
'SM-G981B/DS': [5.0, -25.0] # SM-G981B in table
}
MODEL_RX_TX_COMPENSATION_200918 = { # date: 200918
# Official Google calibration of 20/09/18
'iPhone7': [0.0, 3.0],
'iPhoneXR': [0.0, 0.0],
'iPhoneXS': [0.0, 3.0],
'iPhone11': [0.0, 1.0],
'iPhone11Pro': [0.0, 3.0],
'SM-G973F': [2.0, -29.0],
'SM-G970F': [5.0, -24.0],
'SM-A405FN': [2.0, -23.0],
'SM-A515F': [5.0, -24.0],
'SM-A908B': [5.0, -24.0],
'SM-G981B/DS': [5.0, -24.0] # SM-G981B in table
}
MODEL_RX_TX_COMPENSATION_200813 = { # date: 200813
# Official Google calibration of 20/08/13
'iPhone7': [0.0, 3.0],
'iPhoneXR': [0.0, 0.0],
'iPhoneXS': [0.0, 3.0],
'iPhone11': [0.0, 1.0],
'iPhone11Pro': [0.0, 3.0],
'SM-G973F': [5.0, -24.0],
'SM-G970F': [5.0, -24.0],
'SM-A405FN': [5.0, -24.0],
'SM-A515F': [5.0, -24.0],
'SM-A908B': [5.0, -24.0],
'SM-G981B/DS': [5.0, -24.0] # SM-G981B in table
}
MODEL_RX_TX_COMPENSATION_200613 = {
# Official Google calibration of 20/06/13
'iPhone7': [0.0, 3.0],
'iPhoneXR': [0.0, 0.0],
'iPhoneXS': [0.0, 3.0],
'iPhone11': [0.0, 1.0],
'iPhone11Pro': [0.0, 3.0],
'SM-G973F': [-3.0, -24.0],
'SM-G970F': [-3.0, -24.0],
'SM-A405FN': [-3.0, -24.0],
'SM-A515F': [-3.0, -24.0],
'SM-A908B': [-3.0, -24.0],
'SM-G981B/DS': [-3.0, -24.0] # SM-G981B in table
}
MODEL_RX_TX_COMPENSATION_200530 = {
# early internal data used for testing
'iPhone7': [0.0, 3.0],
'iPhoneXR': [0.0, 0.0],
'iPhoneXS': [0.0, 3.0],
'iPhone11': [0.0, 1.0],
'iPhone11Pro': [0.0, 3.0],
'SM-G973F': [10.0, 0.0], # off
'SM-G970F': [-4.0, -14.0],
'SM-A405FN': [-4.0, -14.0],
'SM-A515F': [-4.0, -14.0],
'SM-A908B': [-4.0, -14.0],
'SM-G981B/DS': [-4.0, -14.0]
}
# Google values taken from https://developers.google.com/android/exposure-notifications/ble-attenuation-computation
def get_measurements(filename, receiver, transmitter):
'''
Get measurements sent from a transmitter to a receiver.
Returns an array of [RSSI] values
'''
results = []
conn = sqlite3.connect(filename)
c = conn.cursor()
args = (receiver, transmitter)
c.execute('SELECT rssi FROM results WHERE transmitter_id = ? AND receiver_id = ?', args)
temp = c.fetchall()
for i in range(0, len(temp)):
if temp[i][0] < -20:
# filter iPhone "special" values
results.append(temp[i][0])
conn.close()
return results
def get_model(filename, phone_id):
'''
Get model of a transmitting phone.
Returns a string
'''
conn = sqlite3.connect(filename)
c = conn.cursor()
c.execute('SELECT transmitter_model FROM results WHERE transmitter_id = ?', (phone_id,))
temp = c.fetchall()
model = temp[0][0]
conn.close()
return model
def get_attenuations(filename, compensation=MODEL_RX_TX_COMPENSATION):
'''
Get a set of attenuations, compensated with the supplied model.
Returns an array of [(attenuation, ground truth distance)] tuples
'''
results = []
conn = sqlite3.connect(filename)
c = conn.cursor()
c.execute('SELECT rssi, tx_power, receiver_model, transmitter_model, ground_truth_distance FROM results')
temp = c.fetchall()
for i in range(0, len(temp)):
rssi = temp[i][0]
phonetx = temp[i][1]
# Check if data was recorded with TX_POWER_ULTRA_LOW, adjust to GAEN
# ULTRA_LOW = -21, LOW = -15, must adjust attenuation by 6
# This allows us to use the calibration values in the table uniformly
adjust = 0
if phonetx == -21 or phonetx == -20:
adjust = 6
# Extract txpower and rxadjust from compensation table
txpower = compensation[temp[i][2]][1]
rxadjust = compensation[temp[i][3]][0]
# NOTE: before using the updated GAEN calibration data, we used an
# approximation of the calibration for all Samsung devices which
# resulted in a txpower of -24 and an adjustment of -3. Together
# with the adjustment due to TX_POWER_ULTRA_LOW, the old
# attenuation calculation was:
# attenuation = -24 - (rssi + 3)
attenuation = txpower - (rssi + adjust + rxadjust)
gtd = temp[i][4]
if gtd != None:
results.append((attenuation, gtd))
conn.close()
return results
def get_attenuations_en(filename, gtd='avg', att='avg'):
'''
This function parses a v1.6 EN JSON file and returns a set of observations,
compatible with the get_attenuations function so that it can be used for
plotting and statistics
gtd: either 'avg' or 'min' ground truth distance measured over the interval
att: either 'avg' or 'min' attenuation measured over the interval
Returns an array of [(attenuation, ground truth distance)] tuples
'''
results = []
exposure_windows = json.load(open(filename, 'rb'))
for _, exposure_window in exposure_windows.items():
for _, scan_window in exposure_window.items():
for _, rx in scan_window.items():
for _, tx in rx.items():
if tx[gtd+'_gtd'] != None:
results.append((tx[att+'_att'], tx[gtd+'_gtd']))
return results