测量员使用差分 GPS 系统来获得准确的位置。 固定式 GPS 和流动站共同努力消除一些错误。我想我可以用两个便宜的 GPS 构建一个穷人的差分 GPS,方法是从两个 GPS 收集数据并从流动站中减去固定设备的运动矢量。 但这不适用于消费级 GPS。 如果我愿意先阅读,我可能会直接去...
对来自相邻设备的多个 GPS 输出进行平均确实比单个设备产生更好的答案。我在窗台上放了三个,通过 USB 端口为 Linux 机器供电。
USB GPSs in a window窗口中的 USB GPS
我在编写读取设备的 Python 代码时犯了另一个错误,接近尾声:
### edited for presentation, may not be functional without some TLC
# dmesg after plug in gives usb port info
import serial
import math
import re
import datetime
import sys
# https://github.com/Knio/pynmea2/blob/master/pynmea2/nmea_utils.py
def timestamp(s):
'''
Converts a timestamp given in "hhmmss[.ss]" ASCII format to a
datetime.time object
'''
ms_s = s[6:]
ms = ms_s and int(float(ms_s) * 1000000) or 0
t = datetime.time(
hour=int(s[0:2]),
minute=int(s[2:4]),
second=int(s[4:6]),
microsecond=ms)
return t
def datestamp(s):
'''
Converts a datestamp given in "DDMMYY" ASCII format to a
datetime.datetime object
'''
return datetime.datetime.strptime(s, '%d%m%y').date()
def dm_to_sd(dm):
'''
Converts a geographic coordiante given in "degres/minutes" dddmm.mmmm
format (ie, "12319.943281" = 123 degrees, 19.953281 minutes) to a signed
decimal (python float) format
'''
# '12319.943281'
if not dm or dm == '0':
return 0.
d, m = re.match(r'^(\d+)(\d\d\.\d+)$', dm).groups()
return float(d) + float(m) / 60
ser0 = serial.Serial('/dev/ttyACM0', 2*9600)
ser1 = serial.Serial('/dev/ttyACM1', 2*9600)
ser2 = serial.Serial('/dev/ttyACM2', 2*9600)
lat0=0
lon0=0
lat1=0
lon1=0
lat2=0
lon2=0
time = ""
while True :
state=ser0.readline().split(",")
if state[0]=="$GPRMC":
lat0 = dm_to_sd(state[3])
lon0 = -dm_to_sd(state[5])
time = datetime.datetime.combine(datestamp(state[9]), timestamp(state[1]))
state=ser1.readline().split(",")
if state[0]=="$GPRMC":
lat1 = dm_to_sd(state[3])
lon1 = -dm_to_sd(state[5])
time = datetime.datetime.combine(datestamp(state[9]), timestamp(state[1]))
state=ser2.readline().split(",")
if state[0]=="$GPRMC":
lat2 = dm_to_sd(state[3])
lon2 = -dm_to_sd(state[5])
time = datetime.datetime.combine(datestamp(state[9]), timestamp(state[1]))
print time.strftime("%Y-%m-%dT%H:%M:%S")+","+str(lat0)+","+str(lon0)+","+str(lat1)+","+str(lon1)+","+str(lat2)+","+str(lon2)
sys.stdout.flush()
代码永远循环,读取三个设备中的每一个,寻找GPRMC具有有趣数据的消息,并将格式化的消息打印到输出文件。 回想起来,简单的 print 语句应该将数据格式化为我最终想要的形状。 我有一个像这样的文件
2017-06-29T13:59:59, 35.111,-78.222,35.112,-78.223,35.113,-78.224
其中 35 和 -78 大约是纬度和经度。 但是我想要的是重新排列的:
2017-06-29T13:59:59, 35.111,-78.222,1
2017-06-29T13:59:59, 35.112,-78.223,2
2017-06-29T13:59:59, 35.113,-78.224,3
其中尾随的 1,2,3 标识传感器。 由于我可能会再次导入数据,因此我编写了这个 JSL 来进行转换。 (其实大部分代码都是为了生成图片,注释在最后。)
colors={{255,0,0},{0,255,0},{0,0,255},{0,0,0}};
ipicture=1e7; // sequence number with leading digit
path="H:\GPSWander\images\";
takePicture = function({},
// {filename=path||"gps"||char(ipicture++)||".png"},
// Report( gb )[framebox( 1 )]<<SAVEPICTURE>= .003, trans = trans * .80,
Report( gb )[framebox( 1 )] << Transparency( trans );
takePicture();
);
Report( gb )[framebox( 1 )] << Transparency( 1.0 );
Report( gb )[framebox( 1 )] << Marker Size( 2 );
dt << selectrows( 5 :: N Rows( dt ) );
dt << hide( 1 );
dt << clearselect;
step = N Rows( dt ) / 10000; // frames in video
For( i = 1, i < N Rows( dt ), i += step,
dt << selectrows( i :: i + step + step + step + step ); // trail
dt << hide( 0 );
takePicture();
dt << hide( 1 );
dt << clearselect;
);
</SAVEPICTURE>
寻找“gpsLog3.txt”的开放功能。 它有我从导入预览帮助我的数据表复制的脚本。 接下来的几行删除了一些包含无效数据的行。 坏的只有6个;我不确定为什么通道 2 上的 GPS 报告 0,0。
接下来的几行创建 lat9,lon9 作为 lat1,2,3 和 lon1,2,3 的平均值。 <
下一步创建仅包含要连接的列的子集,重命名它们,添加 id 变量。 然后将表连接起来,关闭不需要的表。
接下来生成的汇总表用于在随后的 GraphBuilder 中设置参考线和轴限制。 然后有一些循环来驱动图形生成器中的动画序列(以及开始拍照的奇怪功能。)
- 我借用了一些 github 代码来处理一些 NMEA GPS 问题,感谢 Knio!
- 如果你尝试这样做,你可能还需要“sudo adduser $USER dialout”,查一下。
Explaining the density ellipse in the video解释视频中的密度椭圆
这GPS漫游视频。