与 GPS 的串行通信 - 连续数据传输

Serial communication with GPS - Continuous data transfer

我正在使用 C++ 从 Hemisphere GPS 单元获取数据以进行一些 post 处理。我正在使用 a serial library 与设备通信。您只能订阅来自该 GPS 装置的数据。您可以接收位置信息的频率范围为 20Hz、10Hz、5Hz……最多每 5 秒一次。我以前使用串行通信的经验是发送命令并等待响应。我有两个问题。

我遇到的第一个问题是,在我移动 GPS 和它报告它已移动之间似乎存在延迟(大约 3-5 秒)。是否有某种类似队列的缓冲区正在被填满?因此,当我站着不动时,固定位置会填满队列,而当我移开几米远时,仍会报告固定位置。如果是这样,我怎样才能删除这个缓冲区,以便我只获得最新的数据?

第二个问题是我取回的结果,两个结果合并在一起或者分块取出来。这是我得到的原始数据的示例:

$GPGLL,5804.7646091,N,11407.8367957,W,035009.40,A,D*7C
$GPGLL,5804.7646449,N,11407.8368155,W,035009.50,A,D*79
$GPGLL,5804.7646737,N,11407.8368444,W,035009.60,A,D*75
$GPGLL,5804.7647076,N,11407.8368787,W,035009.70,A,D*7B
$GPGLL,5804.7647484,N,11407.8368970,W,035009.80,A,D*7B
$GPGLL,5804.7647751,N,11407.8369257,W,035009.90,A,D*7E
$GPGLL,5804.7648048,N,1.7650578,N,11407.8372036,W,035010.80,A,D*77 //bad data
$GPGLL,5804.7650880,N,11407.8372280,W,035010.90,A,D*73
$GPGLL,5804.7651175,N,11407.8372626,W,035011.00,A,D*71
$GPGLL,5804.7651413,N,11407.8372992,W,035011.10,A,D*75
$GPGLL,5804.7651673,N,11407.8373189,W,035011.20,A,D*71
$GP,N,11407.8374179,W,035012.90,A,D*72 //bad data
$GPGLL,5804.7652561,N,11407.8374194,W,035013.00,A,D*79
$GPGLL,5804.7652545,N,11407.8374191,W,035013.10,A,D*7B
$GPGLL,5804.7652553,N,11407.8374223,W,035013.20,A,D*75
$GPGLL,5804.7652543,N,11407.8374190,W,035013.30,A,D*7E
$GPGLL,580407.8374360,W,035015.00,A,D*76 //bad data
$GPGLL,5804.7652603,N,11407.8374404,W,035015.10,A,D*75
$GPGLL,5804.7652625,N,11407.8374373,W,035015.20,A,D*75
$GPGLL,5804.7652647,N,11407.8374386,W,035015.30,A,D*7A
$GPGLL,5804.7652668,N,11407.8374359,W,035015.40,A,D*72
$GPGLL,5804.76526W,035017.10,A,D*7F //bad data
$GPGLL,5804.7652684,N,11407.8374404,W,035017.20,A,D*7B

这是我如何阅读它的代码片段:

int baudrate = 9600;
serial::bytesize_t databits = serial::eightbits;
serial::parity_t parity = serial::parity_none;
serial::stopbits_t stopbits = serial::stopbits_one;
serial::flowcontrol_t flowcontrol = serial::flowcontrol_none;
Serial* serialObj = new serial::Serial(ss.str(), baudrate, serial::Timeout(),
                      databits, parity, stopbits, flowcontrol);

while (true)
{
    std::string rawData = serialObj->readline();
    std::cout << rawData << std::endl; 
    //decode and do other processing - takes about 0.5 seconds
}

我试过调整订阅率,但结果似乎还是一样。有什么想法会干扰通信吗?

注意:数据订阅是通过厂商提供的设置工具完成的。

这里的问题看起来不像是 C++ 问题,而是 GPS 系统问题。我不知道您对 GPS 系统的体验如何,但这里可能会发生一些事情:

The first issue that I am encountering is that there seems to be a latency between when I move the GPS and when it reports that it has moved (about 3-5 seconds).

解释:一般来说,GPS 是不精确的。如果你是静止的,听起来你是静止的,那么 GPS 有距离中心位置约 10-30 米,甚至高达 100 米或更多的误差区域。此外,GPS 在移动时最准确。

但是,如果接收器从一个固定点移动到另一个固定点,则获得良好信号变得更加困难,因为它必须:

  1. 首先检测到它移动了,这很难让接收器检测到从一个静止点到另一个非常接近的静止点。
  2. 然后重新计算它的位置,这在很大程度上取决于环境,特别是如果在城市或建筑物附近进行测试。如果接收器计算出它在几乎默认情况下的 multipath 环境中的位置,那就更糟了。

因此接收器很可能需要 3-5 秒才能更新其位置,并且 直到 然后它将发送其最后已知的最佳位置,即原始位置 (现在更不准确了)。

(旁注:这就是 GPS 漂移发生在汽车中的原因;当静止时,GPS 会失去方向并开始偏离其实际位置。Google 和 Apple 地图尝试将其减少 "fixing"(更好的词是 "affixing,",但通俗地说,它是固定的。)smartphones 检测静止运动时的 GPS 点;这个过程变得容易得多,因为 GPS在 smart phone 中是 enhanced GPS —— 这意味着 GPS 接收器通过蜂窝技术得到增强,也是 smart phone 的 on-board 传感器,例如陀螺仪、加速度计、磁力计和重力传感器。(或者也称为 WiFi 接入点,这些接入点以前是 HEAT 映射的,这是当 GPS 坐标与 MAC 地址和信号环境相关联时,例如 Google 地图使用其地图车辆和室内地图。)几乎所有各种集成传感器都可以比谨慎的 GPS 传感器系统更容易和更快地检测运动(或缺乏);即使是非常昂贵的 o ne.)

The second issue is that the results I get back, two results are merged together or pieces take out.

错误的数据是由多种原因造成的,通常是计算错误,由以下原因引起:

  1. 电磁干扰,例如靠近电源、车辆或其他(即任何)发射器。
  2. 一颗或多颗 GPS 卫星的数据不完整。这种情况发生在高层建筑附近,尤其是许多高层建筑,或者如果有悬垂物。即使 horizon 附近的卫星也会导致这种情况,因为地球本身会阻挡清晰的信号路径。
  3. 或者通常的嫌疑人,不安全的信号线.

大多数接收者 "throw out" 通常是错误数据,选择解决方案轮询由滚动平均值确定的最高值的位置。虽然 "bad data" 在原始数据中可见,但 位置不受影响 .

看起来您使用的库中的代码没有任何问题,但 GPS 传感器的行为就像它应该的那样这通常是不完美的 没有非常昂贵的精密计时单元和非常昂贵的数字罗盘等;如果没有大量外部传感器的增强,这些检测运动的速度仍然很慢,并且在静止时肯定会表现出一定程度的预期不精确