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

标签 c++ gps serial-port

我正在 C++ 中从半球 GPS 单元获取数据以进行一些后处理。我正在使用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 map 试图通过“修复”来减少这种情况(更好的说法是“固定”,但通俗地说,是固定。)智能手机检测静止运动时的 GPS 点;这个过程变得更加容易,因为智能手机中的 GPS 是 enhanced GPS ——这意味着 GPS 接收器通过蜂窝技术以及智能手机的板载传感器(例如陀螺仪、加速计、磁力计和重力传感器)得到增强。(或者也称为之前热映射的 WiFi 接入点,即 GPS 坐标时)与 MAC 地址和信号环境相关联,就像 Google map 对其 map 车辆和室内地图所做的那样。)几乎所有各种集成传感器都可以比谨慎的 GPS 传感器系统更容易、更快速地检测运动(或缺乏);甚至非常昂贵。)

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

不良数据是由多种原因造成的,通常是计算错误,造成的:

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

大多数接收器通常会“丢弃”不良数据,并选择解决方案轮询滚动平均值确定的最高值的位置。虽然“坏数据”在原始数据中可见,但位置不受影响

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

关于c++ - 与 GPS 的串行通信 - 连续数据传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37560058/

相关文章:

c++ - 使用挂起的 read_async_some 关闭 boost::asio::serial_port

c - 带标记和空间奇偶校验的串行通信

c++ - fgetc 的奇怪行为

时间:2019-03-08 标签:c++tron2darrayrepeating

android - 在 Android Studio 中找不到 GeoPoint 类?

android - GPS 或 ACCELEROMETER 哪个更适合计算赛道?

Android:如何从 GPS 获取最准确的位置

c++ - 轻量级包装器 - 这是一个常见问题吗?如果是,它的名称是什么?

c++ - 在 Lighttpd 中开发插件

java - 处理 bufferUntil() 方法仅适用于 '\n'