Zweck: Im Allgemeinen können Sie anhand der Positionsberechnung mit Wi-Fi oder Beacon verstehen, was Sie hinter den Kulissen tun ~~.
Methode: Ich werde die Grundidee erklären und sie mit Python-Code demonstrieren.
Umgebung: MacOS Mojave 10.14.6, Python 3.7.4
Schritt 1. Berechnen Sie die Entfernung mit der ** Okumura-Hata-Kurve ** aus der vom Sender empfangenen Signalstärke und den Positionsinformationen des Empfängers. Schritt 2. Bereiten Sie einen Kreis vor, der auf der berechneten Entfernung als Radius und Position jedes Empfängers zentriert ist. Schritt 3. Finden Sie den Schnittpunkt von Kreisen mit ** Dreipunktpositionierung **. ** Schnittpunktkoordinaten = Positionskoordinaten des Senders **
Ein konkretes Bild der Dreipunktpositionierung befindet sich am Ende dieses Eintrags. Wenn Sie interessiert sind, sehen Sie das bitte zuerst.
Bereiten Sie die richtigen Antwortdaten für die eigentliche Berechnung vor. Dieses Mal haben wir die Toramon Hills, in denen sich unser Unternehmen befindet, und die umliegenden Einrichtungen ins Visier genommen. Die spezifische Position ist wie folgt.
Jetzt, wo wir diese Längen- und Breitengrade haben Entfernung vom Drei-Quadrat-Theorem, Finden Sie die (theoretische) Funkstärke an jedem Empfänger aus der Entfernung.
Dieses Mal verwenden wir städtische Umgebungen, kleine oder mittelgroße Städte aus Hata-Modell: Wikipedia.
# -*- coding: utf-8 -*-
import math
import numpy as np
import pandas as pd
import sympy.geometry as sg
# latitude 1 digree = 0.0090133729745762 km
# longitutde 1 degree = 0.010966404715491394
def eucl_dist(pointA, pointB):
return np.sqrt((pointA[0]-pointB[0])**2+(pointA[1]-pointB[1])**2)
# euclidean distance
def Oku_Hata(f, h_b, C_H, d):
Loss = (69.55 + 26.16*math.log10(f)
- 13.82*math.log10(h_b) - C_H
+ (44.9 - 6.55*math.log10(h_b))*math.log10(d))
return Loss
# Okumura_Hata Curve
def inv_Oku_Hata(f, h_b, C_H, Loss):
numerator = Loss - 69.55 - 26.16*math.log10(f) + 13.82*math.log10(h_b) + C_H
denominator = 44.9 - 6.55 * math.log10(h_b)
d = 10**(numerator/denominator)
return round(d, 10)
# Inversed Okumura_Hata Curve
# variables
f = 150 # frequency of transmissiton: Megahertz
h_b = 1 # height of base station antenna : meter
h_M = 1 # heigth of mobile station antenna ; meter
C_H =0.8 + (1.1 *math.log10(f) - 0.7) * h_M -1.56*math.log10(f)
d = 500
# Test whether or not the functions function?
euDist = eucl_dist([0,0],[3,4])
Loss = Oku_Hata(f, h_b, C_H, d)
d = inv_Oku_Hata(f, h_b, C_H, Loss)
print('euDist should be 5: ', euDist)
print('Loss from distance : ', Loss)
print('d should be 500: ', d) # Should be 500
Überprüfe das Ergebnis
euDist should be 5: 5.0 Loss from distance : 248.5613025107495 d should be 500: 500.0
Die Zeremonie scheint richtig gemacht zu sein. Berechnen Sie als Nächstes die Entfernung von den tatsächlichen Positionsinformationen und konvertieren Sie sie in Verlust.
# Set of lattitude/ longitude each GeoData
tmitter = [35.6662344,139.7496597] # Transmitter from Torano-Mon
sensorLocation = {'S1':['GoodMorningCafe',35.6664959,139.7500406],
'S2':['LeParc',35.6666179,139.7479538],
'S3':['GrandSuite',35.6675194,139.7489692]}
# SensorLocation around Trano-Mon
# Compute distance (= radius) from the transmitter
r1 = eucl_dist(tmitter, sensorLocation['S1'][1:])
r2 = eucl_dist(tmitter, sensorLocation['S2'][1:])
r3 = eucl_dist(tmitter, sensorLocation['S3'][1:])
radii = [r1, r2, r3] # plural of radius
# Compute Loss
L1 = Oku_Hata(f, h_b, C_H, r1)
L2 = Oku_Hata(f, h_b, C_H, r2)
L3 = Oku_Hata(f, h_b, C_H, r3)
print('List of distance: ', radii)
print('List of Loss: ', L1, L2, L3)
Ergebnis
List of distance: [0.0004620249560447818, 0.0017484756389397347, 0.0014587718293119327] List of Loss: -22.378972679965557 3.572964717331658 0.040582137429893805
Da Verlust berechnet werden konnte (aus der Entfernung) Berechnen Sie die Entfernung (vom Verlust). ~~ Ich mache es mit korrekten Antwortdaten, also kann es nicht geholfen werden, wenn ich herumgehe. Sag mir nicht, ich soll den Abstand von Anfang an nutzen! ~~
d1 = inv_Oku_Hata(f, h_b, C_H, L1)
d2 = inv_Oku_Hata(f, h_b, C_H, L2)
d3 = inv_Oku_Hata(f, h_b, C_H, L3)
print('Computed Value: ', [d1, d2, d3]) # plural of radius
print('Original Value: ', radii)
Überprüfe das Ergebnis
Computed Value: [0.000462025, 0.0017484756, 0.0014587718] Original Value: [0.0004620249560447818, 0.0017484756389397347, 0.0014587718293119327]
Da der Wert in der Mitte der Formel gerundet ist, ist die Anzahl der Stellen unterschiedlich, aber es scheint, dass er richtig berechnet werden kann.
Code. Ich habe Sympy verwendet, weil es einfach zu bedienen zu sein scheint. Qiita: Der Schnittpunkt von Kreisen mit Sympy
# Step2.
centers = [sg.Point(sensorLocation['S1'][2], sensorLocation['S1'][1]),
sg.Point(sensorLocation['S2'][2], sensorLocation['S2'][1]),
sg.Point(sensorLocation['S3'][2], sensorLocation['S3'][1])]
# x = longitude, y = latitude
circles = [sg.Circle(centers[0], radii[0]),
sg.Circle(centers[1], radii[1]),
sg.Circle(centers[2], radii[2])]
# define all three circles
print('List of centers (latitude/longitude) :', centers)
print('List of Circles :', circles)
Ergebnis
Zentralkoordinaten
List of centers (latitude/longitude) : [Point2D(698750203/5000000, 356664959/10000000), Point2D(698739769/5000000, 356666179/10000000), Point2D(349372423/2500000, 178337597/5000000)]
Kreisinformationen. Der Radius wurde hinzugefügt. Es ist eine Liste von Mittelkoordinaten und Radien.
List of Circles : [Circle(Point2D(698750203/5000000, 356664959/10000000), 231012478022391/500000000000000000), Circle(Point2D(698739769/5000000, 356666179/10000000), 174847563893973/100000000000000000), Circle(Point2D(349372423/2500000, 178337597/5000000), 145877182931193/100000000000000000)]
Code. Immerhin benutze ich Sympy. Es gibt 3 Kreise, aber da die Schnittpunkte jeweils 2 berechnet werden, können 6 Lösungen erhalten werden. Daher besteht die Logik darin, die Schnittpunkte, die dreimal auftreten, aus den sechs Lösungen zu extrahieren. Daher runde ich den Berechnungsfehler und ignoriere ihn.
# Step3.
crossPoints12 = sg.intersection(circles[0], circles[1])
crossPoints23 = sg.intersection(circles[1], circles[2])
crossPoints31 = sg.intersection(circles[2], circles[0])
# Compute crosspoints for each two circles
crossPointsList = [
[float(crossPoints12[i].y),float(crossPoints12[i].x)] for i in [0,1]
] + [
[float(crossPoints23[i].y),float(crossPoints23[i].x)] for i in [0,1]
] + [
[float(crossPoints31[i].y),float(crossPoints31[i].x)] for i in [0,1]
]
crossPointsList = [[round(i[0],8), round(i[1],8)]for i in crossPointsList]
df = pd.DataFrame(crossPointsList).groupby([0, 1])[0].count()
print('Computed Value: ', df[df.values == max(df.values)].index[0])
print('Original Value: ', tmitter)
# print the most frequent set of lattitude-longitude
Ergebnis
Computed Value: (35.6662344, 139.7496597) Original Value: [35.6662344, 139.7496597]
Es scheint, dass die richtige Antwort abgeleitet wurde. Ich bin glücklich.
Wenn Sie mit "Dreipunktpositionierung" googeln, werden Sie viele davon sehen, aber vorerst war dieser Blog der älteste Eintrag, den ich gesehen habe, daher werde ich Respekt einbringen. Referenz: Ich wünschte, ich könnte die zweidimensionalen Koordinaten des iPhone mit RSSI von iBeacon erhalten
Wenn ich also über das Ende der Geschichte spreche, spreche ich über andere Blogs als die oben genannten Blogs. In der Praxis ist dieser Code, insbesondere die Hata-Kurve, nutzlos.
In der Stadt werden Objekte gestreut und Funkwellen diffus reflektiert, sodass die Funkwellenausbreitung den Empfänger nicht im Idealzustand erreicht. Ich habe nicht vor, die detaillierte Geschichte dieses Bereichs vorzustellen, da sie über den Rahmen technischer Blogs hinausgeht. Wenn Sie wissen wollen, denke ich, wäre es schön, wenn Sie googeln oder sich uns anschließen könnten.
das ist alles.
~~ Es ist mir egal, aber ich habe das Gefühl, ich werde mir auf die Zunge beißen ~~