Essayez de calculer la position de l'émetteur à partir du modèle de propagation des ondes radio avec python [Wi-Fi, Beacon]

Aperçu

Objectif: En général, le calcul de position à l'aide du Wi-Fi ou de Beacon vous permet de comprendre ce que vous faites dans les coulisses ~~.

Méthode: Je vais expliquer l'idée de base et la démontrer en utilisant du code Python.

environnement: MacOS Mojave 10.14.6, Python 3.7.4

façon de penser de base

Les choses nécessaires

  1. Récepteurs radio (3) et leur emplacement
  2. Émetteur (smartphone, etc.) et sa position
  3. Force des ondes radio atteignant chaque récepteur
  4. Courbe Okumura-Hata

procédure

Étape 1. Calculez la distance avec la ** courbe d'Okumura-Hata ** à partir de la force du signal reçu de l'émetteur et des informations de position du récepteur. Étape 2. Préparez un cercle centré sur la distance calculée comme le rayon et la position de chaque récepteur. Étape 3. Trouvez l'intersection des cercles avec ** Positionnement en trois points **. ** Coordonnées de l'intersection = Coordonnées de la position de l'émetteur **

Une image concrète du positionnement en trois points se trouve au bas de cette entrée. Si vous êtes intéressé, voyez d'abord cela.

Code et résultats

Étape 0. Préparation des bonnes réponses

Préparez les données de réponse correctes pour le calcul réel. Cette fois, nous avons ciblé les collines de Toramon où se trouve notre entreprise et les installations environnantes. La position spécifique est comme ça.

ぼくとらのモン.PNG

Maintenant que nous avons ces latitude / longitude Distance du théorème des trois carrés, Trouvez la puissance radio (théorique) de chaque récepteur à partir de la distance.

Cette fois, nous utilisons des environnements urbains, des villes de petite ou moyenne taille de Hata-model: 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

Vérifier le résultat

euDist should be 5: 5.0 Loss from distance : 248.5613025107495 d should be 500: 500.0

La cérémonie semble bien se dérouler. Ensuite, calculez la distance à partir des informations de position réelles et convertissez-les en perte.

# 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)

résultat

List of distance: [0.0004620249560447818, 0.0017484756389397347, 0.0014587718293119327] List of Loss: -22.378972679965557 3.572964717331658 0.040582137429893805

Étape 1. Calculez la distance avec la ** courbe d'Okumura-Hata ** à partir de la force du signal reçu de l'émetteur et des informations de position du récepteur.

Puisque la perte peut être calculée (à partir de la distance) Calculez la distance (à partir de la perte). ~~ Je le fais avec des données de réponse correctes, donc ça ne peut pas être aidé si je fais le tour. Ne me dites pas d'utiliser la distance depuis le début! ~~

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)

Vérifier le résultat

Computed Value: [0.000462025, 0.0017484756, 0.0014587718] Original Value: [0.0004620249560447818, 0.0017484756389397347, 0.0014587718293119327]

Étant donné que la valeur est arrondie au milieu de la formule, le nombre de chiffres est différent, mais il semble qu'il puisse être calculé correctement.

Étape 2. Préparez un cercle centré sur la distance calculée comme le rayon et la position de chaque récepteur.

code. J'ai utilisé sympy car il semble facile à utiliser. Qiita: L'intersection des cercles avec 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)

résultat

Coordonnées du centre

List of centers (latitude/longitude) : [Point2D(698750203/5000000, 356664959/10000000), Point2D(698739769/5000000, 356666179/10000000), Point2D(349372423/2500000, 178337597/5000000)]

Informations sur le cercle. Le rayon a été ajouté. C'est une liste de coordonnées centrales et de rayons.

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)]

Étape 3. Trouvez l'intersection des cercles avec ** Positionnement en trois points **. ** Coordonnées de l'intersection = Coordonnées de la position de l'émetteur **

code. Après tout j'utilise sympy. Il y a 3 cercles, mais 6 solutions peuvent être obtenues car les intersections sont calculées à 2 chacune. Par conséquent, la logique est d'extraire les intersections qui apparaissent trois fois sur les six solutions. Par conséquent, il arrondit et ignore l'erreur de calcul.

# 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

résultat

Computed Value: (35.6662344, 139.7496597) Original Value: [35.6662344, 139.7496597]

Il semble que la bonne réponse a été dérivée. Je suis heureux.

Supplément: Image du positionnement en trois points, etc.

Si vous recherchez sur Google avec "positionnement en trois points", vous en verrez beaucoup, mais pour le moment, ce blog était la plus ancienne entrée que j'ai vue, donc je vais vous présenter le respect. Référence: J'aimerais pouvoir obtenir les coordonnées bidimensionnelles de l'iPhone avec RSSI d'iBeacon

Donc, quand je parle de la fin de l'histoire, je parle de blogs autres que les blogs ci-dessus, En pratique, ce code, en particulier la courbe de Hata, est inutile.

En ville, les objets sont dispersés et les ondes radio sont réfléchies de manière diffuse, de sorte que la propagation des ondes radio n'atteint pas le récepteur dans l'état idéal. Je n'ai pas l'intention de présenter l'histoire détaillée de ce domaine car cela dépasse le cadre des blogs techniques. Si vous voulez savoir, je pense que ce serait bien si vous pouviez Google ou nous rejoindre.

c'est tout.

~~ Je m'en fiche, mais j'ai l'impression que je vais me mordre la langue ~~

Recommended Posts

Essayez de calculer la position de l'émetteur à partir du modèle de propagation des ondes radio avec python [Wi-Fi, Beacon]
Essayez de mesurer la position d'un objet sur le bureau (système de coordonnées réel) à partir de l'image de la caméra avec Python + OpenCV
Essayez d'automatiser le fonctionnement des périphériques réseau avec Python
Essayez d'imaginer les données d'élévation du National Land Research Institute avec Python
[Version terminée] Essayez de connaître le nombre d'habitants de la ville à partir de la liste d'adresses avec Python
Essayez de résoudre le diagramme homme-machine avec Python
Calculez le nombre total de combinaisons avec python
Le mur lors du passage du service Django de Python 2.7 à la série Python 3
Essayez de résoudre le livre des défis de programmation avec python3
Apprenez Nim avec Python (dès le début de l'année).
Essayez de créer une table d'enregistrement de bataille avec matplotlib à partir des données de "Schedule-kun"
Essayez de résoudre le problème d'affectation du médecin de formation avec Python
Calculer le coefficient de régression d'une analyse de régression simple avec python
Essayez d'obtenir le contenu de Word avec Golang
Comment gratter le cours d'une action individuelle du site Web Nikkei Shimbun avec Python
Comment connaître le nombre de GPU de python ~ Remarques sur l'utilisation du multitraitement avec pytorch ~
Essayez d'importer dans la base de données en manipulant ShapeFile d'informations numériques sur les terres nationales avec Python
Essayez de visualiser les nutriments des flocons de maïs que le champion de M-1 Milkboy a dit avec Python
J'ai essayé de trouver l'entropie de l'image avec python
Essayez de gratter les données COVID-19 Tokyo avec Python
Essayez d'obtenir la liste des fonctions du paquet Python> os
Essayez d'évaluer les performances du modèle d'apprentissage automatique / de classification
Comment calculer la quantité de calcul appris de ABC134-D
Essayez de déchiffrer les caractères déformés dans le nom du fichier joint avec Python
Récupérez la source de la page à charger indéfiniment avec python.
Essayez d'extraire les caractéristiques des données de capteur avec CNN
Résumé du format de chaîne de caractères en Python3 Que ce soit pour vivre avec l'ancien modèle ou le nouveau modèle
Je souhaite extraire une URL arbitraire de la chaîne de caractères de la source html avec python
Premier python ② Essayez d'écrire du code tout en examinant les fonctionnalités de python
Je veux sortir le début du mois prochain avec Python
Exportez le contenu de ~ .xlsx dans le dossier en HTML avec Python
Essayez d'extraire une chaîne de caractères d'une image avec Python3
Essayez de modéliser le rendement cumulatif du roulement dans le trading à terme
Astuces: [Python] Calculez la valeur moyenne de la zone spécifiée avec bedgraph
Je veux vérifier la position de mon visage avec OpenCV!
J'ai essayé d'améliorer l'efficacité du travail quotidien avec Python
Essayez de résoudre l'itinéraire le plus court avec les données sociales Python + NetworkX +
Du «dessin» à «l'écriture» du diagramme de configuration: essayez de dessiner le diagramme de configuration AWS avec des diagrammes
[Python] Essayez de reconnaître les caractères des images avec OpenCV et pyocr
PhytoMine-I a essayé d'obtenir les informations génétiques de la plante avec Python
Essayez d'exploiter Facebook avec Python
Existence du point de vue de Python
Essayez de calculer Trace en Python
Comment calculer la date avec python
[Python] Comment spécifier la position d'affichage de la fenêtre et la taille de matplotlib
Mettez Cabocha 0.68 dans Windows et essayez d'analyser la dépendance avec Python
Calculer l'itinéraire le plus court d'un graphe avec la méthode Dyxtra et Python
Comment couper la partie inférieure droite de l'image avec Python OpenCV
[Introduction à Python] Comment trier efficacement le contenu d'une liste avec le tri par liste
Essayez d'utiliser le framework web de Python Django (1) - De l'installation au démarrage du serveur
J'ai essayé d'obtenir le code d'authentification de l'API Qiita avec Python.
Essayez de ne faire réagir que le carbone en bout de chaîne avec SMARTS
J'ai essayé de rationaliser le rôle standard des nouveaux employés avec Python
J'ai essayé d'obtenir les informations sur le film de l'API TMDb avec Python
Essayez de résoudre un problème défini de mathématiques au lycée avec Python
[Introduction à Python] Quelle est la méthode de répétition avec l'instruction continue?
J'ai essayé de prédire le comportement du nouveau virus corona avec le modèle SEIR.