“SIM820X-M2 5G HAT 在高德地图API精准定位”的版本间的差异
第192行: | 第192行: | ||
sudo pip3 install pynmea2 | sudo pip3 install pynmea2 | ||
sudo pip3 install pynmeagps | sudo pip3 install pynmeagps | ||
+ | wget https://www.waveshare.net/w/upload/1/17/SIMXXX-GNSS.zip | ||
sudo python3 SIM7600X-GNSS.py | sudo python3 SIM7600X-GNSS.py | ||
</pre> | </pre> |
2024年1月22日 (一) 16:00的最新版本
摘要:为什么SIM7600定位和我的位置差异这么大(将SIM7600X获取到的坐标系放到百度或者高德地图坐标反查),甚至有几条街的差距呢,其实是坐标系和单位的差异。下面就让我们来验证一下:
硬件准备
硬件连接图
软件准备
原理分析
SIM7600X用到的坐标系是WGS-84坐标系;而我们常用的百度或者高德地图用到的坐标系是经过加密的百度坐标(bd09)和火星坐标系(gcj_02)。因此,如果直接将WGS-84坐标系放到百度或者高德等地图是有很大误差的(放到谷歌地图可以)此外,SIM7600获取到的经纬度是分为单位,需要先转换常用的单位度:
SIMXXX获取经纬度等位置信息
由于 GPS 室内搜索不稳定,请将模块或者天线放到阳台或窗户旁,或者直接在户外进行实验。 插上GPS天线,并将接收器标签面朝下置于空旷的室外,在正常情况下(户外,天气良好,没有大型建筑遮挡)上电需要等待约1分钟才能接收到定位信号;如果天气条件不好,可能需要更长的定位时间,甚至无法定位。
- 打开minicom,发送以下指令打开GPS:
AT+CGPS=1
- 用以指令获取经纬度等位置信息:
AT+CGPSINFO
- 打开NEMA获取详细信息
sudo minicom -D /dev/ttyUSB1
- 单位转换
ddmm.mm--> dd.mm.ss: 度数不变,分数*100/60 : 如2232.448620--> 22.(32448620*100/60)= 22.54081033
坐标系转换关键代码 def wgs84_to_gcj02(lng, lat):
""" WGS84转GCJ02(火星坐标系) :param lng:WGS84坐标系的经度 :param lat:WGS84坐标系的纬度 :return: """ dlat = _transformlat(lng - 105.0, lat - 35.0) dlng = _transformlng(lng - 105.0, lat - 35.0) radlat = lat / 180.0 * pi magic = math.sin(radlat) magic = 1 - ee * magic * magic sqrtmagic = math.sqrt(magic) dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi) dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi) mglat = lat + dlat mglng = lng + dlng return [mglng, mglat]
def wgs84_to_bd09(lon, lat):
lon, lat = wgs84_to_gcj02(lon, lat) return gcj02_to_bd09(lon, lat)
def _transformlng(lng, lat):
ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \ 0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng)) ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 * math.sin(2.0 * lng * pi)) * 2.0 / 3.0 ret += (20.0 * math.sin(lng * pi) + 40.0 * math.sin(lng / 3.0 * pi)) * 2.0 / 3.0 ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 * math.sin(lng / 30.0 * pi)) * 2.0 / 3.0 return ret
def _transformlat(lng, lat):
ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + \ 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng)) ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 * math.sin(2.0 * lng * pi)) * 2.0 / 3.0 ret += (20.0 * math.sin(lat * pi) + 40.0 * math.sin(lat / 3.0 * pi)) * 2.0 / 3.0 ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 * math.sin(lat * pi / 30.0)) * 2.0 / 3.0 return ret
- 编辑并保存示例程序
sudo nano SIMXXX.py
from socket import socket import sys import re import pynmea2 import serial import chardet import time import math import json
global Latitude global Longitude global line global line1 global ser2
x_pi = 3.14159265358979324 * 3000.0 / 180.0 pi = 3.1415926535897932384626 # π a = 6378245.0 # Semi-major axis ee = 0.00669342162296594323 # Eccentricity squared
def _transformlng(longitude, latitude):
ret = 300.0 + longitude + 2.0 * latitude + 0.1 * longitude * longitude + \ 0.1 * longitude * latitude + 0.1 * math.sqrt(math.fabs(longitude)) ret += (20.0 * math.sin(6.0 * longitude * pi) + 20.0 * math.sin(2.0 * longitude * pi)) * 2.0 / 3.0 ret += (20.0 * math.sin(longitude * pi) + 40.0 * math.sin(longitude / 3.0 * pi)) * 2.0 / 3.0 ret += (150.0 * math.sin(longitude / 12.0 * pi) + 300.0 * math.sin(longitude / 30.0 * pi)) * 2.0 / 3.0 return ret
def _transformlat(longitude, latitude):
ret = -100.0 + 2.0 * longitude + 3.0 * latitude + 0.2 * latitude * latitude + \ 0.1 * longitude * latitude + 0.2 * math.sqrt(math.fabs(longitude)) ret += (20.0 * math.sin(6.0 * longitude * pi) + 20.0 * math.sin(2.0 * longitude * pi)) * 2.0 / 3.0 ret += (20.0 * math.sin(latitude * pi) + 40.0 * math.sin(latitude / 3.0 * pi)) * 2.0 / 3.0 ret += (160.0 * math.sin(latitude / 12.0 * pi) + 320 * math.sin(latitude * pi / 30.0)) * 2.0 / 3.0 return ret
def setup():
# global response ser2 = serial.Serial("/dev/ttyUSB2",115200) print("ttyUSB2 Open!!!") ser2.write('AT+CGPS=1\r'.encode()) print("AT+CGPS=1") ser2.close() print("ttyUSB2 Close!!!")
def loop():
global ser1 ser1 = serial.Serial("/dev/ttyUSB1",115200) print("ttyUSB1 Open!!!") while True: line = str(ser1.readline(),encoding='utf-8') if line.startswith("$GPRMC"): global Longitude global Latitude rmc = pynmea2.parse(line) if re.match("^\d+?\.\d+?$", rmc.lat)is not None: print(rmc) latitude = rmc.latitude longitude= rmc.longitude
- SIM820X uses the gcj_02 coordinate system, no coordinate conversion is required
dlat = _transformlat(longitude - 105.0, latitude - 35.0) dlng = _transformlng(longitude - 105.0, latitude - 35.0) radlat = latitude / 180.0 * pi magic = math.sin(radlat) magic = 1 - ee * magic * magic sqrtmagic = math.sqrt(magic) dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi) dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi) mglat = latitude + dlat mglng = longitude + dlng
- Please comment out the conversion part
print ("longitude,latitude")#longitude,latitude print (""+str(mglng)+","+str(mglat)+"")#经度,纬度 time.sleep(2)
def destroy():
ser1.close() print("ttyUSB1 Close!!!") ser2 = serial.Serial("/dev/ttyUSB2",115200) print("ttyUSB2 Open!!!") ser1.close() print("ttyUSB1 Close!!!") ser2.close() print("ttyUSB2 Close!!!")
try:
setup() loop()
except KeyboardInterrupt:
destroy()
- 运行示例程序后生成的坐标复制到高德地图API
sudo pip3 install pynmea2 sudo pip3 install pynmeagps wget https://www.waveshare.net/w/upload/1/17/SIMXXX-GNSS.zip sudo python3 SIM7600X-GNSS.py
- 结果显示:
114.0832857092161,22.53842762954979
我的位置