Lab10 - Introduction to GPS

Authors:

v1.0 (2014 Fall) Rishi Sharma **, Sahaana Suri **, Paul Rigge **, Kangwook Lee **, Kannan Ramchandran **
v1.1 (2015 Fall) Kabir Chandrasekher *, Max Kanwal *, Kangwook Lee **, Kannan Ramchandran **

In this lab, you will learn how GPS signals are used to estimate the location of an object. GPS satellites broadcast several different signals. These signals contain a very accurate measurement of the satellite's time, as well as the satellite's position, velocity, etc.

GPS receivers make use of the fact that light propagates at a known speed, so the receiver can compute distances from the satellites by measuring how long it takes the GPS signal to propagate from the satellite to the receiver. This requires very accurate time measurements — light in free space travels 300m in a microsecond, so small timing errors result in huge distance errors.

The first section of the lab will be to determine how a GPS chip actually goes about receiving and decoding signals. We will step through a subset of problems that must be combatted to successfully send signals from a satellite to your GPS chip. The second portion of the lab will then explore how a GPS chip can use the data it receives to determine its location, assuming the raw, received signals were acquired and decoded. We end with a little open-ended challenge for you. Hope you have fun!

$\mathcal{SCIENCE\ on\ the\ SIDE}$

Keeping time to an extreme level of accuracy is the crux of the utility of GPS, but even infinite accuracy isn't enough. If engineers don't take into account both Einstein's theories of special and general Relativity, the whole system goes up in flames.

Consider the following simple calculations:

Let's say we want our GPS location to be accurate to within $15m$ on Earth. Since distances are measured from the satellite via the change in time of the satellite's clock and the GPS device's clock, multiplied by the speed of light, this implies that we need our device to keep time accurately at the level of $\frac{15m}{c} = \frac{15m}{3 \times 10^{8} \frac{m}{s}} \approx 50ns$.

Since the satellites with which the GPS device communicates with are orbitting the Earth (twice per day) at speeds of $14,000\ km/hr$, according to special relativity, the clocks on the satellites actually run slower relative to those on the Earth's surface according to $T_{sat} = \frac{T_{Earth}}{\sqrt{1 - \frac{v^c}{c^2}}}$. Plugging in the appropriatae values, we see that the satellites' clocks tick more slowly by about $7 \mu s$ per day.

However, according to general relativity, objects under the influence of relatively weaker gravitational fields experience time faster than those under stronger gravitational fields, according to $T_{sat} = \frac{T_{Earth}}{\sqrt{1 - \frac{2GM}{Rc^2}}}$. Given that these satellites are $20,000km$ above the Earth and that they experience approximately one-fourth the gravity as we do on Earth, the resulting rate at which time passes faster for the satellites is $45 \mu s$ per day.

Thus, we have that the net change in the amount of time satellites experience relative to us on Earth is $45 \mu s - 7 \mu s = \boxed{+38 \mu s / day}$.

Given that a $50ns$ error in keeping time corresponded to a distance error of $15m$, a $38\mu s$ error in keeping time corresponds to an error in location of more than $11km$. Even crazier is that this is the amount of error in location that builds up per day! Without taking relativity into consideration, GPS devices would be rendered useless within 2 minutes of being synchronized with the satellites' atomic clocks.

Thanks a lot, Einstein!
<img src="http://images.mentalfloss.com/sites/default/files/styles/insert_main_wide_image/public/einstein1_7.jpg", width=150px></img>

For more info on the awesomeness of Einstein's Theory of Relativity, see Wikipedia.

Fore some mind-boggling results due to relativity, see these paradoxes.

For more info about relativity in GPS, see this doc.

Warning: Time dilation may occur in your head while your brain works at relativistic speeds to contemplate these ideas!

Part I: Data Acquisition

How does a GPS chip decode received signals?

When you a turn a GPS on, it immediately begins to listen for satellite signals. The satellites are continuously transmitting data, and the GPS chip is expected to receive this signal and make sense of it.

The first signal a GPS receiver attempts to find is the Coarse/Acquisition signal. This contains a 1500 bit chunk of data called the "almanac." It contains information and status concerning all the satellites (locations and status) agreed upon by all satellites and is valid for approximately 180 days. This signal is sent at a very low data rate and is intended only to give the receiver a rough idea of the time/location before moving on to the higher data rate, more precise signals. In this lab, we will only focus on the almanac being modulated over the C/A signal.

A simplified version of the C/A signal is depicted and described below.

Data bits (data signals) from each satellite is transmitted at 50 bits / second. This slow data signal is xor'd with a much faster pseudorandom bit sequence (pseudorandom noise, PRN) that repeats every millisecond (1023 samples). Each satellite transmits with a unique PRN that will not correlate with any other satellite's code (the codes orthogonal to one another, and will "cancel each other out" when xor'd together). This is a form of "Code Division Multiple Access," (CDMA) where multiple transmitters can send messages over a single channel without risk of collision. As long as each PRN is orthogonal to the rest, each data signal can be independently recovered.

See http://en.wikipedia.org/wiki/GPS_signals, http://en.wikipedia.org/wiki/Code_division_multiple_access#Steps_in_CDMA_modulation, and come talk to us if you're interested in learning more about this!

The following code allows you to simulate an idealized GPS receiver with some plausible parameters.

The pseudorandom code is generated by a linear feedback shift register (see http://en.wikipedia.org/wiki/Linear_feedback_shift_register).

The function transmit_to_earth(signal) simulates what the signal might look like by the time it reaches your receiver. Skim through the code, but don't worry if you don't understand all of it.

In [1]:
import numpy as np
import scipy.signal

# linear feedback shift register, default for taps is that used by GPS C/A Signal
def lfsr(n, starting_state=(1 << 10) - 1, taps=[3,10]):
    state = starting_state
    for i in range(n):
        yield state
        state = ((state << 1) & ((1 << max(taps))-1)) + \
            reduce(lambda x,y: x^y, map(lambda x: state & (1<<(x-1)) != 0, taps), False)

# coarse/acquisition code generation. reset is all 1's state. This is data that 
# is modulated by a pseudorandom bit sequence. 
def ca(starting_state=(1 << 10) -1):
    return np.fromiter( ( 2*(i >> 9)-1 for i in lfsr(1023, starting_state=starting_state)), dtype=np.float)
ca_canonical=ca()

offset = int(np.random.uniform(0, ca_canonical.size))

# adapted from http://common.globalstar.com/doc/axonn/GPS-L1-Link-Budget.pdf
def transmit_to_earth(signal, temp=290, offset=offset, bw=2e6, SNR_boost=0, NF=0):
    signal = np.roll(signal, -offset) # add a random phase
    elevation = 2.5e7 #m, approximately over the horizon
    antenna_gain = 13. #dBi
    power = 46.5 #dBm
    c_lambda = .1904 #m
    temp = 290 #K
    thermal_noise = 10*np.log10(1.38e-23 * temp) + 30 #kT in dBm
    # Carrier to Noise ratio in dB
    CbyN0 = power + antenna_gain - 20 * np.log10(4*np.pi * elevation / c_lambda) - thermal_noise
    SNR = CbyN0 - 10*log10(bw) + SNR_boost - NF
    #print SNR
    return signal + 10**(-SNR/20.) * np.random.normal(size=signal.size)

Problem 1: Signal Strength

GPS satellites have limited power and need to spread their signals over the entire surface of the earth, so the signals are very weak by the time they get to the GPS receiver. As a result, thermal noise and noise from other sources will be large compared to the signal. The code below plots the received signal in the time domain. There is a slider on the bottom that you can move around to boost the signal to noise ratio (SNR) in dB. The SNR measures exactly what you would expect it to: what is the ratio of actual signal to noise in the received message. As an analogy, think of yourself talking to a friend in a loud, crowded room. In order for your friend to hear you, you most likely have to speak very loudly to be heard over the background noise. Imagine what you would have to do to be heard from across the room! In a similar fashion, as you increase your SNR, you are more likely to get your signal across successfully. However, just as you need to exert more energy to speak louder, this also requires more power on the satellite's end.

NOTE: The slider in the following code will not work inline!

In [3]:
%pylab
# from nbviewer.ipython.org
from matplotlib.widgets import Slider

fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2, left=0.1)

x = np.linspace(0, 1023, len(ca_canonical))
line, = plt.plot(x, [0.]*len(x))
ax.set_xlim([0, 1023])
ax.set_ylim([-5,5])
def on_change(val):
    line.set_ydata(transmit_to_earth(ca_canonical, SNR_boost=val))
on_change(0)

slider_ax = plt.axes([0.1, 0.1, 0.8, 0.02])
slider = Slider(slider_ax, "Noise Figure", 0, 50, valinit=0, color="#AAAAAA")
slider.on_changed(on_change)
print "Look for offset = " + str(offset)
Using matplotlib backend: MacOSX
Populating the interactive namespace from numpy and matplotlib
Look for offset = 373

Q1: By approximately how much do you need to boost the SNR for the received signal to look "clean"? What was the original SNR of the signal?

This is subjective, but there should be some SNR where it stops looking like garbage and starts looking like the signal. Is it reasonable to ask a satellite to use this much more power?

A1. Your answer here

Problems 2 and 3: Signal Starting Point and Decoding

The next problem is that when the GPS first starts up and hears a signal, it doesn't know when the data starts. Note that transmit_to_earth() "rolls" the input by a randomly generated offset in order to simulate the fact that a GPS receiver doesn't know where the bits start and end.

Once a receiver knows this time offset, it knows the time to $<1$ms (unfortunately, light goes really far in a millisecond). The next step is for the receiver to take each group of 1023 samples and figure out if they correspond to a 1 bit or a 0 bit. A GPS receiver needs to do all of these tasks despite the signal being weaker than the noise!

The basic tool for achieving these tasks is the matched filter (http://en.wikipedia.org/wiki/Matched_filter). Matched filters perform a correlation on an input signal with an expected reference signal. A matched filter performs a convolution with the time-reversed, conjugated signal, which essentially amounts to a sliding dot product (remember, convolution time-reverses and conjugates the signal, generally, so if you time-reverse and conjugate in the first place, then the operation becomes a simple sliding dot product). The idea is that this slidiing dot product will in general be small, until the two signals precisely align, where you will see a spike. If the two signals are aligned, $\sum_{i=0}^N r_i * (b * r_i) = Nb$ (recall $r_i$ is $\pm 1$). If the two signals are not aligned, because we have chosen our sequence to look random, we say $r_i$ is approximately independent from $r_k$ if $k\ne i$, so $\sum_{i=0}^N r_i (b * r_{i+k})$ has expectation approximately 0.

Q2. In the space below, implement a function that performs matched filtering, i.e. performs a correlation on signal and reference. It should be able to handle signal and reference being different sizes.

In [4]:
def matched_filter(signal, reference=ca_canonical):
    #Your code here
    pass

If you have correctly implemented matched_filter, the below code should plot the result of matched filtering your noisy signal. The slider on the bottom boosts (or reduces) the SNR. If you boost the SNR, you should see a peak at offset (your particular random offset is printed by the above code). Cool stuff!

In [ ]:
%pylab
# from nbviewer.ipython.org
from matplotlib.widgets import Slider

fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2, left=0.1)
x = np.linspace(0, 1023, len(ca_canonical))
line, = plt.plot(x, [0.]*len(x))
ax.set_xlim([0, 1023]), ax.set_ylim([0,80])
def on_change(val):
    line.set_ydata(10*np.log10(matched_filter(transmit_to_earth(ca_canonical, SNR_boost=val))**2))
on_change(0)

slider_ax = plt.axes([0.1, 0.1, 0.8, 0.02])
slider = Slider(slider_ax, "SNR Boost", -10, 10, valinit=0, color="#AAAAAA")
slider.on_changed(on_change)
print "Look for offset = " + str(offset)

Q3 When the matched filter is aligned with the input, the output is $X=Nb + \sum_{i=0}^N v_i$, where $v_i\sim N(0,\sigma^2)$ is some additional noise. For our value of $N=1023$, what is the variance of our estimator $\hat{b}=\frac{1}{N}X$? What is the SNR of $\hat{b}$? How much bigger is it than our original SNR? (Recall $b\in \{ -1, 1\}$). Based on Q1, is this enough to make our signal look clean?

Q4 Your answer here

For the higher datarate GPS signals that give more precise timing information, $N$ is smaller and the noise averaging takes longer. To average out enough noise to get a good lock, GPS receivers need to correlate for a long time. This is the primary reason it can take a long time for your GPS to figure out where you are.

Problem 4: Noise Figure

So far, we have assumed that our receiver detects the signal perfectly. In reality, no receiver is perfect and designers must work around many nonidealities. One common problem is noise figure. Before converting a signal from analog to digital, receivers pass the signal through an amplifier to get the weak signal to a high enough level for sampling. Unfortunately, active components like amplifiers add their own noise to the system. The parameter that measures this noise is called noise figure—it measures how much extra noise an active component adds to a signal.

For the purposes of this lab, we can treat $SNR_{out}=SNR_{in} - NF$, where $SNR_{in}$ is the SNR of the signal before going through the amplifier, $NF$ is the noise figure of the amplifier, and $SNR_{out}$ is the SNR of the signal at the output of the amplifier. All values are in dB.

Q4 Write code that generates 100 different random offsets. Use the noise_figure and offset parameter of transmit_to_earth to generate 100 different simulated signals with noise figures of 1dB and 8dB. Use your matched filter code to find the offsets for the two different noise figures. Which noise figure performs better? By how much?

Great! Now you know how GPS signals are transmitted and received :D

Part II: Finding your location

How does a GPS chip determine where it is located

Let's switch gears a bit and explore what a GPS chip does in order to use the obtained data effectively. We'll build up a simple model, and then let you pretend to be the GPS chip.

Image and video hosting by TinyPic

We first assume that we have obtained the $N$ GPS signals (from the first part), each of which gives a noisy measurement of the distance between the GPS satellite and the object.

The noisy measurements are modeled as follows, where $n_i$ is iid Gaussian noise with zero mean and variance $\sigma^2$. $$D_i = d_i + n_i $$

In the above equation, $d_i$ is the actual distance to the $i$-th satellite, and $D_i$ is the reported distance, which is corrupted by additive noise $n_i$. This additive white gaussian noise (AWGN) channel model is actually very common in information theory, and can be analyzed just like how we analyzed the BEC and BSC earlier in the course! It is a pretty good model for satellite communication links as you don't have to deal with shadowing, multipath, excessive interference, etc. (come talk to one of us if you're interested in learning more about this stuff/what it means!)

For simplicity, let's visualize the entire space as a 2D plane. Assume that all GPS satellites and the object to be located (GPS chip) are on the plane. Denote the position of the unknown object as $(x, y)$, and let $(x_i, y_i)$ be the position of the $i$th GPS satellite.

Q5. Consider the case where $\sigma=0$, i.e., noiseless distance measures are given. In the 2D case, what is the minimum $N$ necessary to estimate the unknown position exactly?

(hint: This isn't supposed to be too theorectical. Think geometry!)

A5 Your answer here

Q6. What about in the 3D case?

A6 Your answer here

Q7. Going back to the 2D case, find the MLE of $(x, y)$ given $\{(x_i,y_i)\}$ and $\{D_i\}$.

Hint 1: Leave your answer in the form of an expression to be maximized (as in, something proportional to the likelihood function)

Hint 2: Use the distance formula. What is the relationship betweek $d_i$ and $(x_i,y_i)$?

A7 Your answer here

Part III: Help Us

I guess everyone received the following email sent on Nov 11th.:

======================================================================================================================

Subject: [cory-info] CORY HALL BURGLARY YESTERDAY NIGHT BETWEEN 11:03 P.M.- 11:44 P.M.

Date: Wed, Nov 11, 2015 at 10:19 AM

Dear Building Occupants:

Yesterday night between 11:03 p.m. and 11:44 p.m. the BLISS Lab was burglarized. The elapsed time for entry, theft and exit from the building was approximately 6 minutes. To prevent thefts from occurring inside or nearby Cory Hall and Soda Hall please remember to:

  • Be AWARE of your surroundings; Be aware;
  • Lock up all personal belongings when you leave the building
  • Never prop doors open allowing individuals without card key access to enter a secure space

Don’t allow strangers to “tail gate” behind you through card reader controlled doors. Immediately report any suspicious activity to UCPD at (510) 642-6760 and myself at (415) 713-3403.

BE SAFE, REMAIN VIGILIGENT and AWARE.

======================================================================================================================

Indeed, the hidden secret of EE126 is stolen from Kangwook’s desk in the BLISS lab. The note has been secretly shared among teaching staffs at Berkeley for more than 50 years, and has been secret sauce of EE126.

Note: Treat all (x,y) coordinates in the following paragraphs as (latitude, longitude).

Fortunately, the UCPD promptly reacted and caught the suspect, but the suspect didn’t possess the note; he claims that he lost it while escaping. We believe that he must have dropped the note at $(x_0, y_0)$, where he started running at a constant velocity $(v_x, v_y)$ for $99$ minutes until he reached $(x_{99}, y_{99}) = (x_0,y_0) + 99(v_x, v_y)$. We found that the GPS sensor in his iPhone has collected distance measurements from $5$ GPS towers in the SF bay area for $99$ minutes. The GPS towers are located as described in the following figure.

The UCPD asked us to locate the treasure (or $(x_0,y_0)$). We need your help! The location of the GPS towers and measurement data are provided below. If you think that you found the location of the secret, please check out the location. Whoever finds the ‘secret notes’ and return the notes without opening it will be awarded 1% bonus to his/her final grade. You may want the secret notes more than the bonus. If so, go ahead, but you will be no longer eligible for the bonus.

Thanks,

EE126 teaching staffs

Q8. Using the sensor positions and measured distances please locate the treasure.

In [1]:
# (x,y) coordinates of the 5 GPS towers
sensor_position = [(37.7,-122.3), (37.9,-122.15), (37.83,-122.15), (37.91, -122.4), (37.9, -122.21)]
# measured_dist[i][j]: measured distance from tower j at time i 
measured_dist = [[0.18092487513008076, 0.11072056254850829, 0.11548324353044823, 0.14740965363718331, 0.052440578676188655], [0.18085642784765654, 0.11172109090710736, 0.11870381837108762, 0.14423145396798284, 0.054676143632989539], [0.18183337653975337, 0.11460538199354256, 0.12195392247876467, 0.14102071110426151, 0.057334034893181923], [0.18182569735244739, 0.1180107254058962, 0.12523862367774111, 0.13775306985724164, 0.059724085620234527], [0.18188534437901518, 0.12017640526270429, 0.12853870125885605, 0.13507274105648534, 0.062271800500420742], [0.1822929528102365, 0.12333711931020667, 0.1323660201939299, 0.13201233809791779, 0.0650869526462102], [0.1819326677752735, 0.1263088748427221, 0.13480364545066748, 0.12855879314100396, 0.068460227799641532], [0.18427585232931426, 0.12944409014989336, 0.13803735999263791, 0.12613712676930203, 0.069771134874712926], [0.18413017648054561, 0.13138767718877645, 0.14101737361725922, 0.1213268877660183, 0.07197966380796772], [0.18527971591871026, 0.13472119035092014, 0.14437744826052257, 0.11907032078730187, 0.075360221133277006], [0.18572564014894899, 0.13765005883492373, 0.14775739267448362, 0.11571814019067604, 0.077902283957751853], [0.18704865045548105, 0.14043709557137474, 0.1509796012752192, 0.11223881592788226, 0.080862125442720506], [0.18769761127120421, 0.14339314422971336, 0.15419003710234946, 0.10969194967186589, 0.084507074770295842], [0.18941526859437416, 0.14736901559267471, 0.15528991948432572, 0.10616470191361667, 0.086102630423212562], [0.18901378498779936, 0.14869455729228009, 0.16019543718474361, 0.10397316169500903, 0.089232154302476843], [0.19057871995380204, 0.15178597992316514, 0.16369878543892372, 0.099955697068183136, 0.091978341759641771], [0.1916219313593992, 0.15505207047883579, 0.16658561899768803, 0.097565944145254907, 0.095298689876633508], [0.19251045300888375, 0.15781278318526157, 0.1700658609725271, 0.093879640374472148, 0.098060917077795101], [0.19372976785566304, 0.16033389519540239, 0.17289567959847801, 0.091063743720272552, 0.10024420684822032], [0.19396269359816179, 0.16450325636221749, 0.1781826387655821, 0.087546008162278199, 0.10397061618868761], [0.19561196700913874, 0.16759297601729722, 0.17965115821240343, 0.084572433135827241, 0.10751536885641846], [0.1969882651422285, 0.16949541904056212, 0.18196102790346005, 0.081403949795341102, 0.1095407609536953], [0.19896209807962262, 0.17266053967650105, 0.18554910422438617, 0.078162028724375401, 0.11281853663606281], [0.20047236152097164, 0.17608912923972564, 0.18882263835507154, 0.074638870785167427, 0.11559964156688472], [0.20169265851832377, 0.17899525975385666, 0.19118298587506738, 0.07102693145409518, 0.11835846045065544], [0.20186371425396912, 0.18326969571511331, 0.19426893389687078, 0.071125342075690184, 0.12143839495577738], [0.20472695776210234, 0.18376255545229198, 0.19840954415239501, 0.066176678118726823, 0.12403180659384892], [0.20593450858725831, 0.18693547313189016, 0.20038033326143526, 0.063595775546547578, 0.1277418240914566], [0.20779265840660419, 0.19056300128505493, 0.20471714521620493, 0.05944819906677027, 0.13079093778976053], [0.20936740913351592, 0.1940848659382908, 0.20770410684885429, 0.056652702807357479, 0.13418798200231533], [0.21117541264211895, 0.19765616307847791, 0.2097088078454778, 0.053745645136496711, 0.13614495231793353], [0.21222029673487641, 0.20085670851203202, 0.21372686146510844, 0.050169294168023432, 0.1403841187427789], [0.2142582563343661, 0.20254922663132668, 0.21588874389818541, 0.045974311503579238, 0.1428795867870149], [0.21561796806926858, 0.20653043204073498, 0.21947612865133603, 0.043902115534836868, 0.14549927487149558], [0.21722868020912983, 0.20907150646548608, 0.22330061654645028, 0.041497541191181445, 0.14915917838745885], [0.21902973073401996, 0.2120170323199225, 0.22658145185157338, 0.038448751687014296, 0.15202973456083529], [0.22107197020267877, 0.21516341066940717, 0.22964406842908847, 0.035458749972292002, 0.15479899205866018], [0.22297655347504181, 0.21887802519737506, 0.2324608786293749, 0.033418447986894091, 0.1584570276739074], [0.22664718144272694, 0.22078512129310168, 0.23560568815276312, 0.029578251383426599, 0.15990485459889781], [0.22697372332077109, 0.22489583515861583, 0.23925202529857045, 0.027028329488261699, 0.16406028947963694], [0.22844634008187939, 0.22714279949276808, 0.24167163817263024, 0.024131883936034666, 0.1672607691901547], [0.23089240275806536, 0.23036938813817998, 0.24563750776388227, 0.021382647543300784, 0.17048910059019473], [0.23192451193582742, 0.23344898264337852, 0.2488703593217369, 0.020039170398504329, 0.17312904342639118], [0.23446888941721883, 0.2362976639612544, 0.25247052544036336, 0.016463757469989498, 0.1764621394875163], [0.23803183825354729, 0.23983193219391488, 0.25378340503661989, 0.015124779532628014, 0.18087011063138406], [0.23967964738421182, 0.24184042365459113, 0.25779402570507909, 0.014450972361793015, 0.18358964369388475], [0.2408244168914461, 0.24599867296016617, 0.26189338836316772, 0.013416726511648011, 0.18568656907685521], [0.24297450603183898, 0.24879316512877703, 0.2642028172767325, 0.012542882696968833, 0.1890685497058906], [0.24552312671934423, 0.25122092275983415, 0.26794092946536902, 0.013362621183512714, 0.19200684880144731], [0.24682173286590067, 0.254134356476028, 0.27049720069931676, 0.016252211703171971, 0.19635709883771099], [0.25043792825039979, 0.25801417311366925, 0.27334756300612045, 0.016645030112949204, 0.20003285721492364], [0.25261521545937066, 0.26188482214272923, 0.27741073169554509, 0.020722829991911301, 0.20088831754349121], [0.25349003055488684, 0.26434758482329901, 0.280108950619955, 0.022118858474842597, 0.20376640396756454], [0.25587005314600786, 0.26740402721397422, 0.28357294432279762, 0.02423836820718224, 0.20752284176538258], [0.25870055819967275, 0.26967755115073933, 0.28694285187731666, 0.026918656427935006, 0.21076567676254457], [0.26177091332311941, 0.27265037177152512, 0.29031713828993916, 0.030142023165463248, 0.21416210750947084], [0.26250457134537025, 0.27659637797986525, 0.29123357651024295, 0.031477836531228751, 0.21728726442254814], [0.26431982859318243, 0.27927666679388552, 0.29651752435380452, 0.036087105459632278, 0.21987375182927008], [0.26799264935216732, 0.28277237556065515, 0.2995622169905906, 0.039305905041416692, 0.22330314809921206], [0.27008550281828547, 0.28590948790701548, 0.30252669082225164, 0.04156868150074864, 0.22609845693618913], [0.27259126085837815, 0.28888981916952827, 0.30562284997045436, 0.044570007327231494, 0.22966754687671059], [0.27448588815034181, 0.29238899953598552, 0.30825535811821414, 0.047930992236333507, 0.23177148407143522], [0.27674105142454364, 0.29480112112424345, 0.31122524001325103, 0.050661185922385998, 0.23520109852186924], [0.27992600888981134, 0.29907035814751459, 0.3152412578138219, 0.053094279568120538, 0.24075718554743381], [0.28258101111590228, 0.30160468014115099, 0.31807131167599823, 0.056332300619393712, 0.24210032195336123], [0.28497201552682544, 0.30375651782854934, 0.32184200950761727, 0.059782290062306849, 0.24512731568875479], [0.28671703806022264, 0.30755489595079916, 0.32478347181819528, 0.063231850616162669, 0.24852307597630491], [0.2893632563138227, 0.31124092592943348, 0.32800818842006596, 0.06607088880629515, 0.25199350853199209], [0.29094116894310185, 0.31345526236269389, 0.33094492489585409, 0.069479354767775434, 0.25436442718990709], [0.29435456127978854, 0.31653514791139309, 0.33295898016408987, 0.071296533204458112, 0.25684056462442367], [0.29834852339262424, 0.31995520569233099, 0.33762945612535156, 0.075186590853383917, 0.26097995970194943], [0.29956702199459934, 0.32303536168630448, 0.33968853640939262, 0.079501343321272455, 0.26422176785356394], [0.30203413747642011, 0.32656169686114556, 0.34357465537318915, 0.081726302278657223, 0.26684512633838497], [0.30475943938521455, 0.32932759626223612, 0.34653378619109271, 0.085130265531227101, 0.26959257170896544], [0.30745973824796502, 0.33337478546436339, 0.34958575610598064, 0.087987246020435117, 0.27368430326997484], [0.30924950393537565, 0.33462598591232467, 0.35234418110816929, 0.089754265046455242, 0.27610631202548963], [0.31265378264457916, 0.33894819185082359, 0.35620914264426229, 0.095542284477165701, 0.27929965217714292], [0.31382742282581416, 0.34081084567597741, 0.35912043107387481, 0.098383423248617513, 0.28282601170026517], [0.317304878940459, 0.34499096401336804, 0.36190128916635372, 0.10113433700627801, 0.28587004468585525], [0.32020229441482972, 0.34768604916221924, 0.36578283496183683, 0.10378955723803922, 0.28922980824142935], [0.32209714437397047, 0.35127219844990354, 0.36883119802588843, 0.10725475735751867, 0.29170445521871569], [0.32591447851019684, 0.35436404602815297, 0.37231771523195822, 0.11014312499652494, 0.29505739779406637], [0.32795625717381877, 0.35737006078722633, 0.37372041256226141, 0.11481949637520138, 0.2971293357076189], [0.33012085169274014, 0.36117296054944353, 0.37835538250772593, 0.11660312247788236, 0.30175730414744406], [0.3334374262419002, 0.36401363438388584, 0.38091362703819232, 0.11984758173254288, 0.3045817877819787], [0.33572985872515376, 0.36677603890224819, 0.38484838615600325, 0.12308869206303608, 0.30756036418626209], [0.33811954822310164, 0.36968329101535763, 0.38799028676250624, 0.1260452788021264, 0.31071249602638079], [0.34109675048119953, 0.37266653685132894, 0.39007374117583066, 0.12990815284686089, 0.31467145491215076], [0.34395231844478868, 0.37703471615213097, 0.39578804765317532, 0.13199408650238825, 0.31765909054104424], [0.34700050017894585, 0.37969277746271796, 0.39804838793956626, 0.13402074389334101, 0.32137304981934744], [0.34904036495792923, 0.38205602459116561, 0.40030748900807217, 0.1383714853328665, 0.32355546851369565], [0.35170871735659814, 0.38536374333594065, 0.40382995313872666, 0.14203230663829933, 0.32672364633806633], [0.35468376001465879, 0.38855170038643205, 0.40678678741104335, 0.14498731152350811, 0.3299863965117556], [0.35746808893994719, 0.39076537366252373, 0.40935460620733538, 0.14725112831128512, 0.33201504506959889], [0.35890713339236857, 0.39524049698199487, 0.41363366554976205, 0.15110089952220024, 0.33556467975948379], [0.36287055080155561, 0.39904546947452363, 0.41567466942924031, 0.1543114018192186, 0.33923876889383847], [0.36529803938412103, 0.40075932804576087, 0.41920417047217673, 0.15648807886864119, 0.34093441076734898], [0.36826839271971967, 0.40434321391066269, 0.42259745639684215, 0.16040200792193332, 0.34577375862188831], [0.37104414089452364, 0.40724805882920068, 0.42537982773864524, 0.16322779288267006, 0.34837881298010731], [0.37365133845521903, 0.4099345962058058, 0.42961129221283711, 0.1670372891560509, 0.35169085159540625]]

n_of_sensors = len(sensor_position)
n_of_timeslots = len(measured_dist)