如何使用 ruby 读取恒定的 NMEA http 数据流



我有一个名为"gps2ip"的iPhone应用程序,它启动了一个Web服务器,您可以访问该应用程序以获取流式NMEA数据。

您可以使用 qgis 直接连接到此流,以获取地图上更新的位置位置。我想以编程方式访问此流。

如果我在浏览器 url 窗口中输入以下内容:http://192.168.1.116:11123其中 192.168.1.116 是我的智能手机的 ip,如 gps2ip 应用程序所示

我在我的 safari/chrome/mozilla 浏览器屏幕上不断收到换行分隔的 NMEA 字符串流,不断在底部更新新的数据行。

    GPS 2 IP Server started. "exit" to finish.
    $GPGGA,005730,3403.415,N,07914.488,W,1,8,0.9,13.6,M,46.9,M,0,2*56
    $GPRMC,005730,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*66
    $GPGGA,005730,3403.415,N,07914.488,W,1,8,0.9,13.6,M,46.9,M,0,2*56
    $GPRMC,005730,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*66
    $GPGGA,005731,3403.415,N,07914.488,W,1,8,0.9,13.7,M,46.9,M,0,2*56
    $GPRMC,005731,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*67
    $GPGGA,005731,3403.415,N,07914.488,W,1,8,0.9,13.7,M,46.9,M,0,2*56
    $GPRMC,005731,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*67
    $GPGGA,005732,3403.415,N,07914.488,W,1,8,0.9,13.6,M,46.9,M,0,2*54
    $GPRMC,005732,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*64
    $GPGGA,005732,3403.415,N,07914.488,W,1,8,0.9,13.6,M,46.9,M,0,2*54
    $GPRMC,005732,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*64
    $GPGGA,005733,3403.415,N,07914.488,W,1,8,0.9,13.5,M,46.9,M,0,2*56
    $GPRMC,005733,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*65
    $GPGGA,005733,3403.415,N,07914.488,W,1,8,0.9,13.5,M,46.9,M,0,2*56
    $GPRMC,005733,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*65
    $GPGGA,005734,3403.415,N,07914.488,W,1,8,0.9,13.4,M,46.9,M,0,2*50
    $GPRMC,005734,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*62
    $GPGGA,005734,3403.415,N,07914.488,W,1,8,0.9,13.4,M,46.9,M,0,2*50
    $GPRMC,005734,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*62
    $GPGGA,005735,3403.415,N,07914.488,W,1,8,0.9,13.3,M,46.9,M,0,2*56
    $GPRMC,005735,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*63
    $GPGGA,005735,3403.415,N,07914.488,W,1,8,0.9,13.3,M,46.9,M,0,2*56
    $GPRMC,005735,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*63
    $GPGGA,005736,3403.415,N,07914.488,W,1,8,0.9,13.2,M,46.9,M,0,2*54
    $GPRMC,005736,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*60
    $GPGGA,005736,3403.415,N,07914.488,W,1,8,0.9,13.2,M,46.9,M,0,2*54
    $GPRMC,005736,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*60
    $GPGGA,005737,3403.415,N,07914.488,W,1,8,0.9,13.4,M,46.9,M,0,2*53
    $GPRMC,005737,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*61
    $GPGGA,005737,3403.415,N,07914.488,W,1,8,0.9,13.4,M,46.9,M,0,2*53
    $GPRMC,005737,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*61
    $GPGGA,005738,3403.415,N,07914.488,W,1,8,0.9,13.4,M,46.9,M,0,2*5C
    $GPRMC,005738,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*6E
    $GPGGA,005738,3403.415,N,07914.488,W,1,8,0.9,13.4,M,46.9,M,0,2*5C
    $GPRMC,005738,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*6E
    $GPGGA,005739,3403.415,N,07914.488,W,1,8,0.9,13.4,M,46.9,M,0,2*5D
    $GPRMC,005739,A,3403.415,N,07914.488,W,0.00,,120115,003.1,W*6F
    $GPGGA,005739,3403.415,N,07914.488,W,1,8,0.9,13.4,M,46.9,M,0,2*5D

我知道如何将这些 NMEA 代码行解析为纬度/经度对,我只需要能够在 ruby 环境中轻松访问"最后一个"。

我希望能够提取最后一两行并手动解析 NMEA 字符串,但我还没有找到一种方法来"从消防水管中啜饮"数据而不会生成错误消息。

当我尝试这个时:

require 'open-uri'
open("http://192.168.1.116:11123")

我收到此错误:

Net::HTTPBadResponse: wrong status line: "GPS 2 IP Server started. "exit" to finish."

"GPS 2 IP 服务器启动"的位置。退出'以完成"当然是响应的第一行。

我应该用什么红宝石来啜饮这把数据?显然 open-uri 想要 html 标头,而我的流没有这些。显然,我只需要流式传输纯文本。

由于这不是HTTP协议,因此您需要更通用的Socket。你可以做这样的事情:

require 'socket'
s = TCPSocket.new '192.168.1.116', 11123
while line = s.gets 
  puts line
end
s.close 

根据数据到达的速度以及处理每行所需的时间,您可能需要调查将每行放入队列(如 Sidekiq),以便多个工作人员可以同时处理行。

由于您拥有的是永无止境的数据流,因此您不能只获取最后一条消息。 您必须使用流,并决定何时收到足够的流来开始处理。 您可能会利用GPRMC消息来执行此操作。

在nmea_plus(完全披露,我写的),你可以这样做:

require 'socket'
require 'nmea_plus'
allowable_delay = 3  # threshold to consider the stream as fresh
caught_up = false    # flag to say whether we've crossed the threshold
io_source = TCPSocket.new('192.168.1.116', 11123)
source_decoder = NMEAPlus::SourceDecoder.new(io_source)
source_decoder.each_message do |msg|
  case msg.data_type
  when 'GPRMC'
    if Time.now - msg.utc_time < allowable_delay
      caught_up = true
    end
  when 'GPGLL'
    if caught_up
      puts "Fix: #{msg.latitude}, #{msg.longitude}"
    end
  end
end

默认情况下,解码器会忽略任何未解析为 NMEA 的行。

相关内容

  • 没有找到相关文章

最新更新