RTCM3 协议解析器
项目描述
吡咯
当前状态| 安装| 阅读| 解析| 生成| 序列化| 示例| 可扩展性| 命令行实用程序| 图形客户端| 作者和许可
pyrtcm是 RTCM3 © GPS/GNSS 协议的原始 Python 3 解析器。RTCM3 是海事无线电技术委员会发布的专有 GPS/GNSS差分校正或 DGPS协议。
RTCM 标准 10403.n 差分 GNSS(全球导航卫星系统)服务 – 第 3 版。
pyrtcm主页位于https://github.com/semuconsulting/pyrtcm。
这是一个独立项目,我们与海事服务无线电技术委员会没有任何隶属关系。
仅供参考,有一些配套库可以处理标准 NMEA 0183 © 和 UBX © (u-blox) GNSS/GPS 消息:
当前状态
将 RTCM3 消息解析为其组成数据字段。有关当前实现的消息类型的列表,请参阅中的RTCM_MSGIDS字典。rtcmtypes_core.py可以轻松添加其他消息类型 - 请参阅可扩展性)。
HTML 格式的 Sphinx API 文档可在https://www.semuconsulting.com/pyrtcm获得。
欢迎投稿 - 请参阅CONTRIBUTING.MD。
安装
pyrtcm兼容 Python >=3.7,没有第三方库依赖。
在下文中,python&pip指的是 Python 3 可执行文件。您可能需要键入
python3或pip3,具体取决于您的特定环境。
安装最新版本的推荐方法pyrtcm是使用
pip:
python -m pip install --upgrade pyrtcm
本地安装也可用,前提是你有 Python 包setuptools并wheel安装:
git clone https://github.com/semuconsulting/pyrtcm.git
cd pyrtcm
python setup.py sdist bdist_wheel
python -m pip install dist/pyrtcm-0.3.0.tar.gz --user --force_reinstall
阅读(流媒体)
class pyrtcm.rtcmreader.RTCMReader(stream, **kwargs)
您可以RTCMReader通过使用活动流对象调用构造函数来创建对象。流对象可以是任何支持read(n) -> bytes方法的数据流(例如,文件或串行,有或没有缓冲区包装器)。pyrtcm实现一个内部SocketStream类以允许以与其他流相同的方式读取套接字(参见下面的示例)。
然后可以使用该RTCMReader.read()函数读取单个 RTCM 消息,该函数返回原始二进制数据(作为字节)和解析数据(作为 a RTCMMessage,通过parse()方法)。只要传入的数据流对象是线程安全的,该函数就是线程安全的。RTCMReader还实现了一个迭代器。
示例 - 串行输入:
>>> from serial import Serial
>>> from pyrtcm import RTCMReader
>>> stream = Serial('/dev/tty.usbmodem14101', 9600, timeout=3)
>>> rtr = RTCMReader(stream)
>>> (raw_data, parsed_data) = rtr.read()
>>> print(parsed_data)
<RTCM(1077, DF002=1077, DF003=0, GNSSEpoch=204137001, DF393=1, DF409=0, DF001_7=0, DF411=0, DF412=0, DF417=0, DF418=0, DF394=760738918298550272, NSat=10, DF395=1073807360, NSig=2, DF396=1044459, DF397_01(005)=75, DF397_02(007)=75, DF397_03(009)=81, ..., DF404_19(030,1C)=0.0, DF404_20(030,2L)=0.0)>,
示例 - 文件输入(使用迭代器)。
>>> from pyrtcm import RTCMReader
>>> stream = open('rtcmdata.log', 'rb')
>>> rtr = RTCMReader(stream)
>>> for (raw_data, parsed_data) in rtr: print(parsed_data)
...
示例 - 套接字输入(使用增强的迭代器):
>>> import socket
>>> from pyrtcm import RTCMReader
>>> stream = socket.socket(socket.AF_INET, socket.SOCK_STREAM):
>>> stream.connect(("localhost", 50007))
>>> rtr = RTCMReader(stream)
>>> for (raw_data, parsed_data) in rtr.iterate(): print(parsed_data)
解析
您可以使用静态函数解析单个 RTCM 消息RTCMReader.parse(data),该函数采用包含二进制 RTCM 消息的字节数组并返回一个RTCMMessage对象。
注意:一旦实例化,RTCMMessage对象就是不可变的。
例子:
>>> from pyrtcm import RTCMReader
>>> msg = RTCMReader.parse(b"\xd3\x00\x13>\xd0\x00\x03\x8aX\xd9I<\x87/4\x10\x9d\x07\xd6\xafH Z\xd7\xf7")
>>> print(msg)
<RTCM(1005, DF002=1005, DF003=0, DF021=0, DF022=1, DF023=1, DF024=1, DF141=0, DF025=4444030.8028, DF142=1, DF001_1=0, DF026=3085671.2349, DF364=0, DF027=3366658.256)>
该RTCMMessage对象根据其消息类型或“身份”公开不同的公共属性。属性定义为数据字段(“DF002”、“DF003”等),例如1005消息包含以下数据字段:
>>> print(msg)
<RTCM(1005, DF002=1005, DF003=0, DF021=0, DF022=1, DF023=1, DF024=1, DF141=0, DF025=4444030.8028, DF142=1, DF001_1=0, DF026=3085671.2349, DF364=0, DF027=3366658.256)>
>>> msg.identity
'1005'
>>> msg.DF024
1
辅助方法可用于解释各个数据字段:
>>> from pyrtcm import RTCM_DATA_FIELDS, datasiz, datascale, datadesc
>>> dfname = "DF012"
>>> RTCM_DATA_FIELDS[dfname]
(INT20, 0.0001, "GPS L1 PhaseRange - L1 Pseudorange")
>>> datasiz(dfname) # size in bits
20
>>> datascale(dfname) # scaling factor
0.0001
>>> datadesc(dfname) # description
'GPS L1 PhaseRange - L1 Pseudorange'
重复组内的属性使用两位数后缀(“DF030_01”、“DF030_02”等)进行解析。该payload属性始终包含作为字节的原始有效负载。
当调用该方法时,MSM NSAT 和 NCELL 重复组内的属性可以选择用其对应的卫星 PRN 和信号 ID 进行标记,__str__()方法是将关键字参数设置labelmsm为 True(例如DF405_10(014,2C),表示 DF405 组中的第 10 项是指卫星 PRN 014,信号 ID 2C)。
生成
class pyrtcm.rtcmmessage.RTCMMessage(**kwargs)
RTCMMessage您可以通过使用以下关键字参数调用构造函数来创建对象:
- 有效载荷为字节
例子:
>>> from pyrtcm import RTCMMessage
>>> msg = RTCMMessage(payload=b">\xd0\x00\x03\x8aX\xd9I<\x87/4\x10\x9d\x07\xd6\xafH ")
>>> print(msg)
<RTCM(1005, DF002=1005, DF003=0, DF021=0, DF022=1, DF023=1, DF024=1, DF141=0, DF025=4444030.8028, DF142=1, DF001_1=0, DF026=3085671.2349, DF364=0, DF027=3366658.256)>
序列化
该类RTCMMessage实现了serialize()一种将RTCMMessage对象转换为适合写入输出流的字节数组的方法。
例如创建和发送1005消息类型:
>>> from serial import Serial
>>> serialOut = Serial('COM7', 38400, timeout=5)
>>> from pyrtcm import RTCMMessage
>>> msg = RTCMMessage(payload=b">\xd0\x00\x03\x8aX\xd9I<\x87/4\x10\x9d\x07\xd6\xafH ")
>>> print(msg)
<RTCM(1005, DF002=1005, DF003=0, DF021=0, DF022=1, DF023=1, DF024=1, DF141=0, DF025=4444030.8028, DF142=1, DF001_1=0, DF026=3085671.2349, DF364=0, DF027=3366658.256)>
>>> output = msg.serialize()
>>> output
b'\xd3\x00\x13>\xd0\x00\x03\x8aX\xd9I<\x87/4\x10\x9d\x07\xd6\xafH Z\xd7\xf7'
>>> serialOut.write(output)
例子
/examples 文件夹中提供了以下示例:
rtcmserial.py- 说明如何从串行/UART 端口传输 RTCM 数据。rtcmfile.py- 说明如何从二进制日志文件流式传输 RTCM 数据。rtcmsocket.py说明如何使用 RTCMReader 迭代器功能为 RTCM 消息实现 TCP 套接字读取器。rtcmbuild.py- 说明如何从组成数据字段构建 RTCM 有效负载。ntripclient.py- 说明了一个使用 pyrtcm 解析 RTCM3 输出的简单NTRIP客户端。
可扩展性
RTCM 协议主要在模块中定义rtcmtypes_core.py为rtcmtypes_get.py一系列字典。RTCM 使用一系列预定义的数据字段(“DF002”、DF003“等),每个字段都有指定的数据类型(UINT32 等)。消息负载定义必须符合以下规则:
1. datafield names must be unique within each message class
2. datafield types must be one of the valid data fields ("DF026", "DF059", etc.)
3. repeating or bitfield groups must be defined as a tuple ('numr', {dict}), where:
'numr' is either:
a. an integer representing a fixed number of repeats e.g. 32
b. a string representing the name of a preceding attribute containing the number of repeats e.g. 'DF029'
{dict} is the nested dictionary of repeating items or bitfield group
使用两位数后缀(“DF030_01”、“DF030_02”等)解析重复的属性名称。支持嵌套重复组。
命令行实用程序
命令行实用程序gnssdump可通过pygnssutils软件包获得。这能够读取和解析来自各种输入源(例如串行、套接字和文件)的 NMEA、UBX 和 RTCM3 数据,并以各种格式输出到各种媒体。有关详细信息,请参阅https://github.com/semuconsulting/pygnssutils。
要安装pygnssutils:
python3 -m pip install --upgrade pygnssutils
有关gnssdump实用程序的帮助,请键入:
gnssdump -h
图形客户端
支持 NMEA、UBX 和 RTCM3 协议的 python/tkinter 图形 GPS 客户端可在以下位置获得:
https://github.com/semuconsulting/PyGPSClient
作者和许可信息
pyrtcm完全由无偿志愿者维护。它没有从广告或企业赞助中获得资金。如果您发现该库有用,我们将不胜感激您的小额捐赠!
项目详情
下载文件
下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。