t i n k l a m a t i s


Kaip veikia mobiliojo ryšio tinklai? Kas yra ir kuo skiriasi GSM, HSPA ir LTE ryšio technologijos? Kaip galima patikrinti ryšio kokybę ir susipažinti su techniniais mobiliųjų tinklų parametrais?


Šis nedidelis praktinis darbas padės atsakyti į šiuos klausimus ir paskatins giliau pasidomėti šiuolaikinių ryšio tinklų subtilybėmis. Čia pateikiami algoritmai, leidžiantys nuskaityti mobiliųjų programėlių surinktus duomenis apie ryšio tinklo kokybės parametrus ir juos analizuoti. Šie algoritmai gali atsakyti į klausimus, kokio stiprumo mobiliojo ryšio siganalas yra mano buvimo vietoje, kaip jis keičiasi judant, iš kokių bazinių stotelių atsklinda radijo signalai ir kaip juos veikia gretimų stočių trukdžiai. Tokiu būdu galima matyti signalo parametrų kitimą laikui bėgant ir pavaizduoti juos žemėlapyje.


Telekomunikacijų mokslo centras Vilniaus universiteto Fizikos fakultetas
Saulėtekio al. 9, III-ieji rūmai, 10222 Vilnius
El. paštas: rimvydas.aleksiejunas@ff.vu.lt

Reikės


  1. Android telefono arba planšetės
  2. Mobiliosios programėlės G-MoN arba Network Cell Info Lite
  3. Interaktyvios programavimo aplinkos Jupyter Notebook
  4. Šiek tiek Python žinių

Toliau seka paaiškinimai, kaip šiuos žingsnius įgyvendinti.

Mobiliosios programėlės


Mobiliosios programėlės bus reikalingos radijo ryšio tinklo duomenų rinkimui. Jų yra sukurta nemažai, tačiau čia naudosime dvi iš jų, pritaikytas Android operacinei sistemai: G-MoN ir Network Cell Info Lite. Jas galite susirasti ir įsidiegti per Google Play platformą.

Panašias programėles galite susirasti ir kitoms operacinėms sistemoms. Jos skirsis surinktų duomenų pateikimo formatais, todėl žemiau pateikiamus pavyzdžius teks adaptuoti kitokio formato įvesties duomenims.

Įsidiegę G-MoN arba Network Cell Info Lite turėsite programėles, kurių pagalba galėsite registruoti radijo ryšio signalo parametrus. Kaip naudoti programėlėmis, paskaitykite jų instrukcijose.

G-MoN


Network Cell Info


Matavimai


Belieka atlikti pačius matavimus. Atsidarę G-MoN ar Network Cell Info Lite programėlę palikite ją veikimo režimu (turėkite omenyje, kad jos naudos baterijos resursus). Programėlė matuos priimamo ryšio signalo parametrus ir kaups juos atminties kortelėje, kol tos programos nesustabdysite. Tokiu būdu galėsite turėti informaciją apie signalo pokyčius tose vietose, kur eisite ar važiuosite.

Android kortelės srityje, skirtoje naudotojo duomenims, šios programėlės sukuria direktorijas gmon ir Network Cell Info Lite, kurioje ir talpina duomenų bylas su matavimais. G-MoN sukuria *.kml ir *.txt tipo bylas, o Network Cell Info Lite programėlė -- *.csv tekstines bylas. Visas šias bylas galima persikelti į kompiuterį, kad jas būtų galima panaudoti duomenų analizei debesų kompiuterijos platformoje.

Jupyter Notebook programavimo aplinka


Algoritmams vykdyti jums reikės Python programavimo aplinkos Jupyter Notebook su pagrindinėmis šios kalbos bibliotekomis. Susidiegę šią aplinką jūs galėsite įsikelti tinklamatis.ipynb dokumentą su algoritmais ir juos paleisti vykdymui.

Python programavimo kalba


Verta susipažinti ir kas tai yra Python. Tai viena iš populiaresnių programavimo kalbų, skirta mokslinių rezultatų skaitmeniniam apdorojimui. Egzistuoja nemažai elektroninės literatūros, kursų, vaizdo pamokėlių ir pavyzdžių Python programavimo kalba, pvz. Python tutorial anglų kalba arba Python pradžiamokslis lietuviškai. Toliau pateikiami jau galutiniai algoritmai, todėl juos galima paleidinėti su testiniais duomenimis arba pritaikyti savo išmatuotiems duomenims ir tuo pačiu susipažinti ir su Python programavimo kalba.

Matavimų rezultatų analizė


O dabar būdami jau veikiančioje Python aplinkoje, paleiskite žemiau esančius algoritmų blokus paspausdami Ctrl+Enter.


In [1]:
from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import folium
from folium import Map
import branca.colormap as cm
import seaborn as sns
import csv
%matplotlib inline

G-MoN matavimo duomenys


Pasinaudodami Python bibliotekomis nuskaitykime surinktus G-MoN matavimų rezultatus ir pasižiūrėkime, kas yra jų viduje.


In [2]:
gmon_file = '/home/data/measurements/gmon/gmon_gsm_rxl_2017_09_15_13_35_06.txt'

lines=list(csv.reader(open(gmon_file)))    
print(lines[0])  
df_gmon = pd.read_csv(gmon_file, sep=';', names=lines[0][0].split(';')).iloc[1:]
df_gmon.head()


['LCID;CID;LAC;NET;PSC;RNC;RXL;QUAL;RSRP;RSRQ;ECIO;TYPE;LAT;LON;SPEED;ALT;SNR;DATE;TIME;N1CID;N1LAC;N1RXL;N2CID;N2LAC;N2RXL;N3CID;N3LAC;N3RXL;N4CID;N4LAC;N4RXL;N5CID;N5LAC;N5RXL;N6CID;N6LAC;N6RXL']
Out[2]:
LCID CID LAC NET PSC RNC RXL QUAL RSRP RSRQ ... N3RXL N4CID N4LAC N4RXL N5CID N5LAC N5RXL N6CID N6LAC N6RXL
1 46215947 180531 8003 24601 -1 11 -55 17.8 -82 -7 ... -103 182 -1 -105 167 -1 -102 2147483647 -1 -78
2 46215947 180531 8003 24601 -1 11 -55 17.8 -82 -7 ... -103 182 -1 -105 167 -1 -102 2147483647 -1 -78
3 46215947 180531 8003 24601 -1 11 -55 17.8 -82 -7 ... -103 182 -1 -105 167 -1 -102 2147483647 -1 -78
4 46215947 180531 8003 24601 -1 11 -55 17.8 -84 -10 ... -98 182 -1 -104 42 -1 -104 43 -1 -104
5 46215947 180531 8003 24601 -1 11 -55 17.8 -84 -10 ... -98 182 -1 -104 42 -1 -104 43 -1 -104

5 rows × 37 columns

Matavimų statistika


Pasikeitę tekstinius duomenis į float tipo skaičius, galime matyti ir matavimų statistiką.


In [3]:
df_gmon['LAT'] = df_gmon['LAT'].astype(float)
df_gmon['LON'] = df_gmon['LON'].astype(float)
df_gmon['RSRP'] = df_gmon['RSRP'].astype(float)
df_gmon['RXL'] = df_gmon['RXL'].astype(float)
df_gmon['QUAL'] = df_gmon['QUAL'].astype(float)

df_gmon[['LAT', 'LON', 'RSRP', 'RXL', 'QUAL']].describe()


Out[3]:
LAT LON RSRP RXL QUAL
count 623.000000 623.000000 623.000000 623.000000 623.000000
mean 54.722946 25.330433 -78.423756 -54.537721 18.842697
std 0.000443 0.001886 10.384267 5.448806 7.059256
min 54.722410 25.326990 -112.000000 -83.000000 -4.000000
25% 54.722585 25.328795 -85.000000 -55.000000 14.400000
50% 54.722770 25.331010 -81.000000 -53.000000 18.600000
75% 54.723255 25.331755 -71.000000 -51.000000 24.800000
max 54.724000 25.333030 -55.000000 -51.000000 30.000000

Duomenų atvaizdavimas žemėlapyje


O dabar pasižiūrėkime, kaip atrodo duomenys žemėlapyje.


In [4]:
def val2rgb(value, minval=0, maxval=100):
    """ 
    Funkcija matavimo taškų nuspalvinimui
    """
    green_max, red_max = 180, 255
    red, green, blue = 0, 0, 64
    value -= minval
    maxval -= minval

    if value < maxval/2:
        green = green_max;
        red = int(np.round((np.float(value)/(maxval/2))*red_max))
    else:
        red = red_max
        green = int(np.round((1-((np.float(value)-(maxval/2))/(maxval/2)))*green_max))

    return '#{:02x}{:02x}{:02x}'.format(red, green, blue)

In [5]:
minval, maxval = df_gmon['RSRP'].min(), df_gmon['RSRP'].max() 
map_1 = folium.Map(location=[df_gmon['LAT'].mean(), df_gmon['LON'].mean()], zoom_start=17, width='90%', height=u'80%')
for ii in range(1, len(df_gmon)+1):
    val = val2rgb(df_gmon['RSRP'][ii], minval, maxval)
    folium.CircleMarker(location=[df_gmon['LAT'][ii], df_gmon['LON'][ii]], radius=1, color=val, 
                        fill_color=val).add_to(map_1)
values = np.linspace(minval, maxval, 10) 
colors = map(lambda x: val2rgb(x, minval, maxval), values)
colormap = cm.StepColormap(colors, vmin=minval, vmax=maxval, index=values, caption='RSRP (dBm)')
map_1.add_child(colormap)    
map_1


Out[5]:

Network Cell Info matavimų rezultatai



In [6]:
df_nwcell = pd.read_csv('/home/data/measurements/nwcell/CMWFpro_20170915_141406_meas_ainf_d0_n772.csv')
print('Data size: ', df_nwcell.shape)
df_nwcell.columns


Data size:  (229, 35)
Out[6]:
Index([u'sim', u'radiotype', u'radio', u'carrier', u'mcc', u'mnc', u'area',
       u'cellid', u'enbrnc', u'lcid', u'xarfcn', u'unit', u'band', u'fc',
       u'sigl', u'asu', u'signal', u'lat', u'lon', u'acc', u'time', u'speed',
       u'bearing', u'alt', u'api', u'device', u'rsrq', u'rssnr', u'ss', u'cqi',
       u'ta', u'rssi_cdma', u'rssi_evdo', u'ecio_cdma', u'ecio_evdo'],
      dtype='object')

In [8]:
df_nwcell = df_nwcell[['radio', 'cellid', 'enbrnc', 'xarfcn', 'unit', 'fc', 'sigl', 'asu', 'signal', 
                       u'lat', u'lon', u'acc', u'time', u'speed', u'bearing', u'alt', u'api', u'rsrq', 
                       u'rssnr', u'ss', u'cqi', u'ta']]
df_nwcell.head()


Out[8]:
radio cellid enbrnc xarfcn unit fc sigl asu signal lat ... time speed bearing alt api rsrq rssnr ss cqi ta
0 LTE+ 46215947 180531 1542 165 1839.2 4 67 -73 54.723649 ... 1505472621000 2.7 22.0 173.0 25 -6 19.4 31 -1 3
1 LTE+ 46215947 180531 1542 165 1839.2 4 68 -72 54.723959 ... 1505472626000 7.3 2.0 164.0 25 -5 23.2 31 -1 3
2 LTE+ 46215947 180531 1542 165 1839.2 4 63 -77 54.724329 ... 1505472631000 9.1 7.0 161.0 25 -6 15.4 30 -1 3
3 LTE+ 46215947 180531 1542 165 1839.2 4 56 -84 54.724851 ... 1505472637000 9.8 1.0 155.0 25 -9 10.2 30 -1 -1
4 LTE+ 46215947 180531 1542 165 1839.2 4 51 -89 54.725270 ... 1505472642000 10.5 33.0 154.0 25 -16 11.2 31 -1 3

5 rows × 22 columns

Kaip matavimai atrodo žemėlapyje



In [9]:
minval, maxval = df_nwcell['signal'].min(), df_nwcell['signal'].max()
map_2 = folium.Map(location=[df_nwcell['lat'].mean(), df_nwcell['lon'].mean()], zoom_start=13, width='90%', height='80%')
for ii in range(len(df_nwcell)):
    val = val2rgb(df_nwcell['signal'][ii], minval, maxval)
    folium.CircleMarker(location=[df_nwcell['lat'][ii], df_nwcell['lon'][ii]], radius=1, color=val, 
                        fill_color=val).add_to(map_2)
values = np.linspace(minval, maxval, 10) 
colors = map(lambda x: val2rgb(x, minval, maxval), values)
colormap = cm.StepColormap(colors, vmin=minval, vmax=maxval, index=values, caption='signal (dBm)')
map_2.add_child(colormap)        
map_2


Out[9]:

Kaip matavimai atrodo laiko skalėje



In [10]:
df_nwcell.plot(x=pd.to_datetime(df_nwcell['time']*10**6).map(lambda t: t.strftime('%H:%M:%S')), 
               y=['asu', 'ss', 'rssnr', 'signal', 'rsrq'], style=['k-', 'r-', 'g-', 'b-', 'm-'], ylim=(-120, 80), 
               figsize=(12, 6)).legend(loc='center left', bbox_to_anchor=(1, 0.5));


Statistika


Kokia yra Network Cell Info išmatuotų signalų statistika?


In [11]:
df_nwcell[['asu', 'ss', 'rssnr', 'signal', 'rsrq']].describe()


Out[11]:
asu ss rssnr signal rsrq
count 229.000000 229.000000 229.000000 229.000000 229.000000
mean 47.174672 24.344978 12.940611 -92.825328 -7.484716
std 11.135728 4.905129 6.058542 11.135728 1.952502
min 28.000000 16.000000 -1.600000 -112.000000 -16.000000
25% 38.000000 20.000000 8.600000 -102.000000 -9.000000
50% 45.000000 23.000000 13.000000 -95.000000 -7.000000
75% 57.000000 29.000000 17.000000 -83.000000 -6.000000
max 75.000000 31.000000 29.600000 -65.000000 -4.000000

Koreliacija


Ar yra kokia nors priklausomybė tarp atskirų išmatuotų parametrų?


In [12]:
# Koreliacijos koeficientas:
print('signal ~ rssnr: {:.1f} %'.format(df_nwcell['signal'].corr(df_nwcell['rssnr']) * 100))
print('signal ~ ss:    {:.1f} %'.format(df_nwcell['signal'].corr(df_nwcell['ss']) * 100))


signal ~ rssnr: 52.3 %
signal ~ ss:    96.2 %

Kaip koreliacija atrodo grafiškai?


In [13]:
df1 = df_nwcell[['signal', 'rssnr']]
df1.insert(2, 'ydata', 'rssnr')
df1.columns = ['signal', 'yval', 'ydata']

df2 = df_nwcell[['signal', 'ss']]
df2.insert(2, 'ydata', 'ss')
df2.columns = ['signal', 'yval', 'ydata']

corr_res = pd.concat([df1[['signal', 'yval', 'ydata']], df2[['signal', 'yval', 'ydata']]])

In [14]:
sns.lmplot(x='signal', y='yval', data=corr_res, col='ydata', sharey=False);



In [15]:
sns.jointplot(x = 'signal', y = 'rssnr', data = df_nwcell, kind='kde');


Kiti matavimų parametrai


Yra ir daugiau išmatuotų parametrų. Kokios jų tarpusavio koreliacijos?


In [17]:
df_nwstats = df_nwcell[['asu', 'ss', 'rssnr', 'signal', 'rsrq']]
corr = df_nwstats.corr().mul(100).astype(int)
sns.clustermap(data=corr, annot=True, fmt='d', cmap='Blues', row_cluster=False, col_cluster=False, figsize=(5, 5));


Parametrų tarpusavio koreliacijos



In [19]:
pd.plotting.scatter_matrix(df_nwstats, diagonal='kde', figsize=(10, 6))
plt.tight_layout()


Daugiau informacijos


Radijo ryšio signalo matavimo duomenys ir programėlės

Apie ryšių technologijas